Colour
One gamut, 15 coordinate systems. Every solid below contains exactly the same colours — the ones an sRGB display can make. What changes is where each system decides to put them, and the shape is the argument.
- Reading it
- A cube in one space is a cone in another and a spindle in a third. The shape tells you what that system thinks “close together” means.
- Controls
- Drag to orbit, scroll to zoom, click the solid to sample the colour under the pointer. Focus the view and the arrow keys orbit, + and − zoom.
- Drawn with
- Canvas 2D and the site’s own colour engine — no 3D library, no WebGL context to be refused. Roughly eleven thousand points, depth-sorted every frame.
Spaces
OKLCH08/15
The one this site is built inOKLab in polar form. The spike is the whole story: chroma available at a given lightness varies enormously by hue, so asking for a flat 0.2 chroma across a palette will clip in yellow and look washed out in blue. Every colour on this site is derived by asking this shape what it can hold.
The ceiling is a function of hue. Ask it, do not guess it.
Render
- Mode
- The six faces of the RGB cube — which is the gamut’s boundary in every one of these spaces.
- Camera
- Show
- Shading is off by default and stays gentle when on. It reads as depth, but it is a lie told about the colour — and this is a page about the colour.
Track a colour
- L
- 0.687
- C
- 0.170
- H
- 36°
- Called
- Fetches 31,918 handpicked names — about 300KB, so only on request.
The same colour, read off 15 different rulers. Switch spaces with the marker on and watch the numbers change while the dot stays on the same physical colour — that gap is the entire reason colour management exists.
But I asked for one lightness
The shortest proof of the thing this page keeps asserting. Ask both models for a row of colours at one lightness; under each row is the grey a viewer would actually match those colours to. Same request, two answers, and only one of them is the answer you meant.
every swatch asked for L 50%
every swatch asked for L 0.50
- Lightness
- 0.50
- Colourfulness
- 0.90Drag it to zero and both rows go flat — the disagreement is entirely about what colour does to apparent brightness.
- The point
- The second strip in each column is the grey a viewer would match each swatch to. One column is ragged and one is flat, and both were asked for exactly the same thing. After a slide in meodai’s palette-generation lecture.
Generators
Two ways of producing a ramp, both from meodai and both working in HSL — which is exactly why they are here rather than anywhere else on this site. HSL’s “lightness” is not lightness, and the bars under each ramp are what that costs. Neither library will tell you; judging a ramp needs a perceptual space, and that is the one thing this page has lying around.
bars: perceived lightness (OKLab L)
- Evenness
- Steps between neighbours run 0.013 to 0.158 of perceived lightness — 11.9× between the smallest and largest. All three generators work in HSL or HSV, where a constant step in L is not a constant step in lightness; this is the size of that gap.
- Chroma used
- 79% of what these hues can hold at these lightnesses, on average. Near 100 means the ramp is pressed against the gamut wall and a wider display would not help it.
- Ends
- APCA Lc 25 between first and last. Under 60 — these two cannot carry body text on each other. Hue travels 133°.
- Steps
- 9
- Anchors
- First hue20Second hue240
- Path
- How the walk between the two anchors is paced. The curve changes where steps bunch up — and the bars above show it landing somewhere other than where you asked.
- In the gamut
- Scroll back up with OKLCH selected. A ramp is a path through the solid, and seeing the path is how you notice it wandering in hue or flattening out where the gamut pinches.
Edit the conditions, not the colours
Every generator above asks you to choose a curve. This one asks you to light a room — one sphere, a five-sided box, three coloured lights — and the palette falls out of it. It is the only one here that shows you why its colours belong together, because you can watch them all being made by the same light. Raytraced on the fly by ray-color.
drag a light · shift-drag to send it behind the sphere
- Lights
- 0.90.30.2
- Scene
- Three directional lights, red key with yellow and mint fills. The classic three-point setup.
- Samples
- 7 points along the circle
- Evenness
- Steps of 0.018 to 0.241 in perceived lightness — 13.6×. Measured like the curve generators above, though it is not really the same question: nobody asked this palette to be even, they asked it to be one room.
- In the gamut
- Worth doing with OKLCH selected. A lit sphere samples a narrow, curving band of the solid — which is exactly what makes the result hold together, and what a curve drawn through colour space has to imitate on purpose.
Pigment models
Everything above is a way of addressing light. This is the other tradition: red, yellow and blue as primaries, mixed the way paint mixes — taught in every art room, and wrong about physics in ways that stopped mattering once it started working. Thirty-six wheels read off their original sources, from Boutet in 1708 to a pixel-art palette from 2024, by way of RYBitten.
- Showing
- Chromatic Circle
Johannes Itten · 1961 - Lightness
- Twelve hues spanning 0.318 of perceived lightness — 12th most even of 36. A wheel drawn as twelve equal steps is nothing of the kind.
- Hue
- Largest gap between neighbouring hues is 75°, against the 30° an even twelve would give. Every one of these models leaves a stretch of the perceptual circle empty.
- Range
- Across all 36 models, lightness spread runs from 0.202 to 0.606. Three centuries of careful people, disagreeing by a factor of three.
- In 3D
- The first is always a cube — that is the model’s own geometry. The second is the shape of its assumptions, and the lopsidedness is the point.
Thirty-six models, by year
Blue and yellow
The oldest fact in colour, and the one digital tools get wrong by default. 4 models, the same two colours: the ones that average go grey in the middle and the ones that model pigment go green. That is not a bug in anyone’s code — averaging two lights and mixing two pigments are different physics.
What a plain lerp and most CSS gradients do. Averages the numbers the display is handed.
Perceptually even, which removes the muddy middle of an RGB ramp — but it is still two lights being blended.
Reconstructs a reflectance curve for each colour and mixes those. This is how paint behaves.
- Mixing
- and
- Steps
- 9Odd, so there is always a true middle to ring.
- Chroma
- The number beside each row is how colourful its midpoint is. Averaging two near-complements drives it toward zero — that is the grey everyone complains about, and it is not a bug, it is what averaging two lights does. Kubelka-Munk holds 0.134 because it is not averaging lights at all.
- Why no RYB
- The pigment models above map a recipe to a colour, and that mapping has no inverse — so there is no way to ask what two arbitrary screen colours would be as RYB recipes, and no honest RYB row to add here.
The chroma ceiling
The spindle’s silhouette, read as a number. How much chroma sRGB can hold at one lightness, hue by hue — the fact that governs every palette this site generates, and the one thing the 3D view can show you but not tell you.
- Peak
- 0.297 at hue 328°
- Floor
- 0.122 at hue 200°
- Spread
- 2.4× between the most and least accommodating hue at this lightness. A palette that asks every hue for the same chroma is asking one of them for something it does not have.
- Tracked
- chroma 0.170 against a ceiling of 0.205 at its own lightness — 83% of the way out.
- Lightness
- L = 0.72
One hue, cut open
The solid shows the whole gamut and the ceiling curve shows the peak at every hue. Neither answers the question someone building a ramp actually has: at this hue, how much chroma is there at each lightness, and where is the widest point?
- Hue
- Cusp
- The widest point at this hue is 0.224 chroma, at lightness 0.67. Every ramp through this hue has to get past that point, and a ramp that ignores it either clips or leaves colour unused.
- Tracked
- Sitting at 83% of the way to the wall at its own lightness — nutelch calls that relC, and it is the quantity the relative-chroma space above rescales the whole solid by.
When it does not fit
Everything above shows that colours fall outside sRGB. This is what gets done about it — and it is the decision the rest of this site rests on. Push chroma past the ceiling and the two repairs stop agreeing.
Asked for
Outside sRGB and outside Display P3 — no display shows this, so the swatch is already the P3 repair.
Chroma reduced
What this site does. Lightness and hue are held; only saturation gives.
ΔL +0.000 · ΔC -0.119 · ΔH 0.0°
Channels clipped
What clamping RGB does. Cheap, and it moves the two things a ramp depends on.
ΔL +0.034 · ΔC -0.067 · ΔH 7.5°
- Lightness
- 0.62
- Chroma
- 0.290 · ceiling 0.171
- Hue
- 150°
- Verdict
- This hue holds 0.171 chroma at this lightness and you asked for 0.290. Clipping channels moved lightness by 0.034 and hue by 7.5°; reducing chroma moved neither.
- As CSS
- oklch(0.62 0.171 150)
Notes
- Gamut
- What a display can reproduce. A volume of real colour.
- Space
- A coordinate system for naming colours. Not a gamut, and the two are confused constantly — “OKLCH is wider than sRGB” is a category error.
- Why OKLCH
- This site derives its palette here. Lightness in OKLCH is perceptual, so a dark theme is arithmetic rather than guesswork — and the spindle shows the catch: how much chroma you can have depends sharply on hue.
- After maxrovensky
- The idea, the taxonomy and twelve of the spaces come from Color Space Studio. The implementation here is this site’s own — its colour engine, its renderer, no code taken. The pigment models, relative chroma and the generators came later, from meodai’s libraries; see ATTRIBUTION.md.