Color
An OKLCH color palette for CSS
Besides the seed derived tokens, Monsoon includes a fixed palette of 22 hues with 11 steps each, from 50 to 950. It is generated in OKLCH so that the same step looks equally light across hues, and every color is available as a custom property and as utilities.
The hues and steps
Five neutrals and seventeen colors: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink and rose. Steps run 50, 100, 200 and so on up to 900, then 950.
Why OKLCH
In the familiar RGB and HSL spaces, two colors with the same "lightness" number can look very different: a pure yellow looks far lighter than a pure blue. OKLCH is a perceptual space. Its lightness channel follows what people see, chroma measures colorfulness and hue is an angle. That gives the palette a useful property: step 500 of one hue sits next to step 500 of another, so swapping bg-blue-600 for bg-violet-600 keeps the same visual weight and roughly the same contrast with white text.
Monsoon generates the palette from a short list of hue definitions. Every hue shares one lightness curve from 0.975 at step 50 to 0.27 at step 950. Warm hues such as amber and yellow get a small lightness lift around their peak, which is where those colors naturally look best, and each hue drifts slightly across the steps so dark shades do not turn muddy.
Kept inside sRGB on purpose
OKLCH can describe colors that most screens cannot show. Each step is generated with a requested chroma and then reduced, by a binary search, until it fits inside the sRGB gamut. The result renders the same in every browser and on every display instead of being clipped differently by each one.
Using the palette
Every color is a custom property named --color-{hue}-{step} on the root element, written as an oklch() value. Use them in your own CSS:
.chart-bar {
background: var(--color-emerald-500);
}
.chart-bar.negative {
background: var(--color-rose-500);
}And as utilities. Text, background and border get every step; ring, outline, decoration, fill, stroke and shadow color get the middle steps 400, 500 and 600, and so do gradient stops:
<span class="rounded-full bg-emerald-100 text-emerald-800 px-3 py-1 text-sm">Paid</span>
<div class="border-l-4 border-amber-500 bg-amber-50 p-4 text-amber-900">Pending review</div>
<div class="h-24 rounded-xl bg-gradient-to-r from-sky-500 via-indigo-500 to-fuchsia-500"></div>Contrast across the palette
Because every hue follows the same lightness curve, contrast rules of thumb carry across hues. Steps 600 and darker take white text comfortably for normal sized text, and steps 100 and lighter work as tinted backgrounds for text in the 800 to 950 range of the same hue. The middle of the scale, around 400 and 500, is best for large text, icons, borders, chart series and decoration rather than small body text.
These are starting points, not guarantees: warm hues are deliberately lifted at their peak, so a yellow 500 is lighter than a blue 500 and pairs with dark text instead of white. When in doubt, measure the pair, or use the semantic status tokens, which come with tested foregrounds.
Palette or semantic tokens?
Use semantic tokens (bg-primary, bg-surface, text-muted-foreground) for the structure of your interface. They follow the seed and switch with dark mode on their own. Reach for the palette for data and meaning that should not change with the theme: chart series, category labels, tags, illustrations. For palette colors that need a different value in dark mode, add the dark: variant, for example bg-slate-100 dark:bg-slate-800.
Frequently asked questions
How many colors are in the Monsoon palette?
22 hues with 11 steps each, 242 colors, all available as --color-{hue}-{step} custom properties.
Can I use the palette colors in my own CSS?
Yes. Write var(--color-indigo-600) anywhere. The variables are defined on the root element.
Do palette colors change in dark mode?
No, they are fixed. Use the dark: variant or semantic tokens when a color should adapt to the scheme.
Which browsers support OKLCH?
All current major browsers support oklch() colors.
Try it in ten seconds
Paste this into any HTML page. No install, no build.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">