# Fase 5 — what has been built (complete in scope) ## 5.8 big-button create (match /notes) - `/lists` sticky bottom create bar removed; masthead gains a primary "New list" button next to the Trash ghost icon - `handleCreate` creates with empty name + `goto(/lists/[id])`; detail view shows a prominent editable title input (26–32px) with 500 ms autosave (`renameList`) - Matches `/notes` pattern end-to-end ## 5.10 row redesign (button-row + gesture toggle + overlay + drag handles) - Shopping items have **no checkbox** in normal mode. Row is `drag-handle | name-button | qty stepper`. Checked items render strikethrough + muted. - **Swipe right on unchecked → mark checked** (green reveal), **swipe left on checked → uncheck** (neutral reveal). Opposite direction is a no-op snap-back. `SWIPE_COMMIT_THRESHOLD=120`, `SWIPE_REVEAL_WIDTH=96`. No undo toast — the gesture is symmetric and the inverse swipe reverses. - **Double-tap opens an overlay** (Dialog / bottom sheet) with: name input + Delete (red) + Confirm + X close. 300 ms tap-window. Delete still routes through `scheduleUndoable` → `UndoToast`. - **Drag handle** on the left, always visible on mobile, `md:opacity-0 md:group-hover:opacity-100` on desktop. Handle's `onpointerdown` flips a `dragEnabled` flag so dnd only kicks in from the handle, leaving row swipes untouched. - `unit` column **dropped** (migration `011_drop_shopping_items_unit.sql`). The double-tap overlay only edits name, so an unreachable `unit` would be stranded data. Users encode units inside the name (e.g. "Milk 1L"); seed updated accordingly. ## 5.11 selection mode + bulk actions - **Entry**: long-press 500 ms on mobile or `data-testid="selection-toggle"` button in the desktop header. Preselects the row you pressed (mobile). - Inside selection mode: single-tap toggles selection, swipe + double-tap disabled, stepper + drag handle hidden. Row gains a checkbox on the left. - **Chrome**: header turns into `data-testid="selection-bar"` (dark slate-900 with "N selected" + Cancel + desktop-inline actions). Mobile bottom action bar (`data-testid="selection-action-bar"`) above BottomTabBar with Delete / Move / Mark-checked. - **Bulk actions** (one Supabase call each): `bulkDeleteItems` + single UndoToast with batch snapshot, `bulkMoveItems` via a list picker sheet (`data-testid="move-picker"`) listing the collective's other active lists + a "Create new list" row, `bulkCheckItems` filters `is_checked=false` so it only marks, never toggles. ## 5.12 detail-view chrome (hide MobileTopBar, sticky contextual bars) - On `/lists/[id]`, `/tasks/[id]`, `/notes/[id]`, `/lists/[id]/session` the global `MobileTopBar` is hidden via an `isDetailRoute` regex check in `(app)/+layout.svelte`. The route's own contextual header (back + title + actions) becomes the only top chrome and is now `sticky top-0 z-30 bg-surface/80 backdrop-blur-xl`. - `BottomTabBar` stays visible so users can hop between sections. ## 5.15 detail-view title chrome cleanup - `/lists/[id]` and `/tasks/[id]` dropped the uppercase eyebrow label ("ACTIVE LIST" / "TASK MANAGER") that used to sit above the editable title. Title moved up into that space. - `/lists/[id]` status signal replaces the hardcoded "ACTIVE LIST": `completed` → title with `text-text-secondary line-through`; `archived` → muted pill next to title (`data-testid="list-status-pill"`); `active` → plain title. - `/tasks/[id]` has no status on `task_lists`; just the label drop. ## 5.14 inline add-form (last element of the list) - `/lists/[id]` + `/tasks/[id]` no longer have a bottom-sticky add form. The form renders **inline as the last child of the unchecked / pending section** (just above Checked / Completed). Empty-state branch shows message + form beneath it. - On `/lists/[id]` the frequency chips (`ItemSuggestions`) moved below the input (input row on top, chips on second line). Mobile: horizontal scroll; desktop: wrap. - Hides entirely while `selectionMode` is active. - Svelte 5 snippets `addItemForm` / `addTaskForm` so the form is rendered in both the empty-state branch and the between-sections slot without duplication. - `data-testid="add-item-form"` / `"add-task-form"` hooks added for future placement assertions. ## Earlier sub-phases (still relevant) - `apps/web/src/lib/components/layout/DesktopSidebar.svelte` — desktop sidebar extracted from `(app)/+layout.svelte`, `data-testid="desktop-sidebar"`, `hidden md:flex` - `apps/web/src/lib/components/layout/MobileTopBar.svelte` — hamburger + collective name + avatar link; `md:hidden sticky top-0 z-30 backdrop-blur-xl` - `apps/web/src/lib/components/layout/BottomTabBar.svelte` — 4 nav items icon-only, glassmorphism, `pb-[env(safe-area-inset-bottom)]`, `aria-current="page"` on the active route, `data-testid="bottom-tab-bar"` - `apps/web/src/lib/components/layout/MobileDrawer.svelte` — backdrop + collective switcher + manage/settings/logout, `data-testid="mobile-drawer"` - `apps/web/src/lib/components/ScreenMasthead.svelte` — uppercase label (`data-testid="masthead-label"`) + big title (`data-testid="masthead-title"`) + optional `meta` / `actions` snippets. Applied on `/lists`, `/tasks`, `/notes`, `/search`. - `apps/web/src/lib/sync/undoQueue.ts` — `scheduleUndoable({ label, restore, commit, ttlMs? })` with 4-s TTL; auto-commits on timeout, `undo(id)` cancels + restores - `apps/web/src/lib/components/UndoToast.svelte` — rendered globally in `(app)/+layout.svelte`, shows latest undoable, offset above bottom tab bar on mobile - `/lists/[id]` swipe-delete: `SWIPE_MAX=96`, `SWIPE_THRESHOLD=48` (latch-open), `SWIPE_COMMIT_THRESHOLD=200` (full-swipe commit via `scheduleUndoable`) - `apps/web/src/lib/components/ItemSuggestions.svelte` — mobile: horizontal scroll with `[scrollbar-width:none]`; desktop: wraps - `(app)/+layout.svelte` — **critical fix**: outer container now `flex flex-col md:flex-row` (was `flex` only). Without this MobileTopBar and main rendered as horizontal siblings on mobile and the masthead was pushed off-screen. - Mobile tests: `mobile-shell.test.ts` (M-01..M-04), `mobile-masthead.test.ts` (M-05 × 4 routes), `mobile-swipe-delete.test.ts` (M-06/M-07 `.skip` — Chromium touch emulation too flaky), `undoQueue.test.ts` (5 unit tests)