Design System
Philosophy
- Member-first: designed for the 25-year-old opening the app on Sunday morning
- Clean, modern, warm — not corporate SaaS, not startup bro
- Church-appropriate but not churchy
- Accessible: WCAG AA minimum
Spacing (4px grid)
xs: 4px
sm: 8px
md: 16px
lg: 24px
xl: 32px
2xl: 48px
3xl: 64px
Typography
heading1: 28px / bold / 1.2 line-height
heading2: 24px / bold / 1.25
heading3: 20px / semibold / 1.3
body: 16px / regular / 1.5
bodySmall: 14px / regular / 1.5
caption: 12px / regular / 1.4
Font: System default (San Francisco on iOS, Roboto on Android)
Colors
Define in frontend/constants/theme.ts. Include light and dark mode variants.
Semantic Colors
primary— main brand action colorsecondary— secondary actionsbackground— screen backgroundsurface— card/container backgroundtext— primary texttextSecondary— secondary/muted textborder— borders and dividerserror— error statessuccess— success stateswarning— warning states
Components
- Button: primary, secondary, outline, ghost, destructive variants
- Card: elevated surface with optional header/footer
- Input: text, email, password, multiline, with label and error state
- Avatar: circle, with initials fallback
- Badge: status indicator, count badge
- List: standard list with separators, swipe actions
- Modal: bottom sheet (preferred) or center modal
- Toast: non-blocking feedback messages
- Empty State: illustration + title + description + action
Icons
- Lucide icons (consistent, MIT licensed)
- Size: 20px (inline), 24px (default), 32px (featured)
- Color: inherit from parent text color
Motion
- Subtle, purposeful animations
- Duration: 150ms (micro), 250ms (standard), 400ms (complex)
- Easing: ease-out for enter, ease-in for exit
- No animation for essential interactions (accessibility)
Dark Mode
- Support both light and dark mode
- Use semantic color tokens (not hardcoded colors)
- Test both modes for every screen
- Respect system preference, allow manual override