Foundations · Colors
Two palettes, one variable name.
Every color resolves through a CSS custom property. Change data-theme on <html> and components keep the same token names in both modes.
Dark preview
Dark mode sample
Body copy reads cleanly on this surface. The accent dot reads as intentional, not noise.
AccentLight preview
Light mode sample
Body copy reads cleanly on this surface. The accent dot reads as intentional, not noise.
AccentSurfaces
6 tokensBackgrounds move from page to card to nested surfaces. Use the least prominent token that works.
--bg
Darkoklch(0.145 0 0)Lightoklch(0.98 0.005 80)
--card
Darkoklch(0.205 0 0)Lightoklch(1 0 0)
--surface
Darkoklch(0.18 0 0)Lightoklch(1 0 0)
--surface-2
Darkoklch(0.17 0 0)Lightoklch(0.975 0.003 80)
--surface-3
Darkoklch(0.16 0 0)Lightoklch(0.955 0.004 80)
--button
Darkoklch(0.22 0 0)Lightoklch(0.96 0 0)
Text
5 tokensUse primary for headings, secondary for body copy, and muted for metadata.
--primary
Darkoklch(0.985 0 0)Lightoklch(0.18 0 0)
--secondary
Darkoklch(0.87 0 0)Lightoklch(0.32 0 0)
--muted
Darkoklch(0.62 0 0)Lightoklch(0.50 0 0)
--body
Darkoklch(0.91 0 0)Lightoklch(0.22 0 0)
--code-text
Darkoklch(0.86 0 0)Lightoklch(0.28 0 0)
Borders
2 tokensUse border for quiet containers and border-strong for visible controls.
--border
Darkrgba(255,255,255,0.10)Lightrgba(10,10,10,0.08)
--border-strong
Darkrgba(255,255,255,0.18)Lightrgba(10,10,10,0.18)
Brand
2 tokensUse the accent for active filters, live states, and high-signal hover feedback.
--accent
Darkoklch(0.78 0.09 60)Lightoklch(0.55 0.13 40)
--accent-soft
Darkoklch(0.78 0.09 60 / 0.14)Lightoklch(0.55 0.13 40 / 0.10)