# DESIGN.md Design reference for the Colectivo app. Stack: SvelteKit + shadcn-svelte + Tailwind CSS. Generated mockups are in `.stitch/designs/`. Stitch project ID: `10316144241804324155`. --- ## 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 | Notes | |---|---|---|---| | Screen title | 20px | 600 | | | Section label | 13px | 600 | Uppercase, `letter-spacing: 0.05em` | | Body / list item | 16px | 400 | | | Meta / secondary | 13px | 400 | `text-slate-500` | | Badge / tag | 11px | 500 | Uppercase, `rounded-full` | | Input | 16px | 400 | Min 16px prevents iOS zoom on focus | Line height: 1.5 for body, 1.2 for headings. No text smaller than 11px. ### Spacing Base unit: 4px (Tailwind default). Prefer multiples of 4. Common values: - List item padding: `px-4 py-3` (min 48px touch target) - Screen horizontal margin: `px-4` (mobile), `px-6` (desktop) - Section gap: `gap-6` - Between section label and content: `mt-2` - Bottom nav / sticky input 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 ``). 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, avatar picker) | | `Dialog` | Confirmations (delete list, dissolve collective) | | `Popover` | Presence avatars tooltip | | `Badge` | Priority tags (TODAY, URGENT), status labels (DRAFT, HIGH PRIORITY) | | `Skeleton` | Loading states | | `Sonner` | Toast notifications (sync errors, member joined, undo delete) | --- ## Layout & Navigation ### App Shell Two-column on desktop, single-column on mobile. ``` Mobile Desktop (lg+) ┌─────────────────────┐ ┌──────────┬──────────────────────┐ │ Header │ │ │ Breadcrumb / Title │ ├─────────────────────┤ │ Sidebar │──────────────────────┤ │ │ │ │ │ │ Content │ │ │ Content │ │ │ │ │ │ ├─────────────────────┤ │ User │ │ │ Bottom Nav │ │ Info │ │ └─────────────────────┘ └──────────┴──────────────────────┘ ``` ### Sidebar (desktop) Fixed left sidebar, `surface-raised` background (vs `surface` main area — tonal shift, no border line). ``` ┌──────────────┐ │ Colectivo │ ← collective name, 14px/600 ├──────────────┤ │ 🛒 Lists │ ← active item: slate-900 bg, white text │ ✓ Tasks │ ← inactive: slate-500 text │ 📄 Notes │ │ 🔍 Search │ │ │ │ (spacer) │ │ │ │ ┌──┐ Name │ ← user avatar + display name │ │AG│ Role │ ⚙ ← settings gear icon └──────────────┘ ``` - Collective name at top, 14px/600 - 4 nav items: Lists, Tasks, Notes, Search - User avatar + display name + settings gear at bottom - Width: `w-56` (`224px`) ### Navigation (mobile) Fixed bottom tab bar, 4 tabs. Icons only — no text labels. Active icon: `slate-900`. Inactive: `slate-400`. Glassmorphism background: `backdrop-blur-md bg-white/80`. Respects `safe-area-inset-bottom`. | Tab | Icon | Route | |---|---|---| | Lists | `shopping-cart` | `/lists` | | Tasks | `check-square` | `/tasks` | | Notes | `file-text` | `/notes` | | Search | `search` | `/search` | ### Page Headers Desktop: breadcrumb-style context path above the title, in uppercase 11px/500 `text-slate-400`: ``` WORKSPACE OVERVIEW Shared Lists ``` ``` PROJECT ATLAS / Tasks ``` Mobile: plain title with optional back arrow and overflow `⋯` menu on the right. ### Responsive Breakpoints Tailwind defaults: `sm` (640), `md` (768), `lg` (1024). Sidebar appears at `lg`. Content max-width: `max-w-2xl` centered on large screens. --- ## Screen Patterns ### Lists View (`/lists`) Featured card for the primary/active list (full width, larger), secondary lists in a 2-column grid below. ``` WORKSPACE OVERVIEW Shared Lists ┌─────────────────────────────────────┐ │ Home 👤👤 │ ← featured card │ 12 items · Updated 2h ago │ │ [GROCERIES] [HOUSEHOLD] │ ← category tags, rounded-full └─────────────────────────────────────┘ ┌──────────────┐ ┌──────────────┐ │ Office │ │ Party │ │ 5 items │ │ 26 items │ │ 🗂 │ │ HIGH PRTY │ ← badge └──────────────┘ └──────────────┘ ┌─────────────────────────────────────┐ │ + Create a new shared list... [Create] │ ← sticky bottom input └─────────────────────────────────────┘ ``` - Category tags on list cards: `rounded-full text-xs font-medium bg-slate-100 px-2 py-0.5` - Presence avatars overlap on cards with active members ### List Detail (`/lists/[id]`) Normal (non-session) view. Items with quantity controls. ``` ACTIVE LIST Grocery List ⋯ ┌─────────────────────────────────────┐ │ ☐ Honeycrisp Apples 6 + │ │ ☐ Organic Baby Spinach 2 + │ │ ☐ Whole milk 1L 2 + │ │ ☐ Salted Butter 1 + │ └─────────────────────────────────────┘ [MILK] [BREAD] [EGGS] [COFFEE] [APPLES] ← frequency chips ┌─────────────────────────────────────┐ │ Add item (e.g. Greek Yogurt 500g) [+] │ └─────────────────────────────────────┘ ``` - Quantity controls: `−` count `+` inline at the right of each row - Frequency chips always visible above the input (not just on focus); active chip: `bg-slate-900 text-white`; inactive: `bg-slate-100 text-slate-700` ### Shopping Session Mode (`/lists/[id]/session`) Full-screen takeover. No sidebar, no bottom nav. ``` ✕ Compra semanal 👤👤 ───────────────────────────────────── TO BUY ☐ Whole milk 1L ☐ Bread ☐ Eggs 12 uds ☐ Avocados CHECKED ☑ Butter 250g (muted, struck through) ☑ Olive Oil 1L ───────────────────────────────────── [ Finish shopping ● ] ``` - `TO BUY` and `CHECKED` are uppercase section labels, not divider lines - Items slide from TO BUY to CHECKED on tap — no page scroll - Minimum tap target: `min-h-[56px]` - Presence avatars: `size-6 rounded-full`, overlapping, top-right of header - "Finish shopping" button: full-width, `bg-slate-900 text-white`, with a subtle pulse indicator dot (●) ### Tasks View (`/tasks`) Tasks grouped into named sections. Filter pills at the bottom. ``` PROJECT ATLAS / Tasks 👤👤 ───────────────────────────────────── HIGH PRIORITY ☐ Finalize Q4 strategy deck TODAY ☐ Coordinate with design on monolith tokens URGENT PRODUCT DEVELOPMENT ☐ Core API Integration ☐ Review documentation for Auth endpoints (indented sub-item) ☑ Map database schema to editorial structure (completed) ☐ User testing: Editorial workflow BACKLOG ☐ Update dependency libraries ───────────────────────────────────── [DAILY] [WEEKLY] [URGENT] ← filter pills ┌─────────────────────────────────────┐ │ Add task to Tasks... [Save] │ └─────────────────────────────────────┘ ``` - Section names are user-defined (not system-fixed) - Priority badges on individual tasks: `text-xs uppercase text-slate-400` (TODAY, URGENT) - Filter pills: same style as frequency chips; filter the visible tasks ### Notes View (`/notes`) Notes displayed as cards in a masonry-style grid, grouped by user-defined categories. ``` WORKSPACE / NOTES 🔔 ⊞ 👤 ───────────────────────────────────── CATEGORY Meeting Notes ┌─────────────────┐ ┌─────────────────┐ │ Q4 Product │ │ Sprint Retro: │ │ Roadmap... │ │ Project Apollo │ │ Oct 24, 2023 │ │ Oct 22, 2023 │ └─────────────────┘ └─────────────────┘ CATEGORY Project Ideas ┌─────────────────┐ │ Minimalist │ │ Portfolio... │ └─────────────────┘ ───────────────────────────────────── │ Capture a new thought... # @ [SAVE] │ ``` - Cards: `bg-white rounded-md` on `surface-raised` background (tonal lift, no shadow) - Category labels: uppercase section labels above each group - Inline new-note input at the bottom (not a separate screen) --- ## 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 ``` `bg-slate-800 text-slate-100`, 36px tall. Mounts/unmounts immediately — no animation. ### Frequency Chips (Add Item Input) Sticky input area at the bottom of list and task screens. Frequency chips are **always visible** above the input, not conditional on focus. ``` [MILK] [BREAD ●] [EGGS] [COFFEE] [APPLES] ← scrollable row ┌─────────────────────────────────────────────────┐ │ Add item (e.g. Greek Yogurt 500g) [+] │ └─────────────────────────────────────────────────┘ ``` - Chips: `rounded-full text-xs font-medium px-3 py-1 bg-slate-100` (inactive) / `bg-slate-900 text-white` (active/selected) - Tapping a chip fills the input; user can still edit before confirming - While typing, chips switch to prefix-filtered suggestions (max 10, same pill style) - Confirm with `+` button or `Enter` ### Swipe to Delete On list items and tasks. Swipe left reveals a red destructive zone: ``` ┌────────────────────────────────────────┐ │ ☐ Whole milk 1L ░░░░░░ │ ← item sliding left │ [🗑] │ ← red-500 zone, trash icon only └────────────────────────────────────────┘ ``` Full swipe: immediate deletion + Sonner toast "Deleted · Undo" (4 seconds). Partial swipe: snaps back. No confirmation dialog for single items. ### Drag & Drop Reordering Handle (`grip-vertical` Lucide icon) on the left — always visible on desktop, revealed on long-press on mobile. Use `svelte-dnd-action`. During drag: lifted item has `shadow-md bg-white`, others compress to show insertion point. ### Confirmations **Destructive, hard-to-reverse actions** (delete list, remove member, dissolve collective): `Dialog` with explicit description text. No shortcut. **Soft deletions** (single item, single task): swipe + Sonner undo. No dialog. ### Avatar Component Three mutually exclusive states, all `rounded-full`. | State | Appearance | Size tokens | |---|---|---| | `initials` | Initials on `slate-700` bg, white 600-weight text | `size-6` presence, `size-8` lists, `size-16` settings | | `emoji` | Emoji centered on `slate-700` bg | same | | `upload` | ``, fallback to initials on error | same | Initials rule: first letter of first + last word in `display_name` ("Ana García" → "AG", "Borja" → "B"). ### User Settings Screen (`/settings`) In the desktop sidebar shell. Content area: ``` ← Settings ┌──────┐ │ AG │ ← size-16 avatar └──────┘ Change avatar › DISPLAY NAME ┌────────────────────────────────┐ │ Ana García │ ← auto-save, 500ms debounce └────────────────────────────────┘ Changes saved automatically ← slate-400 hint LANGUAGE [ English ] [ Español ] ← pill segmented control English selected: slate-900/white. Instant effect, no reload. ACCOUNT ← background shift (no line) Email & password → ← external link to Keycloak Managed in Keycloak ← slate-400 DANGER ZONE ← section label in red-500 [ Delete account ] ← ghost red button ``` **Avatar sheet** — `Sheet` (bottom on mobile, dialog on desktop): - Segmented tabs: Initials | Emoji | Photo - Emoji grid: 8 columns, ~40 emoji (🐸 🐼 🦊 🐨 🦁 🐯 🐻 🦋 🌵 🌻 🍀 🌈 ⭐ 🔥 💎 🎯 🎸 🎹 🎨 📚 ✈️ 🏔️ 🌊 🎭 🍕 🍜 🍣 ☕ 🍎 🥑 🍓 🎂 🏠 🚲 🛹 ⚽ 🏄 🧘 🎮 🤿) - Photo upload: file picker → 1:1 crop in-browser → preview → confirm. Max 2MB. JPG/PNG/WebP. ### Empty States Text-only, no illustrations. `text-slate-500`, centered in content area. ``` No lists yet. Tap + to create one. ``` Two lines max. ### Loading States `Skeleton` components matching the shape of the content (list rows, card grids). Spinner only for full-screen blocking operations (login, initial data fetch). --- ## Stitch Mockup Inventory Screens in `.stitch/designs/` — project `10316144241804324155`: | File | Screen | Status | |---|---|---| | `01-lists-view.png` | Lists View | ✅ | | `02-shopping-session.png` | Shopping Session | ✅ | | `03-notes-view.png` | Notes View | ✅ | | `04-tasks-view.png` | Tasks View | ✅ | | `05-list-detail.png` | List Detail with frequency chips | ✅ | | — | User Settings | ⏳ pending generation | | — | Collective Management | ⏳ pending generation |