
Context
As the Unified Design Language evolved, we needed an extended color system with underlying logic to make palettes plug and play for any of the dozen themes.
This led me to the okLCH color space and the idea of re-balancing our colors into perceptually uniform palettes. What started as a side-of-desk project ended with 28 new color ramps, 365 colors, and a visual evolution of the brand.
Here's a high-level overview of the color system and how it works. A more in-depth post about the process is coming soon.
Overview
The primary goal was to expand our color offerings and ensure accessible contrast across themes. To that end, the resulting ramps each have steps 25 to 975 and fall within a given hue range (0 being white and 1000 black). Steps are ordered by luminance, and each step corresponds to a target contrast range.
Since steps are aligned to luminance, we can ensure consistent contrast no matter the combination.


Colors are divided into three categories: Hues (ROYGBIV & friends), Neutrals, and Alphas.
Spectrum Colors
16 chromatic ramps for primary and status slots in a theme, these represent saturated hues covering the majority of the color spectrum.
For these color ramps, the 500 step has minimum 5:1 contrast vs. white, a target derived from our brand teal . Each multiple of 100 has minimum AA contrast with steps five spots away in either direction, and 3:1 contrast vs. those four spots away.
The diagram below shows the hue range for each ramp mapped to the color wheel. Keen eyes may notice that a good number either overlap or abut their neighbors.

These "sibling" colors aren't meant to be used together; they're chosen as alternate options for common canonical status colors (red, green, blue, yellow, etc). This way you can find suitable pairings if your primary color uses a hue that's typically used for statuses.
And that leads us to the next group…which also offers variants. Nice segue!
Neutral Colors
Neutrals are for icons, text, borders, and other relatively monochromatic elements. Here we have two informal subsets: basic grays and… spicy grays.
Black is a pure gray scale from white to black. The next three have a subtle color temperature: gray is cool, zinc is warmer, and ash is a blend of the two. These have a natural teal-to-purple bias to harmonize with the default brand colors.
The latter four are more opinionated in terms of chroma: tinted with red (plum), yellow (sand), green (sage), and blue (steel). You're making a bit of a statement choosing these, but they're available to designers who want to lean into their primary hue or illustration palette, something we regularly see in more immersive K-12 products.
A key feature of the neutral ramps is their more dramatic luminance curve relative to the ROYGBIV ramps. This gives the middle steps a greater range of accessible pairing options. For example, the 500 step has 3:1 contrast with 200, instead of 100, so workhorse foreground colors remain legible on more surfaces.
Ramps also include an extra 75 step that matches the 50 step in the saturated palettes, so that neutral component backgrounds can match their spectrum counterparts. You can maaaaaybe spot this in the chart above. This also helps balance the scale, nudging the darks lowers for a more nuanced dark mode.
Alpha Colors
Black and white aphas take the luminance curve of the black ramp and apply it to their respective alpha values.
black; middle: blackAlpha on white; bottom: whiteAlpha on blackThe system also currently supports an alpha ramp for the default gray, which visually mimics the opaque version.
grayAlpha on white; bottom: grayPalettes
Hues
A single step has min. 3:1 contrast vs steps four spots away, and 4.5:1 five steps away in any palette. For example, step 400 has a 3:1 contrast ratio vs. white through 100 and 4.5:1 vs. 900 to black.
Neutrals
Alpha
Usage
Themes include slots for brand, neutral, info, success, warning, error, and highlight palettes. Semantic tokens like bg-primary point to aliases like colors.brand.500 so you only need to define which primitive ramp you want to use for each slot to get up and running. It looks something like this:
You can override individual tokens for specific needs but must make sure contrast is maintained, since the system assigns foreground and background tokens based on expected step values by default (the step being a proxy for luminance).
It sounds manual, but it can just be a matter of shifting a few tokens up or down the scale.
Theming
With 16 hues and 8 neutrals, we can map colors to semantic slots without having to worry about conflicts with brand colors.
Need your primary color to be red? Cool, your error colors can be pink or magenta. Or ruby or orange. Going for something more muted? Try navy for info and gold for warnings.
Most components also support raw colorScheme props to use a specific color from the system, even if it's not one of your designated slots.
Dataviz
The final piece of the puzzle is a dataviz palette designed with contrast and visual differences in mind. The range of colors now available allowed us to replace one-off or hardcoded colors with intentional choices.

Here's a little tool I made to test and ship our dataviz palettes:
Demo
For a simulated demo of the color system in action, check out the Theming Demo, or fiddle around with the theme settings in the header. I've used the same color palettes on this site, and though the components are different, it might give you a sense of how the colors work together.
Resources
If this kind of thing interests you, here are some resources I found useful when building out the color system:
Tools
- Huetone - A tool to create and visualize okLCH palettes from Alexey Ardov
- OkColor - an okLCH color picker for Figma
- Accessible Palette from Euguene Fedorenko
- Adobe Leonardo by Nate Baldwin for Adobe
Articles
- OKLCH in CSS: why we moved from RGB and HSL - a great primer on okLCH by Evil Martians
- How to generate color palettes for design systems by Matt Ström-Awn
- Reinventing Adobe Spectrum's Colors by Nate Baldwin
- How we redesigned the Linear UI (part II) - specifically the Appearance section
- Accessible Color Systems from Stripe