Files
Parsons/docs/design-system.md
Richie 732c872576 Initial commit: FA 2.0 Design System foundation
Token pipeline (Style Dictionary v4, DTCG format):
- Primitive tokens: colour palettes (brand, sage, neutral, feedback),
  typography (3 font families, 21-variant type scale), spacing (4px grid),
  border radius, shadows, opacity
- Semantic tokens: text, surface, border, interactive, feedback colours;
  typography roles; layout spacing
- Component tokens: Button (4 sizes), Input (2 sizes)
- Generated outputs: CSS custom properties, JS ES6 module, flat JSON

Atoms (3 components):
- Button: contained/soft/outlined/text × primary/secondary, 4 sizes,
  loading state, underline for text variant
- Typography: 21 variants across display/heading/body/label/caption/overline,
  maxLines truncation
- Input: external label, helper text, error/success validation,
  start/end icons, required indicator, 2 sizes, multiline support

Infrastructure:
- MUI v5 theme with full token mapping
- Storybook 8 with autodocs
- Claude Code agents and skills for token/component workflows
- Design system documentation and cross-session memory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:08:15 +11:00

175 lines
7.5 KiB
Markdown

# FA Design System
This is the living design system specification. It is the primary reference for
all agents when creating tokens, components, or compositions.
**This file will be updated progressively as the system is built.**
## Brand context
Funeral Arranger is an Australian online funeral planning platform. It connects
families with funeral directors and provides transparent pricing and service
comparison. The design must:
- **Feel warm and trustworthy** — families are often in grief or distress
- **Prioritise clarity** — reduce cognitive load, no visual noise
- **Be transparent** — pricing, options, and processes should feel open
- **Respect cultural sensitivity** — serve diverse Australian communities
- **Be accessible** — WCAG 2.1 AA minimum across all components
## Brand colours
### Primary palette — Brand (warm gold/copper)
Derived from Parsons brand swatches. The warm gold family conveys trust and warmth.
| Step | Token | Value | Usage |
|------|-------|-------|-------|
| 50 | color.brand.50 | #FEF9F5 | Warm section backgrounds |
| 100 | color.brand.100 | #F7ECDF | Hover backgrounds, subtle fills |
| 200 | color.brand.200 | #EBDAC8 | Secondary backgrounds |
| 300 | color.brand.300 | #D8C3B5 | Surface warmth, card tints |
| 400 | color.brand.400 | #D0A070 | Secondary interactive, step indicators |
| **500** | **color.brand.500** | **#BA834E** | **Primary CTA, main interactive** |
| 600 | color.brand.600 | #B0610F | Hover/emphasis, brand links (4.8:1 on white) |
| 700 | color.brand.700 | #8B4E0D | Active states, brand text (6.7:1 on white) |
| 800 | color.brand.800 | #6B3C13 | Bold brand accents |
| 900 | color.brand.900 | #51301B | Deep emphasis, dark brand surfaces |
| 950 | color.brand.950 | #251913 | Darkest brand tone |
### Secondary palette — Sage (cool grey-green)
Calming, professional secondary palette for the funeral services context.
| Step | Token | Value | Usage |
|------|-------|-------|-------|
| 50 | color.sage.50 | #F2F5F6 | Cool section backgrounds |
| 200 | color.sage.200 | #D7E1E2 | Light cool surfaces |
| 400 | color.sage.400 | #B9C7C9 | Mid sage accents |
| 700 | color.sage.700 | #4C5B6B | Secondary buttons, dark accents (6.1:1 on white) |
| 800 | color.sage.800 | #4C5459 | Supplementary text (6.7:1 on white) |
### Neutral palette
True grey for text, borders, and UI chrome. Cool-tinted charcoal (#2C2E35) for primary text.
| Step | Token | Value | Usage |
|------|-------|-------|-------|
| 50 | color.neutral.50 | #FAFAFA | Page background alternative |
| 100 | color.neutral.100 | #F5F5F5 | Subtle backgrounds |
| 200 | color.neutral.200 | #E8E8E8 | Borders, dividers |
| 300 | color.neutral.300 | #D4D4D4 | Disabled borders |
| 400 | color.neutral.400 | #A3A3A3 | Placeholder text, disabled content |
| 500 | color.neutral.500 | #737373 | Tertiary text, icons |
| 600 | color.neutral.600 | #525252 | Secondary text (7.1:1 on white) |
| 700 | color.neutral.700 | #404040 | Strong text (9.7:1 on white) |
| **800** | **color.neutral.800** | **#2C2E35** | **Primary text colour (13.2:1 on white)** |
| 900 | color.neutral.900 | #1A1A1C | Maximum contrast |
### Feedback colours
| Type | Token | Value | Background token | Background value |
|------|-------|-------|-----------------|------------------|
| Success | color.feedback.success | #3B7A3B (green.600) | color.feedback.success-subtle | #F0F7F0 |
| Warning | color.feedback.warning | #CC8500 (amber.600) | color.feedback.warning-subtle | #FFF9EB |
| Error | color.feedback.error | #BC2F2F (red.600) | color.feedback.error-subtle | #FEF2F2 |
| Info | color.feedback.info | #2563EB (blue.600) | color.feedback.info-subtle | #EFF6FF |
## Typography
### Font stack
| Role | Family | Fallback | Weight range |
|------|--------|----------|-------------|
| Display/Headings (H1-H2) | Noto Serif SC | Georgia, Times New Roman, serif | 600-700 |
| Body/Headings (H3+) | Montserrat | Helvetica Neue, Arial, sans-serif | 400-700 |
| Mono | JetBrains Mono | Fira Code, Consolas, monospace | 400 |
### Type scale
| Role | Size | Line height | Weight | Letter spacing | Token |
|------|------|-------------|--------|----------------|-------|
| Display | 36px | 44px | 700 | -0.02em | typography.display |
| H1 | 30px | 38px | 700 | -0.01em | typography.h1 |
| H2 | 24px | 32px | 600 | 0 | typography.h2 |
| H3 | 20px | 28px | 600 | 0 | typography.h3 |
| H4 | 18px | 24px | 600 | 0 | typography.h4 |
| Body Large | 18px | 28px | 400 | 0 | typography.bodyLarge |
| Body | 16px | 24px | 400 | 0 | typography.body |
| Body Small | 14px | 20px | 400 | 0 | typography.bodySmall |
| Caption | 12px | 16px | 400 | 0.02em | typography.caption |
| Label | 14px | 20px | 500 | 0.01em | typography.label |
| Overline | 12px | 16px | 600 | 0.08em | typography.overline |
## Spacing system
Base unit: 4px. All spacing values are multiples of 4.
| Token | Value | Typical usage |
|-------|-------|---------------|
| spacing.0.5 | 2px | Hairline gaps (icon-to-text tight) |
| spacing.1 | 4px | Tight inline spacing |
| spacing.2 | 8px | Related element gap, small padding |
| spacing.3 | 12px | Component internal padding (small) |
| spacing.4 | 16px | Component internal padding (default), form field gap |
| spacing.5 | 20px | Medium component spacing |
| spacing.6 | 24px | Card padding, section gap (small) |
| spacing.8 | 32px | Section gap (medium) |
| spacing.10 | 40px | Section gap (large) |
| spacing.12 | 48px | Page section separation |
| spacing.16 | 64px | Hero/banner vertical spacing |
| spacing.20 | 80px | Major page sections |
## Border radius
| Token | Value | Usage |
|-------|-------|-------|
| borderRadius.none | 0px | Square corners (tables, dividers) |
| borderRadius.sm | 4px | Inputs, small interactive elements |
| borderRadius.md | 8px | Cards, buttons, dropdowns |
| borderRadius.lg | 12px | Modals, large cards |
| borderRadius.xl | 16px | Feature cards, hero elements |
| borderRadius.full | 9999px | Pills, avatars, circular elements |
## Shadows
| Token | Value | Usage |
|-------|-------|-------|
| shadow.sm | 0 1px 2px rgba(0,0,0,0.05) | Subtle lift (buttons on hover) |
| shadow.md | 0 4px 6px rgba(0,0,0,0.07) | Cards, dropdowns |
| shadow.lg | 0 10px 15px rgba(0,0,0,0.1) | Modals, popovers |
| shadow.xl | 0 20px 25px rgba(0,0,0,0.1) | Elevated panels |
## Responsive breakpoints
| Name | Value | Target |
|------|-------|--------|
| xs | 0px | Mobile portrait |
| sm | 600px | Mobile landscape / small tablet |
| md | 900px | Tablet |
| lg | 1200px | Desktop |
| xl | 1536px | Large desktop |
### Layout conventions
- Max content width: 1200px (`Container maxWidth="lg"`)
- Page horizontal padding: `spacing.4` (mobile), `spacing.8` (desktop)
- Section vertical spacing: `spacing.12`
- Card grid gutter: `spacing.4` (mobile), `spacing.6` (desktop)
## Component conventions
### Interactive elements
- Minimum touch target: 44px height on mobile
- Focus-visible outline: 2px solid `color.interactive.default`, 2px offset
- Hover transition: 150ms ease-in-out
- Active state: slightly darkened background (5-10%)
- Disabled: 40% opacity, no pointer events
### Cards
- Border radius: `borderRadius.md` (8px)
- Internal padding: `spacing.4` (mobile), `spacing.6` (desktop)
- Shadow: `shadow.md` by default, `shadow.lg` on hover
- Price displays: use Display or H2 typography with brand primary colour
### Forms
- Labels above inputs, using Label typography
- Helper text below inputs, using Caption typography in `color.text.secondary`
- Error text replaces helper text in `color.feedback.error`
- Input height: 44px (matching button medium height)
- Field gap: `spacing.4` (16px)
- Section gap within forms: `spacing.8` (32px)