Home / Snippets / Color & Theming /
Muted palette
Low-chroma OKLCH color palette for subtle, sophisticated interfaces. Desaturated colors that feel elegant without being gray.
Quick implementation
:root {
/* Muted palette — L 0.55, C 0.04, varying H */
--muted-blush: oklch(0.55 0.04 30);
--muted-sand: oklch(0.55 0.04 75);
--muted-sage: oklch(0.55 0.04 145);
--muted-slate: oklch(0.55 0.04 200);
--muted-dusk: oklch(0.55 0.04 265);
--muted-mauve: oklch(0.55 0.04 310);
/* Near-neutral — chroma dialed to 0.02 */
--muted-stone: oklch(0.55 0.02 260);
}
/* Usage: background chips, subtle borders, muted icons */
.chip--blush { background: oklch(0.25 0.03 30); color: oklch(0.80 0.04 30); }
.chip--sage { background: oklch(0.25 0.03 145); color: oklch(0.80 0.04 145); }
.chip--dusk { background: oklch(0.25 0.03 265); color: oklch(0.80 0.04 265); }
/* Generating a tonal scale from a muted base */
.surface-subtle { background: oklch(0.20 0.02 265); }
.surface-raised { background: oklch(0.24 0.02 265); }
.surface-overlay { background: oklch(0.28 0.03 265); }
/* Dark-mode muted text on dark backgrounds */
.text-muted-blush { color: oklch(0.72 0.04 30); }
.text-muted-sage { color: oklch(0.72 0.04 145); }
.text-muted-dusk { color: oklch(0.72 0.04 265); }
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior design systems engineer building color palettes for sophisticated interfaces.
Goal: A muted OKLCH color palette where each color has low chroma (0.02–0.06), a distinct hue, and consistent perceptual lightness — suitable for dark UI backgrounds, subtle chips, and de-emphasized text.
Technical constraints:
- All colors must use oklch(L C H) syntax — no hex, hsl, or rgb.
- Fix lightness at a single consistent value (e.g. 0.55) and chroma at a low constant (e.g. 0.04) across the palette — vary only hue.
- Use at least 6 hues evenly spaced or semantically named (blush, sand, sage, slate, dusk, mauve).
- Include a near-neutral "stone" with chroma 0.02 to show the difference from pure gray.
- For dark UI use, provide a tonal scale for each hue (dark surface ~L 0.20, raised surface ~L 0.24, text ~L 0.72).
- Expose everything as CSS custom properties on :root.
Framework variant (pick one):
A) Plain CSS custom properties on :root — reference as var(--muted-sage) etc.
B) JavaScript design token object exported from tokens.js — generate matching CSS variables programmatically.
Edge cases to handle:
- Fallback for browsers without oklch support: provide a @supports not (color: oklch(0 0 0)) block with hsl fallbacks.
- APCA contrast: verify that L 0.72 text on L 0.20 backgrounds meets minimum contrast for body text.
- Gamut clipping: note that C 0.04 is safely within sRGB gamut at all hues — no display-p3 needed.
- Semantic naming conflict: if a project uses "success = green", do not name the sage variant "success" in the palette layer — keep palette and semantic tokens separate.
Return CSS custom properties and a usage example.
Why this matters in 2026
Most dark-mode palettes collapse into high-contrast accent colors on near-black backgrounds, leaving no visual language for secondary content, muted labels, or categorical distinctions. A muted palette — colors with the same perceptual lightness but distinct hues at low chroma — solves this. OKLCH makes it trivially easy: hold L and C constant, rotate H. In any other color space, matching perceived brightness across hues requires manual correction for every color.
The logic
OKLCH's lightness axis is perceptually uniform, meaning oklch(0.55 0.04 30) and oklch(0.55 0.04 265) appear equally bright to human vision — something that HSL cannot guarantee because it treats all hues as equally luminous when they demonstrably are not (yellow appears far brighter than blue at the same HSL lightness). By locking L at 0.55 and C at 0.04 and rotating H through the spectrum, you get a set of colors that look like they belong together: recognizably different hues but never competing for visual weight. Chroma at 0.04 sits low enough to feel quiet, but above 0.02 (near-neutral) enough to read as distinctly colored rather than just gray.
Accessibility & performance
Muted colors at L 0.55 do not meet WCAG contrast requirements against dark backgrounds on their own — they are intentionally de-emphasized. Use them only for decorative surfaces, category chips with additional text labels, or supporting text where the context makes meaning clear without relying on the color alone. For text that must be readable, step up to L 0.72–0.80. CSS custom properties resolve at paint time with zero runtime cost, and oklch() is supported in all modern browsers; a @supports not fallback to hsl() covers the rare edge case of an older user agent.