- CLAUDE.md: project guidance (stack, domain model, auth, i18n, gotchas) - DESIGN.md: full design system spec derived from Stitch mockups (slate monochrome, Inter, shadcn-svelte, screen patterns for all 5 views) - README.md: development plan with Justfile commands - analysis/: functional spec (domain model, use cases, business rules) - plan/: phase-by-phase implementation plans (Fase 0–4) - .stitch/designs/: generated mockups (lists, shopping session, notes, tasks, list detail with frequency chips) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
17 KiB
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 <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, 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 BUYandCHECKEDare 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-mdonsurface-raisedbackground (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 orEnter
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 |
<img object-cover>, 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 |