Design tokens
One semantic contract; themes swap underneath.
Lumen exposes one semantic contract. Themes swap the values underneath without touching component code.
Selector layering
The shipped contract is :root (Day) and .dark (Night) — exactly what lumen/theme.css defines and
what shadcn/Tailwind apps expect, so Lumen drops straight into an existing app. (The standalone labs under
/labs/ predate the package and still use a legacy html[data-mode]/data-mood selector internally;
that is a lab convenience, not the contract.)
The token set
| Group | Tokens |
|---|---|
| Typography | --font-sans / --font-serif / --font-display / --font-mono |
| Surfaces | --background / --foreground, --card / --popover |
| Brand | --primary / -foreground, --secondary, --accent / -foreground, --glow, --gradient-primary |
| Neutrals | --muted / -foreground, --border / --input / --ring |
| Status | --success, --warning, --destructive, --info |
| Health status | --status-in-range / -borderline / -out-of-range (+ -text) — aliases of the status hues |
| Data | --data-1 … --data-6 |
| On-light text | *-text variants (e.g. --primary-text, --data-2-text) |
| Charts | --chart-grid / -axis / -track / -band / -band-line |
| Space | --spacing — the 4px base every gap/pad derives from |
| Size | --size-control-sm/md/lg (32/36/44), --size-tap-min (24 — the pressable floor) |
| Layers | --layer-raised … --layer-tooltip — one stacking vocabulary |
| Icons | --icon-sm/md/lg (16/20/24), --icon-stroke |
| Strokes & opacity | --stroke-hairline / --stroke-emphasis, --opacity-disabled |
| Motion | --duration-quick / --duration-gentle, --ease-lumen |
| Shape & depth | --radius, --radius-sm … --radius-2xl, --shadow-sm / --shadow-lg, --overlay |
Why -text variants exist
Saturated fills are too light to use as small text on the pinkish-white ground. Each hue therefore ships a
paired -text step that clears WCAG AA. The rule is on the author: fills, dots, and bars use the bright
token; small colored text uses the -text step (as the Badge component does).
The semantic tokens are chosen steps from the tonal scales — so contrast is structural, not lucky.