I spent years writing my palettes as lists. A light theme, a dark theme, eight roles on each side, and the slightest change of background forcing me to realign the other seven by hand.

What a list of colours hides

A palette written as a list looks like a set of decisions. Counting both themes and the two contrast levels on my site, that came to a hundred and ten values. The decisions themselves came to five or six. All the rest was just the consequence, copied out by hand because the file did not know how to compute it.

The price is not paid at writing time, it is paid six months later. Faced with a hard-coded colour, nobody can say whether it is still right. All you know is that it was set one day, by eye, in a context that has been forgotten.

The hand-written share of a palette of a hundred and ten values A cloud of a hundred and ten round dots of equal size, laid out in five rows of twenty-two. All are pale fills outlined with a thin stroke, except the first six of the bottom row, marked in the accent colour and gathered under a bracket. Below the bracket, two labels: six, then written by hand. On the right, below the rest of the cloud, one label: the rest, derived. Top left, the tag a hundred and ten values. A HUNDRED AND TEN VALUES six written by hand the rest, derived
What is not marked was never decided, only copied out.

Two anchors, and relationships

The model fits in one sentence: a theme swaps only two values, the lightness of the background and that of the ink. Everything else follows from them. The greys of secondary text are fades of the ink. Cards and alternating bands are lightness offsets taken from the background.

My site now declares six things per theme. Not a single hard-coded colour left. What read like an inventory now reads like an intent.

Contrast stops being a palette

That is the consequence I had not seen coming, and it is the best one.

I had built a contrast setting that slid between two hand-tuned palettes. Thirty-six colours for two levels, and no way to add a third without redoing everything.

Once the colours are derived from the two anchors, lowering the contrast simply means bringing those anchors closer together. One variable, from zero to one. Everything follows. The site’s slider fits into a single number where it used to take two palettes.

Measured at both ends: 15:1 at the most contrasted, 4.6:1 at the softest, in both themes. The accessibility threshold is held by construction, not by the setting.

The travel of the two anchors, from most contrasted to softest Two identical horizontal bands, graduated from the densest fill on the left to the palest on the right. On the top band, tagged at the most contrasted, fifteen to one, two widely separated marks carry the labels ink and background. On the bottom band, tagged at the softest, four point six to one, the same two marks have moved towards the centre. Between the bands, two dashed arrows point inwards on either side of the label the anchors move closer. Below the bottom band, a rule measures the remaining gap, and under it a distinctly shorter dashed bracket in the accent colour carries the label accessibility threshold. AT THE MOST CONTRASTED 15:1 ink background the anchors move closer AT THE SOFTEST 4.6:1 ink background accessibility threshold
The setting brings the two anchors closer, it never lets them reach the threshold.

What I take from it

A colour library is not judged on the number of shades it produces. It is judged on the number of values it leaves you to write by hand.

Six per theme is a system. A hundred and ten is a spreadsheet somebody painted.