Contrast contract ================= Spec: descriptive guidance, not a checkable rule. It carries no forbidden and instead pair, and no `jig check` detector applies to it directly. Section: Design Tokens **Floor: WCAG 2.1 AA.** Two thresholds, and the boundary between them is a common mistake. | | Threshold | | --- | --- | | Small text — 18px or less | **4.5:1** | | Large text — 24px+ regular, or 18px+ bold | **3:1** | | UI elements — input, checkbox and radio borders; meaningful icons | **3:1** | | Decorative elements that convey no meaning | none | **Test against `fill`, not against the background.** Text and controls can sit on a `fill` surface (a tag, a badge, a highlighted row), which is the lowest-contrast case. A colour that passes on the page background can fail inside a tag. In dark mode, test against `bg-overlay` — the brightest level, and therefore the worst case for a light-on-dark foreground. **The brand colour needs 4.5:1** against both `bg-raised` and `fill`, because it is used for link and button text. **When the brand colour cannot reach 4.5:1** — a yellow or very light brand, or a dark brand on a dark surface: 1. Darken or lighten it slightly, if brand recognition survives. 2. Use `--color-text-strong` for interactive elements instead, and keep the brand colour decorative. 3. Add a border to buttons so they clear 3:1. ### APCA WCAG 2's algorithm has known failures — it will pass black text on orange and fail white text on the same orange, when the white is plainly more readable, and it works poorly on dark interfaces. APCA (WCAG 3 draft) measures perceptually and scores by size and weight rather than a flat ratio. Guidance: **for commercial work, comply with WCAG 2.1 AA**, because that is what is legally referenced. Check APCA as well, particularly on dark surfaces. Aim to pass both. APCA reference values, with the sizes they apply at — a score means nothing without one, since APCA takes size and weight into account and thin or small text scores lower for the same colours: | Score | Applies to | | --- | --- | | **90** | Preferred for body text, 14px regular and above | | **75** | Minimum for body text, 18px regular and above | | **60** | Minimum for other text, 24px regular or 16px bold and above | | **45** | Minimum for large text — 36px regular or 24px bold and above — and for interface elements | | **30** | Absolute minimum for text: placeholders, disabled button text | | **15** | Minimum for non-text elements | These thresholds are APCA's own and do not line up with WCAG's large-text definition (`C-17`, 24px regular / 18.66px bold) — the two systems measure differently, and each is right inside its own frame.