What we measure, and what we refuse to guess.
Contrast is arithmetic, and every number in a report can be checked by hand. Here is exactly what the engine does.
WCAG 2.x contrast, in sRGB
Relative luminance is computed per channel with the standard sRGB transfer function, and the ratio is (lighter + 0.05) / (darker + 0.05). Black on white is 21:1. Nothing here is our own invention, and any checker that disagrees with us on a pair of opaque colors is wrong.
The threshold depends on the type, not on the tag. Normal text needs 4.5:1. Large text needs 3:1, and large means 24px, or 18.66px when the weight is 700 or more. A 20px heading is not large text, which is the single most common false pass in hand-checking.
A real browser, scrolled
We load the page in Chromium at 1440×900, wait for it to settle, then scroll it top to bottom so lazy and reveal-gated sections paint before anything is measured. A static read of your CSS cannot tell you what composited on screen after the cascade, after JavaScript, and after a semi-transparent panel.
Backgrounds are resolved by walking up the tree and compositing alpha, which is how text on rgba() gets a truthful number rather than an optimistic one.
Pairs, not elements
A page with 83 failing elements usually has about nine failing color pairs. You do not fix elements, you fix a pair once and it lands everywhere it is used. Pairs are keyed by foreground, background and required ratio together, because the same two colors can legitimately pass in a heading and fail in a caption, and those are two findings with two different answers.
Lightness moves, hue does not
The replacement is found in OKLCh. We hold hue exactly, search lightness for the smallest move that clears the required ratio, and reduce chroma only when that lightness falls outside the sRGB gamut, in which case the proof says so and by how much.
This is arithmetic, not a language model. It is instant, it costs nothing to run, and it returns the same answer every time. It also means we can tell you honestly when a hue cannot carry body text at any lightness, instead of inventing a hex that misses.
Foreground fixes are preferred over background fixes, and a background change large enough to be a redesign is not offered at all. Repainting your page to rescue one label is not a fix.
The things we will not score
Text over a photograph or a gradient has no single background, so there is no honest ratio to report. Those elements are listed separately and counted, never folded into a score to make it look thorough. Every automated accessibility tool that reports a clean sheet on a page full of hero imagery is telling you something it cannot know.
Contrast is also not accessibility. It is one criterion of many, and a passing proof is not a compliance certificate. It is a measured answer to one specific question, which is more than most sites have.
This site is held to it
Every color on Contrastproof is the output of the same repair function, and a test in the repository fails the build if any pair on this page drops below AA. The secondary gray you are reading started at 3.90:1 and was repaired to 5.18:1. The orange is cleared only for display sizes and marks, which is why no small text on this site is orange, and why the buttons put ink on the orange rather than white, since white on it is 3.53:1 and fails.