Skip to content
MM Coffee Co.
#accessibility#design systems

Your brand colours are display colours

The red that looks great at 96px fails WCAG at 11px.

I sampled this site’s palette straight out of the design comps and assumed it was fine. Cream paper, a strong red, a deep blue, a gold. It looks right.

Then I actually measured it.

Colour On paper AA normal text
Red #CD2A1C 3.94:1 fails
Gold #EDAF16 1.44:1 fails
Orange #E2622A 2.58:1 fails
Blue #145CA9 4.95:1 passes
Ink #000000 15.52:1 passes

Red was the problem. Not because it’s a bad red — at 96px it’s perfect, and large text only needs 3:1. But this design sets almost everything at label size: PROGRAM 001, STACK: ASTRO / REACT, the nav. All of it was red at 11px, all of it failing.

The fix isn’t a different palette

Changing the red would change the brand. The fix is admitting there are two jobs and two colours:

--color-red: #cd2a1c;       /* display type, fills, graphics */
--color-red-deep: #b82519;  /* anything at label size */

Same hue, same saturation, darkened until it clears 4.5:1. Side by side you can tell them apart. In context — one at 96px, one at 11px — nobody can, because you’re never comparing them directly.

Make it fail the build

The part I’d skip if I were being honest with myself is the part that matters: this will drift. Someone adds a colour, someone lightens a token, and six months later the labels fail again.

So the check reads the tokens out of the stylesheet and asserts them:

PASS  red-deep     #b82519  4.68:1  (needs 4.5:1 — small red labels)
PASS  red          #cd2a1c  3.94:1  (needs 3:1 — display headlines only)

decorative only — must never carry text:
      gold         #edaf16  1.44:1

The gold row was informative. My first version asserted 3:1 on it and failed — but gold is only ever a fill here, and purely decorative graphics carry no contrast minimum at all. A bad assertion, not a bad colour. Worth knowing the difference before you go darkening things that don’t need it.

← All notes