Themes
Every component follows a light or dark theme. Themes are CSS variables: the neutral scale (--n-*) and the semantic tokens mirror the Figma Colors variables (bg-primary, text-primary, border-primary …) and are re-mapped when data-theme is dark.
import
<html data-theme="dark">Switching themes
Set data-theme on <html>. Persist the choice yourself (the playbook uses localStorage and a pre-paint script to avoid a flash).
Toggle to preview this page in the other theme.
Components in both themes
ActiveFailed
Neutral scale
The scale is inverted in dark mode, so anything written with var(--n-*) adapts automatically. Avoid hard-coded hex colours in components.
| Token | Light | Dark | Use |
|---|---|---|---|
| --n-0 | #ffffff | #0a0a0a | Page and surface background (bg-primary) |
| --n-50 | #fafafa | #121212 | Subtle fill, hover (bg-secondary) |
| --n-100 | #f5f5f5 | #1a1a1a | Muted fill, chips (bg-tertiary) |
| --n-200 | #e5e5e5 | #262626 | Dividers, secondary border |
| --n-300 | #d4d4d4 | #3a3a3a | Default border (--border) |
| --n-400 | #a3a3a3 | #8a8a8a | Placeholder, disabled text, icons |
| --n-500 | #737373 | #a3a3a3 | Tertiary text |
| --n-600 | #525252 | #bdbdbd | Secondary text |
| --n-700 | #404040 | #d4d4d4 | Body text, labels |
| --n-800 | #171717 | #ededed | Primary text |
| --n-900 | #0f0f0f | #fafafa | Headings, highest contrast |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| --bg-primary / --bg-secondary / --bg-tertiary | token | — | Surface levels (map to --n-0 / --n-50 / --n-100) |
| --text-primary / --text-secondary / --text-tertiary / --text-disabled | token | — | Text levels (map to --n-800 / 600 / 500 / 400) |
| --border-primary / --border-secondary | token | — | Borders (--n-300 / --n-200) |
| --brand / --brand-hover / --brand-subtle / --brand-text | token | — | Brand; subtle and text are re-tinted for dark. Switch brands with data-brand |
| --ring-subtle | token | — | Hairline for image and card edges (black 10% in light, white 12% in dark) |
| --color-<hue>-50 / 100 / 200 / 700 | token | — | Pastel status tints (red, green, amber, blue …) become translucent fills with light text in dark |
| .light-scope | class | — | Restores the light neutral scale inside always-dark blocks such as code samples and device frames |
| dark: | Tailwind variant | — | dark:* utilities apply when an ancestor has data-theme="dark" |