### 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/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) / )`) 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 `` + `
` + `` 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

{label}

{title}

``` - [ ] 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.