Colors
Theme tokens, brand scales, grayscale, and status colors. Values and usage.
Zazz colors come in four layers: theme, brand scales, grayscale, and status. Every color is declared in OKLCH for perceptually consistent stepping and mode transitions.
Using colors
Reference any color through its CSS variable:
.headline {
color: var(--foreground);
background: var(--background);
}
.button-primary {
background: var(--primary);
color: var(--primary-foreground);
}With Zazz utilities installed, every theme color has a matching utility class (set up the same way Tailwind would expose them): bg-primary, text-foreground, border-border, and so on.
Theme tokens
Theme tokens like --background, --primary, and --destructive resolve to specific scale values based on the active mode. The complete table of theme tokens with light and dark mappings lives on Foundations → Theme.
Brand scales
The raw color scales that brand theme tokens point into. Replace these per project to rebrand without touching any component. See Foundations → Corporate.
Each scale below has its own hex input. Adjust the base color and Generate to open a fresh 11-step palette in Tints.dev. Or edit all four defaults at once in a single editor.
A first-class theme builder is on the roadmap. For now, generate via Tints.dev and paste the OKLCH output into your variables file.
Primary
:root {
/* Primary; base #4D44E4 */
--primary-50: oklch(0.984 0.007 286.46);
--primary-100: oklch(0.94 0.025 288.37);
--primary-200: oklch(0.85 0.068 285.81);
--primary-300: oklch(0.765 0.108 284.76);
--primary-400: oklch(0.674 0.154 283.18);
--primary-500: oklch(0.593 0.193 280.79);
--primary-600: oklch(0.511 0.23 276.97);
--primary-700: oklch(0.421 0.234 273.27);
--primary-800: oklch(0.32 0.179 273.06);
--primary-900: oklch(0.229 0.127 273.39);
--primary-950: oklch(0.158 0.088 274.05);
}Secondary
:root {
/* Secondary; base #DE4917 */
--secondary-50: oklch(0.984 0.008 27.43);
--secondary-100: oklch(0.95 0.023 24.19);
--secondary-200: oklch(0.878 0.061 25.87);
--secondary-300: oklch(0.814 0.101 27.69);
--secondary-400: oklch(0.749 0.146 30.02);
--secondary-500: oklch(0.687 0.198 34.85);
--secondary-600: oklch(0.61 0.194 36.8);
--secondary-700: oklch(0.5 0.159 36.84);
--secondary-800: oklch(0.383 0.121 36.98);
--secondary-900: oklch(0.276 0.088 36.22);
--secondary-950: oklch(0.215 0.068 37.62);
}Tertiary
:root {
/* Tertiary; base #E5375B */
--tertiary-50: oklch(0.984 0.006 17.54);
--tertiary-100: oklch(0.942 0.023 11.04);
--tertiary-200: oklch(0.861 0.062 11.02);
--tertiary-300: oklch(0.772 0.11 12.13);
--tertiary-400: oklch(0.693 0.163 13.04);
--tertiary-500: oklch(0.613 0.208 14.68);
--tertiary-600: oklch(0.523 0.177 14.77);
--tertiary-700: oklch(0.432 0.147 14.69);
--tertiary-800: oklch(0.334 0.114 14.76);
--tertiary-900: oklch(0.244 0.083 14.99);
--tertiary-950: oklch(0.197 0.068 15.17);
}Grayscale
Neutrals plus the shade and tint scales derived from them. See Foundations → Grayscale.
Neutral
:root {
/* Neutral; base #888890 */
--white: white;
--neutral-50: oklch(0.9911 0 0);
--neutral-100: oklch(0.9581 0 0);
--neutral-200: oklch(0.871 0.004 286.58);
--neutral-300: oklch(0.794 0.007 286.38);
--neutral-400: oklch(0.708 0.009 286.28);
--neutral-500: oklch(0.629 0.012 286.12);
--neutral-600: oklch(0.535 0.015 285.91);
--neutral-700: oklch(0.442 0.015 285.82);
--neutral-800: oklch(0.336 0.014 285.66);
--neutral-900: oklch(0.241 0.009 285.7);
--neutral-950: oklch(0.198 0.008 285.68);
--black: black;
}Shade
Darkened overlays derived from --neutral-950. Each step is the neutral at a specific alpha. Apply over a light surface for a "darken-it" effect.
:root {
/* Shade; derived from --neutral-950 */
--shade-none: oklch(from var(--neutral-950) l c h / 0);
--shade-50: oklch(from var(--neutral-950) l c h / 0.05);
--shade-100: oklch(from var(--neutral-950) l c h / 0.1);
--shade-200: oklch(from var(--neutral-950) l c h / 0.2);
--shade-300: oklch(from var(--neutral-950) l c h / 0.3);
--shade-400: oklch(from var(--neutral-950) l c h / 0.4);
--shade-500: oklch(from var(--neutral-950) l c h / 0.5);
--shade-600: oklch(from var(--neutral-950) l c h / 0.6);
--shade-700: oklch(from var(--neutral-950) l c h / 0.7);
--shade-800: oklch(from var(--neutral-950) l c h / 0.8);
--shade-900: oklch(from var(--neutral-950) l c h / 0.9);
--shade-950: oklch(from var(--neutral-950) l c h / 0.95);
--shade-full: oklch(from var(--neutral-950) l c h / 1);
}Tint
Faded overlays derived from --white. Apply over a dark surface for a "lighten-it" effect.
:root {
/* Tint; derived from --white */
--tint-none: oklch(from var(--white) l c h / 0);
--tint-50: oklch(from var(--white) l c h / 0.05);
--tint-100: oklch(from var(--white) l c h / 0.1);
--tint-200: oklch(from var(--white) l c h / 0.2);
--tint-300: oklch(from var(--white) l c h / 0.3);
--tint-400: oklch(from var(--white) l c h / 0.4);
--tint-500: oklch(from var(--white) l c h / 0.5);
--tint-600: oklch(from var(--white) l c h / 0.6);
--tint-700: oklch(from var(--white) l c h / 0.7);
--tint-800: oklch(from var(--white) l c h / 0.8);
--tint-900: oklch(from var(--white) l c h / 0.9);
--tint-950: oklch(from var(--white) l c h / 0.95);
--tint-full: oklch(from var(--white) l c h / 1);
}Status
Status tokens cover info, success, warning, and destructive. Status colors step darker in dark mode, opposite to brand. See Foundations → Theme → Status.
Light mode
Dark mode
:root {
/* Status: light mode */
--info: oklch(0.5876 0.1389 241.97);
--success: oklch(0.596 0.1274 163.23);
--warning: oklch(0.6658 0.1574 58.32);
--destructive: oklch(0.5771 0.2152 27.33);
}
:is(.dark, .dark *) {
/* Status: dark mode (steps darker, opposite of brand) */
--info: oklch(0.5 0.1193 242.75);
--success: oklch(0.5081 0.1049 165.61);
--warning: oklch(0.5553 0.1455 49);
--destructive: oklch(0.5054 0.1905 27.52);
}Customizing colors
Override any color by re-declaring the variable. Re-target a theme token to point at a different scale step, or replace a corporate scale entirely:
:root {
/* Re-target theme tokens */
--primary: var(--secondary-600);
--destructive: oklch(0.55 0.2 15);
/* Replace a corporate scale */
--primary-50: oklch(0.97 0.02 200);
--primary-100: oklch(0.92 0.05 200);
/* ... through 950 */
}See Practices → Customization for the full override patterns, including scoped overrides for sub-apps and rebrand workflows.
Using a custom value
For one-off colors that don't warrant a scale, declare them directly in your component CSS using OKLCH:
.holiday-banner {
background: oklch(0.6 0.18 145); /* festive green */
color: var(--white);
}OKLCH keeps the value in the same color space as the rest of Zazz, so mixing and stepping behave predictably if you decide to scale the color into a full token later.