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>
This commit is contained in:
174
docs/design-system.md
Normal file
174
docs/design-system.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user