The duplicate design/DESIGN.md was removed; the authoritative "Monolith Editorial" spec lives at design/slate_collective/DESIGN.md. Update CLAUDE.md, README.md, and plan/fase-5-mobile-ux.md accordingly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9.8 KiB
Fase 5 — Rediseño UX Mobile ("Monolith Editorial")
Estado: ⏳ Plan propuesto
Duración estimada: 1–2 semanas
Objetivo: reescribir la capa de presentación para que el app sea mobile-first, siguiendo las mockups de Stitch en design/*/screen.png y la dirección "Monolith Editorial" de design/slate_collective/DESIGN.md.
Esta fase sigue TDD: primero los tests, al final la verificación. Toda la cobertura funcional actual (211 tests) debe seguir verde. Los nuevos tests cubren responsive breakpoints y el shell mobile.
0. Brecha entre el estado actual y la dirección de diseño
Lo que ya funciona a favor del plan:
- Modo Compra ya es full-screen overlay con z-50 (
/lists/[id]/session) — compatible mobile. - Sticky bottom input con glassmorphism básico en
/lists/[id]y/tasks/[id]. - Tokens de diseño en
app.css(RGB triplets +rgb(var(--token) / <alpha>)) compatibles con la paleta slate. - Swipe-to-delete touch en
/lists/[id]para items (parcial — sin zona roja animada ni toast de "undo").
Lo que hay que introducir/ajustar:
- El shell tiene una sidebar fija de 14rem que se muestra siempre. En mobile hay que ocultarla y mostrar top-bar con hamburger + bottom tab bar con glassmorphism.
- Ningún header tiene el tratamiento de masthead editorial (uppercase label + big title) que piden las mockups (
WORKSPACE / Shared Lists,CURRENT INVENTORY / Grocery List, etc.). - Las cards de listas en
/listsson genéricas; la mockup mobile las quiere con icono, meta ("12 items · Shared with Family") y avatares de presencia overlapping. - Swipe-to-delete no tiene zona roja con fade + toast con undo (ver §UX Patterns en
design/colectivo_design_reference.html). - Chips de frecuencia no son horizontalmente scrollables en mobile.
- Headers de sección (todas las pantallas) usan
text-xs uppercase tracking-widepero sin el pairing masthead. - Padding actual
px-6no escala: mobile pidepx-4, desktoppx-6.
Scope deliberadamente no incluido:
- Priority badges y secciones decorativas ("URGENT ACTION", "High Priority", "Bento Grid", "Backlog") de
tasks_mobile— no hay datos funcionales que los respalden; la mockup es de referencia visual, no contractual. - "SAVE" manual en notas (seguimos con autosave).
- Mic/voice search en
search_mobile(fuera de alcance). - Meta ficticia tipo "Dairy • Weekly" en ítems de la compra — el modelo no tiene categorías.
5.0 Tests primero — escribir antes de implementar
Playwright (apps/web/tests/e2e/):
mobile-shell.test.ts:- M-01: en viewport 375×812 (iPhone 13), la sidebar NO es visible.
- M-02: en viewport 375×812, el bottom tab bar es visible con 4 iconos (lists/tasks/notes/search) y el icono de la ruta activa tiene
aria-current="page". - M-03: tap en el hamburger abre un drawer con el collective switcher + settings + logout.
- M-04: en viewport 1280×800, la sidebar SÍ es visible y el bottom tab bar NO aparece.
mobile-masthead.test.ts:- M-05: cada ruta (
/lists,/tasks,/notes,/search) muestra un elemento condata-testid="masthead-label"(uppercase) +data-testid="masthead-title"(big).
- M-05: cada ruta (
mobile-swipe-delete.test.ts:- M-06: en
/lists/[id]con viewport mobile, simulate touch swipe-left en un item → se revela la zona roja con aria-label "Delete item". - M-07: full-swipe dispara el delete; toast con botón "Undo" restaura el ítem si se pulsa en < 4s.
- M-06: en
Vitest (apps/web/src/lib/...):
swipe.test.ts— helper de estado del swipe (offset → revealed → committed) aislado para testeo sin DOM.undoQueue.test.ts— cola de deletes con TTL de 4s que puede cancelarse.
Nota: los 211 tests existentes deben seguir pasando tras el rediseño. Ese es el verdadero smoke de regresión — no añadimos tests funcionales nuevos que dupliquen lo que ya hay.
5.1 Shell responsive
apps/web/src/lib/components/layout/MobileTopBar.svelte:- Hamburger (izq) + wordmark "Colectivo" (centro) + avatar (der)
- Visible solo en
md:hidden - Sticky top con glassmorphism (
backdrop-blur-xl bg-surface/80)
apps/web/src/lib/components/layout/BottomTabBar.svelte:- 4 items: Lists, Tasks, Notes, Search. Solo iconos (sin texto).
- Glassmorphism igual que la top bar.
- Respeta
env(safe-area-inset-bottom)conpb-[env(safe-area-inset-bottom)]. - Active:
text-slate-900/ inactive:text-slate-400. - Visible solo en
md:hidden.
apps/web/src/lib/components/layout/MobileDrawer.svelte:- Se abre al tocar el hamburger.
- Contiene: collective switcher (con lista de colectivos + emoji), botón "Manage collective", enlace a Settings, Sign out.
- Backdrop con click-outside close + trap focus.
- Usa CSS transform (no re-mount) para evitar pérdida de estado.
apps/web/src/routes/(app)/+layout.svelte:- Extraer la sidebar actual a
DesktopSidebar.svelte, renderizar solomd:flex. - Renderizar
<MobileTopBar />+<main>+<BottomTabBar />en mobile. - Main scroll area con
pb-20en mobile para dejar espacio al bottom bar.
- Extraer la sidebar actual a
5.2 Masthead editorial + responsive padding
- Extraer un componente
ScreenMasthead.svelte:<!-- props: label, title --> <p data-testid="masthead-label" class="text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">{label}</p> <h1 data-testid="masthead-title" class="text-[28px] md:text-[32px] font-semibold tracking-[-0.02em] text-text-primary">{title}</h1> - Aplicar en
/lists(WORKSPACE/Shopping Lists),/tasks(TASK MANAGER/ProductivityoTareas),/notes(REPOSITORY/Notes),/search(OMNI-SEARCH/Find Anything.). - Reemplazar
px-6genérico porpx-4 md:px-6en contenedores principales. - Reemplazar
max-wausente pormax-w-2xl mx-autoen pantallas de lectura (notes, search results) para mantener longitudes editoriales en pantallas grandes.
5.3 Rediseño de /lists mobile
- Cards con el tratamiento de la mockup
lists_mobile:- Icono grande (emoji / lucide) arriba-izq
- Título + línea meta (
{n} items · {member_count} membersoActivesi vacío) - Avatares de presencia overlapping (usa
collectiveMembersya cargado; máximo 3, "+N" si más) - Sin shadow — separa por
bg-surface-raisedsobrebg-background
- Card "featured" (primera lista activa) a ancho completo; resto en grid 2×2 en mobile.
- Sticky input conserva
Plus+Createbutton como en la mockup.
5.4 Rediseño de /lists/[id] mobile
- Top-bar contextual: back arrow + nombre de la lista (truncado) + menú 3-dots.
- Fila de ítem:
- Checkbox 24px a la izq
- Nombre (body-lg) + meta opcional
{unit}debajo si existe - Qty stepper a la derecha (
– N +) siempre visible en mobile (quitar hover-only actual) - Handle de drag (GripVertical) oculto en mobile — se activa con long-press
- Swipe-to-delete "zona roja":
- Touch-move left → translate X y revela
bg-red-500 text-whitecon iconoTrash2a la derecha - Threshold 48px = snap abierto; >72% del ancho = commit delete
- Post-delete: toast con "Undo" durante 4s (ver
undoQueue) - Reutilizar lógica existente y añadir animación de color + el componente de toast
- Touch-move left → translate X y revela
5.5 Toast con "Undo" para deletes suaves
apps/web/src/lib/stores/undoQueue.ts:scheduleUndoable({ label, restore, commit })devuelveid- TTL 4s; si nadie llama
undo(id), ejecutacommit; si llamaundo, ejecutarestore
apps/web/src/lib/components/UndoToast.svelte:- Monta al fondo de la pantalla (encima del bottom bar en mobile)
- Muestra label + botón "Undo"
- Escucha el store y desaparece cuando la cola se vacía
- Integrar en: delete de item (lists), delete de task, send-to-trash de nota.
5.6 Chips de frecuencia scrollables
ItemSuggestions.svelte: wrapper conoverflow-x-auto flex-nowrapen mobile, grid en desktop.- Hacer los chips
rounded-full bg-slate-200 dark:bg-slate-800según DESIGN.md §5.
5.7 Adaptar /tasks, /notes, /search al shell + masthead
/tasks: mastheadTASK MANAGER/Tareas. Quitar priority badges de las mockups (no están en el modelo). Mantener secciones "Pendientes / Completadas" con animación flip./notes: mastheadREPOSITORY/Notes+ contador{n} ENTRIES. Listado en una columna mobile; grid masonry solo enmd+./search: mastheadOMNI-SEARCH/Find Anything.. Las secciones ya tienendata-testid="search-group-*"— solo añadir badge "{n} MATCHES" junto al header.
5.Z Verificación final — todos los tests verdes
just test-all→ 0 failures (los 211 actuales siguen verdes + los nuevos mobile tests)- Validación visual en DevTools iPhone 13 (375×812) + Pixel 7 (412×915) + Desktop (1280×800)
loginAs(USERS.borja)en Playwright con viewport mobile emulado — el shell mobile debe estar activo automáticamente.
Plan de ejecución (orden sugerido)
- 5.0 Tests primero — escribir los mobile tests aunque inicialmente fallen.
- 5.1 Shell responsive — sin esto, nada más es testable en mobile.
- 5.5 UndoQueue + UndoToast — dependencia de 5.4.
- 5.2 Masthead + padding — trivial, desbloquea los tests M-05.
- 5.3 / 5.4 / 5.6 — ajustes por pantalla.
- 5.7 — pulido de tasks/notes/search con el shell.
- 5.Z Verificación — correr toda la suite, snapshot visual, commit.
Criterio de aceptación
- En viewport ≤ 768px: sidebar oculta, bottom tab bar + top bar visibles, drawer abre con el switcher.
- Todas las pantallas tienen el par masthead (label uppercase + title big).
- Swipe-left en un item revela la zona roja; full-swipe borra con toast de undo.
- Los 211 tests funcionales siguen verdes. Los nuevos mobile tests (M-01..M-07) pasan.
- Validado manualmente en DevTools en 3 viewports.