Colors
Covers: brand colors, accent colors, neutral palettes, text colors, default color families, semantic color scales.
- Never default to indigo as the brand/accent color: use it only if the project already does or the user requests it.
- Never default to
gray-*orslate-*for neutral/text colors: use them only if the project already does or the user requests them; preferzinc-*orneutral-*. - Prefer near-black and near-white over pure
#000and#ffffor large surfaces and text-heavy UI. Pure extremes are reserved for deliberate contrast moments. - When a palette has a clear warm or cool bias, tint neutrals slightly in the same direction. Do not mix warm-neutral backgrounds with cool-neutral foregrounds unless the brand system already does.
- On saturated fills, soften secondary text with a lighter tint of the fill hue or transparency rather than generic grey. Verify the resulting contrast in the rendered component.
- Give palette colors distinct brightness roles as well as different hues. Similar-brightness accents compete, especially in charts, badges, and status-heavy UIs.
- Increase contrast for primary tasks and important content; lower contrast for structural support like dividers, shadows, inactive chrome, and decorative marks.
Semantic color scales
When defining a custom multi-step palette, give each step a role so component states are derivable, not hand-picked: steps encode intent, not just lightness. For a 10-step scale (scale the mapping to the project's actual step count):
100background,200hover background,300active background400border,500hover border,600active border700solid fill (high contrast),800solid fill hover900secondary text and icons,1000primary text and icons
Derive states by stepping up the scale: fill 700→800 on hover; background 100→200 (hover), 300 (active); border 400→500→600. Build the scale once; reference roles, never pick a new color per state.
Hold chroma as high as the gamut allows at each step rather than letting it fade toward neutral through the middle of the ramp, which is what makes a scale look chalky. Chroma has to fall away at the extremes because the gamut narrows there, so that is expected, not drift. When lightness alone leaves a difficult hue muddy, rotate the hue slightly as you step: toward yellow as the scale lightens, toward blue as it darkens, keeping the total shift within about 15 degrees end to end so the colour keeps its identity. Author the ramp in oklch() so equal lightness steps stay perceptually even across hues; HSL lightness is not perceptual.