Theming
Components read semantic roles, never raw colors. Override roles in your own CSS to retheme. See Colors for the full list.
:root {
/* Remap a role and every component follows */
--primary: var(--coral-500);
--on-primary: var(--clay-950);
--primary-container: var(--coral-100);
--on-primary-container: var(--coral-800);
/* Surfaces */
--background: var(--cream);
--surface: var(--paper);
--surface-sunken: #f1e4d2;
--radius: 1.6rem;
}Rebranding
Swap a role to another tonal scale. Run npm run tokens afterwards to re-check contrast.
:root {
/* Make primary blue for a different product */
--primary: var(--blue-600);
--on-primary: var(--paper);
--primary-container: var(--blue-100);
--on-primary-container: var(--blue-800);
}Dark mode
Dark mode is a .dark class on html that remaps the same roles. Clay shadows are themeable too: highlights get dimmer and drops get deeper. Use next-themes to toggle it.
.dark {
--background: #1d120d; /* warm chocolate, not black */
--surface: #2b1b14; /* raised = lighter */
--surface-sunken: #140b08; /* wells = darker */
--on-surface: var(--cream);
--primary-container: #4a1c1a;
--on-primary-container: var(--coral-200);
/* Clay depth */
--clay-hi: rgb(255 255 255 / 0.07);
--clay-lo: rgb(0 0 0 / 0.35);
--clay-drop: rgb(0 0 0 / 0.7);
}Changing the palette
Edit the brand hexes in scripts/palette.mjs, then run npm run tokens. It regenerates app/tokens.css and fails if any role pair drops below 3:1.