# Closed the colour system at 28 documented colours with a linter that fails a value painted but undocumented, documented but unpainted, mis‑measured, respelled as a literal, or within a perceptual distance of 0.02 of one already there.

2025

**Situation.** Colour on a site with a dark default, a light theme, a print stylesheet, a forced‑colours mode and an illustrated brand does not stay a small set on its own. It had already started to drift in the way it always does: two spellings of the same colour sitting close enough that nobody could tell them apart, values re‑typed as literals beside the tokens that defined them, and documented colours that nothing painted.

**Task.** The palette had to become a closed set with a stated distinctness threshold, and something had to enforce the closure.

**Action.** Twenty‑eight colours, each documented with the contrast ratio it measures on the surface it appears on, and eleven brand values declared once as tokens. The threshold is numeric rather than editorial: two colours closer than a perceptual distance of 0.02 in a uniform colour space are one colour with two spellings. The linter fails five different ways — a value painted but undocumented, documented but unpainted, recorded with the wrong ratio, within the threshold of one already there, or a brand value re‑spelled as a literal. It found two immediately: a theme colour that existed in two spellings 0.018 apart, and a background colour standing in for a wall it sat 0.021 from. Transparency uses relative colour syntax rather than the mixing function, specifically because the guard cannot see through a mix and a palette guard that can be evaded is not a guard. The rule that goes with it is short: change a token rather than a rule, add a colour only when none fits, and never lower a documented ratio to make a design work.

**Result.** The palette is a closed, measured set that cannot quietly grow, and the two near‑duplicate spellings that prompted it are gone. It is a constraint that occasionally says no — a design wanting a slightly different blue has to take the one that exists or make the case for a twenty‑ninth colour, and that case has to include the ratio.

---

- Role: Design Systems Engineer
- Categories: [Frontend Engineering](https://engineer.company/categories/frontend/), [Automation & CI/CD](https://engineer.company/categories/automation/), [Testing & QA](https://engineer.company/categories/testing/), [Design Systems & UI](https://engineer.company/categories/design-systems/), [UX / UI Design](https://engineer.company/categories/ux-ui/), [Documentation](https://engineer.company/categories/documentation/)
- Services: [Frontend Development](https://engineer.company/services/frontend-development/), [UI/UX Design & Design Systems](https://engineer.company/services/ui-ux-design/), [Brand, Marketing & SEO](https://engineer.company/services/brand-marketing/)

<https://engineer.company/portfolio/closed-the-colour-system-at-28-colours-133/>
