Files
collective-lists/plan/fase-5-mobile-ux.md
Oier Bravo Urtasun ee962991e1 docs(fase-5): plan mobile UX rewrite ("Monolith Editorial")
- Add plan/fase-5-mobile-ux.md with 7-chunk breakdown:
    5.0 mobile tests (Playwright mobile-shell/masthead/swipe-delete + Vitest helpers)
    5.1 responsive shell (MobileTopBar + BottomTabBar + MobileDrawer)
    5.2 ScreenMasthead + px-4/md:px-6 pass
    5.3 /lists mobile cards
    5.4 /lists/[id] rows + red-zone swipe-delete
    5.5 undoQueue store + UndoToast
    5.6 scrollable frequency chips
    5.7 tasks/notes/search shell + masthead
    5.Z verify 211 + new M-series green
- Explicit gap analysis vs. current app + deliberate exclusions
    (no priority badges, no voice search, no fake meta like "Dairy · Weekly")
- Index design/ directory: Stitch mockups per screen (mobile + desktop variants),
  plus the "Monolith Editorial" DESIGN.md directing tonal shifts, masthead
  typography, glassmorphism, and the no-line rule
- Relocate DESIGN.md under design/slate_collective/DESIGN.md (old entry point) —
  the current design direction lives at design/DESIGN.md
- Reference design/ from CLAUDE.md + add Fase 5 to README phase index

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 13:36:52 +02:00

164 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### Fase 5 — Rediseño UX Mobile ("Monolith Editorial")
**Estado: ⏳ Plan propuesto**
**Duración estimada: 12 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/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 `/lists` son 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-wide` pero sin el pairing masthead.
- Padding actual `px-6` no escala: mobile pide `px-4`, desktop `px-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 con `data-testid="masthead-label"` (uppercase) + `data-testid="masthead-title"` (big).
- [ ] `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.
**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)` con `pb-[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 solo `md:flex`.
- Renderizar `<MobileTopBar />` + `<main>` + `<BottomTabBar />` en mobile.
- Main scroll area con `pb-20` en mobile para dejar espacio al bottom bar.
#### 5.2 Masthead editorial + responsive padding
- [ ] Extraer un componente `ScreenMasthead.svelte`:
```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` / `Productivity` o `Tareas`), `/notes` (`REPOSITORY` / `Notes`), `/search` (`OMNI-SEARCH` / `Find Anything.`).
- [ ] Reemplazar `px-6` genérico por `px-4 md:px-6` en contenedores principales.
- [ ] Reemplazar `max-w` ausente por `max-w-2xl mx-auto` en 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} members` o `Active` si vacío)
- Avatares de presencia overlapping (usa `collectiveMembers` ya cargado; máximo 3, "+N" si más)
- Sin shadow — separa por `bg-surface-raised` sobre `bg-background`
- [ ] Card "featured" (primera lista activa) a ancho completo; resto en grid 2×2 en mobile.
- [ ] Sticky input conserva `Plus` + `Create` button 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-white` con icono `Trash2` a 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
#### 5.5 Toast con "Undo" para deletes suaves
- [ ] `apps/web/src/lib/stores/undoQueue.ts`:
- `scheduleUndoable({ label, restore, commit })` devuelve `id`
- TTL 4s; si nadie llama `undo(id)`, ejecuta `commit`; si llama `undo`, ejecuta `restore`
- [ ] `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 con `overflow-x-auto flex-nowrap` en mobile, grid en desktop.
- [ ] Hacer los chips `rounded-full bg-slate-200 dark:bg-slate-800` según DESIGN.md §5.
#### 5.7 Adaptar `/tasks`, `/notes`, `/search` al shell + masthead
- [ ] `/tasks`: masthead `TASK MANAGER` / `Tareas`. Quitar priority badges de las mockups (no están en el modelo). Mantener secciones "Pendientes / Completadas" con animación flip.
- [ ] `/notes`: masthead `REPOSITORY` / `Notes` + contador `{n} ENTRIES`. Listado en una columna mobile; grid masonry solo en `md+`.
- [ ] `/search`: masthead `OMNI-SEARCH` / `Find Anything.`. Las secciones ya tienen `data-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)
1. **5.0 Tests primero** — escribir los mobile tests aunque inicialmente fallen.
2. **5.1 Shell responsive** — sin esto, nada más es testable en mobile.
3. **5.5 UndoQueue + UndoToast** — dependencia de 5.4.
4. **5.2 Masthead + padding** — trivial, desbloquea los tests M-05.
5. **5.3 / 5.4 / 5.6** — ajustes por pantalla.
6. **5.7** — pulido de tasks/notes/search con el shell.
7. **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.