foundations
Colour
Role-first. OKLCH everywhere. Light and dark redefine roles — they do not flip them.
Read the full specRole tokens — light and dark, side by side
The CSS variables every consumer references. Left column renders as the root theme; the right column is forced into dark. Roles are named for intent, not for pigment.
Light
- background--background
- foreground--foreground
- card--card
- card-foreground--card-foreground
- popover--popover
- popover-foreground--popover-foreground
- primary--primary
- primary-foreground--primary-foreground
- secondary--secondary
- secondary-foreground--secondary-foreground
- muted--muted
- muted-foreground--muted-foreground
- accent--accent
- accent-foreground--accent-foreground
- border--border
- input--input
- ring--ring
Dark
- background--background
- foreground--foreground
- card--card
- card-foreground--card-foreground
- popover--popover
- popover-foreground--popover-foreground
- primary--primary
- primary-foreground--primary-foreground
- secondary--secondary
- secondary-foreground--secondary-foreground
- muted--muted
- muted-foreground--muted-foreground
- accent--accent
- accent-foreground--accent-foreground
- border--border
- input--input
- ring--ring
Semantic intents
Success, warning, destructive and info — each paired with a foreground that passes AA against its surface.
Light
- success--success
- success-foreground--success-foreground
- warning--warning
- warning-foreground--warning-foreground
- destructive--destructive
- info--info
- info-foreground--info-foreground
Dark
- success--success
- success-foreground--success-foreground
- warning--warning
- warning-foreground--warning-foreground
- destructive--destructive
- info--info
- info-foreground--info-foreground
Risk taxonomy — immutable across surfaces
Safety-data categories. Same colour in the dashboard, WhatsApp previews, marketing visuals, Remotion scenes, PDF reports. Never invent new ones on a surface.
- theft / burglary--risk-theft · #f43f5e
- battery / assault--risk-assault · #f59e0b
- vehicle--risk-vehicle · #0ea5e9
- disorder--risk-disorder · #a855f7
- fire--risk-fire · #ef4444
- medical--risk-medical · #10b981
Chart palette
Five hues. Do not extend beyond five without redesigning. Never encode data by colour alone — always add shape, pattern, or label.
- --chart-1
- --chart-2
- --chart-3
- --chart-4
- --chart-5
WCAG AA contrast — pairs that matter
Every pair ships at or above 4.5:1 for body copy, 3:1 for large text. Verified at build time against the canonical token ramps.
- primaryAA
- body on backgroundAA
- muted on backgroundAA
- accentAA
- successAA
// consumer code
<div className="bg-primary text-primary-foreground">
Action — AA-safe by construction
</div>