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>
This commit is contained in:
2026-04-13 13:36:52 +02:00
parent 2806e06db2
commit ee962991e1
42 changed files with 5018 additions and 29 deletions

163
plan/fase-5-mobile-ux.md Normal file
View File

@@ -0,0 +1,163 @@
### 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.