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 themed
element. Because every component reads from --cajon-* variables, everything
under that element re-themes with no per-component change. Each viewer
below scopes the theme to its own preview — switch the theme and only that
viewer changes:
Controlling the theme in code
import { useTheme } from '@cajon-ui/react';
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@cajon-ui/react. - Add a
@importfor it instyles.css.
Structural tokens (gray, text, spacing, radii, shadows) stay constant across themes — only the brand-expressive tokens change.