Everything is a variable
One stylesheet, styles.css, ships every token and font. Components read only semantic tokens, so both themes come free. Click any token name to copy it.
Install
<link rel="stylesheet" href="styles.css">
<!-- theme: light is default; dark is one attribute -->
<html data-theme="dark">
/* your css uses semantic tokens only */
.panel { background: var(--surface-card); border: 1px solid var(--border-subtle); }
Semantic layer
| Token | Role |
|---|---|
| --surface-page / -card / -sunken / -raised | Page → card → grouping → overlay surfaces |
| --text-display / -body / -muted / -faint | Heading, body, secondary, disabled text |
| --border-subtle / -strong | Hairlines · control borders and baselines |
| --accent / --accent-strong / --accent-text / --accent-surface | Aurora: fills, hover, text, tinted surface |
| --success-text / --warning-text / --danger / --danger-text / --info-text | Status |
| --focus-ring | 2px outline, 2px offset, everywhere |
| --shadow-1 / -2 / -3 | Card · popover · dialog elevation |
Base layers
Raw ramps (--ink-*, --paper-*, --accent-aurora-*, --accent-ember-*, --accent-gold-*, --accent-bifrost-*, --accent-mimir-*) live in tokens/colors.css. Product code should not read them directly, alias per product theme instead.
Type, spacing, motion
| Token | Value |
|---|---|
| --font-display / --font-ui / --font-mono | Newsreader · IBM Plex Sans · IBM Plex Mono |
| --text-2xs … --text-5xl | 11 12 13 14 16 20 25 32 42 56 74 |
| --space-1 … --space-24 | 4 8 12 16 20 24 32 40 48 64 80 96 |
| --radius-s / -m / -l / -pill | 3 · 6 · 10 · 999 |
| --control-h-sm / -md / -lg | 28 · 36 · 44 |
| --dur-fast / --dur-base / --ease | 120ms · 200ms · cubic-bezier(.2,0,0,1) |
Per-product accent
/* Heimdall console: rebind the accent inside the product root */
.heimdall-app {
--accent: var(--accent-gold-500);
--accent-strong: var(--accent-gold-700);
--accent-text: var(--accent-gold-700);
--accent-surface: oklch(0.94 0.04 95);
}
Rebind only the four accent aliases, never neutrals, status, or focus (focus stays aurora across all products, so keyboard users always know where they are).