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

View File

@@ -0,0 +1,239 @@
# DESIGN.md
Design reference for the Colectivo app. Stack: SvelteKit + shadcn-svelte + Tailwind CSS.
---
## Visual Style
### Direction
Clean and minimal. Content is the UI — no decorative elements, no gradients, no shadows unless they carry meaning. Generous whitespace. Every element earns its place.
### Color
Monochromatic slate palette. No accent color — contrast and weight carry hierarchy.
```
--background: slate-50 / slate-950
--surface: white / slate-900
--surface-raised: slate-100 / slate-800
--border: slate-200 / slate-700
--text-primary: slate-900 / slate-50
--text-secondary: slate-500 / slate-400
--text-disabled: slate-300 / slate-600
--destructive: red-500 / red-400 ← only color in the UI
```
Interactive elements (buttons, checkboxes, active states) use `slate-900` on light and `slate-50` on dark — inverting the surface. The only true color is destructive red.
### Typography
Font: **Inter** (or `system-ui` as fallback — acceptable on iOS/macOS).
| Role | Size | Weight |
|---|---|---|
| Screen title | 20px | 600 |
| Section header | 13px | 600, uppercase, tracked |
| Body / list item | 16px | 400 |
| Secondary / meta | 13px | 400 |
| Input | 16px | 400 — prevents iOS zoom on focus |
Line height: 1.5 for body, 1.2 for headings. No text smaller than 13px.
### Spacing
Base unit: 4px (Tailwind default). Prefer multiples of 4. Common values:
- List item padding: `px-4 py-3`
- Screen horizontal margin: `px-4` (mobile), `px-6` (desktop)
- Section gap: `gap-6`
- Bottom nav safe area: always account for `env(safe-area-inset-bottom)`
### Iconography
**Lucide** (ships with shadcn-svelte). Size `20px` inline, `24px` for nav and primary actions. Stroke width `1.5`. Never fill icons.
### Dark Mode
Class-based (`dark` on `<html>`). Respect `prefers-color-scheme` on first load, then persist user preference in `localStorage`. shadcn-svelte's CSS variable system handles theming — no additional setup needed per component.
---
## Component Library
**shadcn-svelte** — copy-paste components built on bits-ui + Tailwind. No runtime dependency, full ownership of component code.
### Conventions
- Copy components into `apps/web/src/lib/components/ui/` (shadcn-svelte default)
- App-specific compositions go in `apps/web/src/lib/components/` (e.g. `ItemRow.svelte`, `ListCard.svelte`)
- Never modify shadcn-svelte primitives directly — compose or wrap them
- Use shadcn-svelte's `cn()` utility for conditional classes
### Key components to install
| Component | Used for |
|---|---|
| `Button` | All actions |
| `Input` | Add item, search, forms |
| `Checkbox` | Shopping items, tasks |
| `Sheet` | Mobile bottom drawers (item edit, member invite) |
| `Dialog` | Confirmations (delete list, dissolve collective) |
| `Popover` | Presence avatars tooltip, note color picker |
| `Badge` | Status labels (archived, completed) |
| `Separator` | Section dividers |
| `Skeleton` | Loading states |
| `Sonner` | Toast notifications (sync errors, member joined) |
---
## Layout & Navigation
### App Shell
Two-column on desktop, single-column on mobile.
```
Mobile Desktop (lg+)
┌─────────────────────┐ ┌──────────┬──────────────────────┐
│ Header │ │ │ Header │
├─────────────────────┤ │ ├──────────────────────┤
│ │ │ Nav │ │
│ Content │ │ Sidebar │ Content │
│ │ │ │ │
├─────────────────────┤ │ │ │
│ Bottom Nav │ └──────────┴──────────────────────┘
└─────────────────────┘
```
### Navigation
**Mobile:** fixed bottom tab bar, 4 tabs. Respects `safe-area-inset-bottom`.
**Desktop (`lg+`):** left sidebar, always visible.
| Tab | Icon | Route |
|---|---|---|
| Lists | `shopping-cart` | `/lists` |
| Tasks | `check-square` | `/tasks` |
| Notes | `file-text` | `/notes` |
| Search | `search` | `/search` |
Collective switcher and user avatar live in the header (mobile) / top of sidebar (desktop).
### Screen Structure
Every screen follows the same skeleton:
```
┌─────────────────────────────┐
│ ← Back Screen Title ⋯ │ ← Header: title + optional action menu
├─────────────────────────────┤
│ │
│ Main content │ ← Scrollable
│ │
├─────────────────────────────┤
│ [ + Add item... ] │ ← Sticky bottom input (list/task screens)
└─────────────────────────────┘
```
### Responsive Breakpoints
Use Tailwind defaults: `sm` (640), `md` (768), `lg` (1024). The sidebar appears at `lg`. Content max-width: `max-w-2xl` centered on large screens.
---
## UX Patterns
### Optimistic Updates
All mutations update the local store immediately before the server responds. On error, revert and show a toast. Never block the UI waiting for a network response.
### Offline Indicator
A slim bar at the top of the content area (not the header) when offline:
```
┌─────────────────────────────┐
│ No connection · Saving locally │ ← slate-800 bg, slate-100 text, 36px tall
└─────────────────────────────┘
```
Disappears immediately when connection is restored. No animation — just mounts/unmounts.
### Add Item Input
Sticky to the bottom of list and task screens. On focus, shows frequency suggestions above it:
```
┌──────────────────────────────┐
│ Milk · Bread · Eggs │ ← Frequency chips (top 5, scrollable row)
├──────────────────────────────┤
│ 🔍 Add item... [+] │ ← Input + confirm button
└──────────────────────────────┘
```
- Chips are horizontally scrollable, `text-sm`, `rounded-full`, `border` style
- Tapping a chip fills the input; the user can still edit before confirming
- While typing, chips are replaced by prefix-filtered suggestions (max 10, vertical list)
- Confirm with the `+` button or `Enter`
### Swipe to Delete
On list items and tasks. Swipe left reveals a red destructive zone:
```
┌─────────────────────────────────────┐
│ ☐ Whole milk 1L ░░░░░░ │ ← item sliding left
│ [Del] │ ← red zone, icon only
└─────────────────────────────────────┘
```
Full swipe confirms deletion immediately (no dialog). Partial swipe snaps back. A toast with "Undo" appears for 4 seconds.
### Drag & Drop Reordering
Handle on the left side of each item (visible on long-press on mobile, always visible on desktop). Use `svelte-dnd-action`. During drag: item has `shadow-md`, others compress slightly to show insertion point.
### Shopping Session Mode
Full-screen takeover. Clean, distraction-free:
```
┌─────────────────────────────┐
│ ✕ Compra semanal 👤👤 │ ← close + presence avatars
├─────────────────────────────┤
│ ☐ Whole milk 1L │
│ ☐ Bread │ ← large tap targets (min 56px height)
│ ☐ Eggs 12 uds │
│ ──────── Checked ──────── │ ← divider, auto-scrolled below
│ ☑ Butter 250g │ ← muted, struck through
├─────────────────────────────┤
│ Finish shopping │ ← full-width button
└─────────────────────────────┘
```
- No bottom nav, no sidebar — only the list
- Items checked during the session slide down past the divider automatically
- Presence avatars are `size-7`, overlap slightly if multiple members present
### Confirmations
**Destructive, hard-to-reverse actions** (delete list, remove member, dissolve collective): use a `Dialog` with explicit confirmation text. No shortcut.
**Soft deletions** (single item, single task): swipe with undo toast — no dialog.
### Empty States
Simple, text-only. No illustrations.
```
No lists yet.
Tap + to create one.
```
Two lines max. Secondary text color. Centered in the content area.
### Loading States
Use `Skeleton` components that match the shape of the content (list rows, not spinners). Spinner only for full-screen blocking operations (login, initial data fetch).