Warm grays, cool grays, and why pure gray looks dead
A gray with no hue in it is the one color that never appears in the physical world. Add a trace of chroma and the whole interface changes.
↑ Click any of these to repaint the entire site with it.
Three grays. One is neutral, one is cool, one is warm.
The difference between them is under two points of chroma in OKLCH. Nobody looking at an interface will consciously identify which one you used. Everybody will notice that one of them looks like a placeholder.
Why pure gray looks wrong#
There is no pure gray in the physical world. Every gray surface you have ever seen was lit by something with a color temperature and was reflecting light from things around it. A perfectly neutral gray is an abstraction, and the visual system reads abstractions as unfinished.
There is also a practical problem: a neutral gray next to a chromatic palette does not belong to it. The grays read as a separate system that happened to be placed nearby.
The fix is very small#
Pull the gray ramp toward the hue of your primary color. Chroma of 0.005 to 0.015 in OKLCH — small enough that nobody names it, large enough that the palette coheres.
/* Neutral — technically gray, visually orphaned */
--gray-500: oklch(55.6% 0 0);
/* Tinted toward the brand hue — same gray, now part of the family */
--gray-500: oklch(55.6% 0.010 258);Do this across the whole ramp with consistent chroma and the grays stop reading as grays and start reading as very desaturated versions of your brand color. Which is what they are.
Warm or cool#
Follow the background. If your page background is a warm off-white, warm grays. If it is cool, cool grays. Mixing produces a subtle wrongness that people notice without being able to name — a warm page under a cool card is one of those things that looks slightly cheap for no identifiable reason.
Broadly:
Warm grays (hue 40–90) read as paper, print, editorial. They sit well with serif type and photography. They feel older and more considered.
Cool grays (hue 220–270) read as screen, precision, technical. They sit well with blue accents, which is most product UI. They feel newer and more clinical.
Green-grays (hue 130–160) are unusual and worth knowing about. They read as natural and calm and appear in a lot of healthcare and sustainability work.
How much chroma is too much#
The boundary is around 0.02. Below that, people describe the color as gray. Above it, they start saying "the beige one" or "the blue-gray", which means it has stopped being a neutral and become a color.
That is a legitimate choice — a strongly tinted neutral is a real design decision and some of the best interfaces use one. Just know which one you are making, because a neutral and a low-chroma color behave differently: a neutral can sit next to anything, and a tinted one has opinions about what it sits next to.
Where it matters most#
Borders. They are the thinnest element in the interface and the most likely to look like a rendering artefact. A tinted border reads as intentional.
Disabled states. A pure gray disabled button looks broken. A desaturated version of the enabled color looks disabled, which is different.
Text tiers. Secondary and tertiary text at pure gray looks like text that failed to load its style. Tinted, it looks like a hierarchy.
Large surfaces. The bigger the area, the more the tint matters. A tinted card on a tinted page reads as one material; a neutral card on a tinted page reads as a hole.
The test#
Put your gray next to your brand color, then next to a gray from a completely different palette. If your gray looks more at home next to the stranger than next to your own brand color, it is not your gray.