⚠️ Design system CSS not found. Check the path in cms/docs.config.js → designSystemPath, then re-run npm run docgen.

Colour Pairing

Check any two palette colours before the pair ships

Open Tool
Tools / Colour Pairing
Download .md file
Open .md in new tab
On this page
  • What it measures
  • Choosing a pair
  • Reading the result
  • Sharing a pair
  • Primitives and production
  • What it does not measure
  • When nothing can be measured

The Colour Pairing tool measures any two colours from the palette against the Web Content Accessibility Guidelines (WCAG) 2 contrast thresholds. Pick a text colour and a background. The specimen under the bar is painted in the pair and reports its ratio, and the Text grade filter narrows both grids to the colours that clear the level you set.


What it measures

The tool reads the palette from the page it runs on, so a brand that overrides the ramps in its theme sees its own colours, not the engine defaults.

  • The eight accent hues at every step: --<hue>-lighter, --<hue>-light, --<hue>, --<hue>-dark
  • Six of the neutral steps: --neutral-50, --neutral-100, --neutral-300, --neutral-500, --neutral-700, --neutral-900
  • --white and --black

That is 40 colours in all. The neutral ramp has 13 steps; the six here are the ones the semantic tokens map to, and the brown ramp is out with them. The grids leave out a token the brand does not define, and one that carries transparency, because one number would be wrong over most surfaces. The footnote under the grids counts each cause separately.

Semantic tokens (--text-primary, --background-secondary, --status-*) are not in the set. They change with the theme and some carry transparency, so a single reading would be wrong in one of the two themes.


Choosing a pair

Two grids, every palette colour in each: Text colour on the left, Background colour on the right. Select a tile on either side and the specimen follows. The chosen tile carries a check and a ring; every other tile is its colour and nothing else, so the grids read as the palette rather than as a table. Hovering a tile names its token, and so does a screen reader.

Text grade is how the grids answer both questions at once. AA and up leaves standing the colours that clear 4.5:1 for normal text against the other side's choice; AAA only leaves the ones that clear 7:1. What survives is what works: which text colours work on this background, and which backgrounds work under this text. The filter always grades for normal text, so a colour that only clears 3:1 is hidden under AA even though it passes for large text and for graphics. The chosen tile always stays, whether or not it clears.

Each grid is one tab stop. Arrow keys walk it in reading order, and the pair follows the tile you land on; the filter removes tiles from that walk, and your current pick always stays in it.

Swap colours exchanges the pair. The ratio does not change, because WCAG 2 measures luminance in both directions the same way; what changes is which colour is painted where.


Reading the result

The specimen reports the ratio to two decimal places, cut rather than rounded. A pair at 4.499:1 fails AA, and the tool says 4.49:1. The tool compares every number before it shortens it. The badge beside the number carries the grade, and it keeps page colours rather than the pair, so a failing pair does not take its own verdict down with it.

The specimen paints the pair at both sizes the checks distinguish, 16px and 24px, and stays in view while the grids scroll. The tool marks each check below Pass or Fail against the pair it is showing; graphics has no AAA level to mark, and the table says so in the cell.

Threshold Applies to
Normal text AA, 4.5:1 Text under 24px, or under 19px bold
Normal text AAA, 7:1 The same text, at the enhanced level
Large text AA, 3:1 Text from 24px, or from 19px bold
Large text AAA, 4.5:1 The same text, at the enhanced level
Graphics and UI AA, 3:1 Component boundaries, focus rings, icons that carry meaning

Large text is WCAG's 18pt, or 14pt bold. In CSS pixels that is 24px, or 18.66px bold, which the tool rounds up to 19px so the rule errs on the safe side.

The grade is one of four: AAA (7:1 and above), AA (4.5:1 and above), Large AA (3:1 and above), or Fail. It is written beside the ratio, never on the swatch, so a failing pair is still readable.


Sharing a pair

The URL always carries the pair: color-pairing.html#fg=white&bg=blue. Copy link in the page options menu copies it, and opening the link lands on that pair. The filter travels only when it is set: grade=aa or grade=aaa.

If a link names a token the brand does not define, that side falls back to its own default — --white for text, --blue for the background — and to the first colour in the palette if the default is missing too. So a link written against one brand still opens under another.


Primitives and production

Every colour the tool names is a palette primitive. Primitives are the subject here, because the ramps are what a brand tunes. In production, components take semantic tokens, and the primitive is what the semantic token points at. When the tool shows that --white clears AA on --blue, the production spelling is whichever semantic pair maps to those two. See Colour for the mapping.

Copy CSS hands you the pair as the system spells it, color: var(--white); background-color: var(--blue);, for a theme file or an experiment. Do not paste it into a component.


What it does not measure

WCAG 2's contrast ratio is the only enforceable standard today. The tool does not show the Advanced Perceptual Contrast Algorithm (APCA), the candidate method for WCAG 3, because WCAG 3 is still a working draft with no decided contrast method and the APCA licence does not cover commercial use. That is a decision to revisit when either changes.

The tool also does not composite transparency. A colour with an alpha channel reads differently over every surface, and one number would be wrong for most of them.


When nothing can be measured

The tool reads colour values by painting them to a canvas and reading the pixel back. A browser with fingerprinting protection on may refuse that readback, and the tool says so rather than guessing. Open it in another browser, or turn the protection off for this site.

A brand that defines fewer than two palette tokens gets the same treatment: nothing to pair, so the tool says so and names the fix — set the palette in the brand theme, then reload.

On this page
  • What it measures
  • Choosing a pair
  • Reading the result
  • Sharing a pair
  • Primitives and production
  • What it does not measure
  • When nothing can be measured
Previous Icon Library
Next QR Code Generator

© 2026 BlackDoctor