Theming
Three brand themes and a dark mode, switchable at runtime from one source.
The system ships three brand themes, each with a dark variant:
| Theme | Brand | Fonts |
|---|---|---|
| Harmonica | Sky blue | Inter + Plus Jakarta Sans |
| Verdant | Emerald | DM Sans + DM Serif Display |
| Ember | Amber | Nunito + Cormorant Garamond |
Switching a theme sets data-theme-id (and data-theme="dark") on the
document element. Because every component reads from --cdz-* variables, the
whole UI re-themes with no per-component change. Try it — this control
re-themes every example on this page:
THEME
neutralprimarysuccesserrorwarninginfoneutralprimarysuccesserrorwarninginfo
Controlling the theme in code
import { useTheme } from '@cdz/ui';
function ThemeMenu() {
const { theme, setTheme, dark, toggleDark, themes } = useTheme();
// theme -> 'harmonica' | 'verdant' | 'ember'
// dark -> boolean
// setTheme('verdant'); toggleDark();
}The provider persists the selection to localStorage, so a hard reload keeps
the chosen theme and mode. Disable persistence with <ThemeProvider persist={false}>.
Adding a theme
- Add a
styles/theme-<name>.cssfile overriding the switchable tokens (brand scale, primary, gradients, glows, fonts) underhtml[data-theme-id="<name>"]. - Add an entry to the
THEMESregistry in@cdz/ui. - Add a
@importfor it instyles.css.
Structural tokens (gray, text, spacing, radii, shadows) stay constant across themes — only the brand-expressive tokens change.