Skip to content

Close the alert-badge AA failure, extend the token gate, restore the brand teal - #7

Merged
DCLXAI merged 2 commits into
mainfrom
fix/contrast-callsite-and-brand-teal
Aug 7, 2026
Merged

Close the alert-badge AA failure, extend the token gate, restore the brand teal#7
DCLXAI merged 2 commits into
mainfrom
fix/contrast-callsite-and-brand-teal

Conversation

@DCLXAI

@DCLXAI DCLXAI commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Closes the two items P12 shipped with, and the gap that let one of them ship.

A live AA failure the P12 gate could not see

alerts.css put literal white on semantic backgrounds, and both failed WCAG AA in dark on surfaces a user actually reads:

before after
.al-badge (#fff on --neg) 3.16:1 4.62:1
.al-row-status.hit (#fff on --pos) 2.33:1 4.60:1

Fixed with --pos-fill/--neg-fill — identical to the semantic tokens in light, darkened in dark — following the --teal-btn idiom P12 already established rather than bending --pos/--neg, which are tuned for text on neutral surfaces and are checked against their own pairs.

P12's SEMANTIC_PAIRS check resolves token-to-token pairs declared in global.css. It structurally could not see a literal colour beside a var() background in a feature file, so this shipped green. validate-tokens.ts now carries findCallsiteContrastViolations, which reads each rule block, resolves a var() background and a literal color, and computes the pair in both themes.

The gate now states what it cannot see

"callsiteContrast": "PASS",
"callsiteContrastScope": "static CSS var()-background + literal-color pairs only — misses JS-set backgrounds, color-mix()/gradient backgrounds, and base/:hover-split pairs"

This matters more than the check itself. Four times during P12 a harness reported success while structurally unable to ask the question it appeared to answer — a validator blind to a whole property family, a codemod emitting CSS browsers silently drop, a snap that crushed values by 66% with no literal left to flag, and a 24-combination viewport matrix run in an emulator that reports vh == svh == lvh == dvh. Each was caught only because a person happened to look.

A LogoChip-shaped failure was live in production while this gate would have printed PASS beside it. A gate whose output implies more than it checks is worse than no gate, because it converts an unknown into a false assurance. So the scope travels with the answer.

Brand colour restored by splitting its roles

P12 darkened --teal #20808d#20708d as a side effect of an accessibility fix, changing the literal brand hex used by the logo mark, focus rings, links and chart strokes.

The cause was one token serving two roles with different requirements: brand identity, governed by WCAG 1.4.11 at 3:1 as a non-text indicator, and text on --teal-soft/--teal-softer, which needs 4.5:1. The stricter requirement dragged the brand hex.

--teal is back to #20808d; --teal-text carries the text role. Verified: --teal clears 3:1 against all five surfaces in both themes (light 4.02–4.63, dark 5.07–6.30), and --teal-text clears 4.5:1 on both tinted surfaces in both themes (light 4.72/5.07, dark 4.56/5.22). Dark never needed the split — #35a4b2 already passed at 4.56/5.22 — which is why only :root changed.

The audit found ~30 text call sites, not the 8 the task named, and two of those named the wrong background token. Every one of the 62 --teal/--teal-text sites was classified by hand and re-classified independently in review; the ones left on --teal are borders, outlines, chart strokes, icon glyphs, the logo SVG and the large 404 digits.

Found while auditing, fixed in passing

LogoChip's fallback avatar rendered #fff at 2.96:1 in dark — live, and invisible to the new gate because its background is set via a JS style prop. Now 4.55:1 via --teal-btn. Two color-mix() sites in the same family were fixed the same way.

Verification

npm run check exit 0 — 63 files / 284 tests, every gate PASS with literals: 0.

Both gates were watched to fail. Reverting .al-badge to --neg produces callsite-contrast: .al-badge — #fff on --neg is 3.16 in dark, needs 4.5; collapsing --teal-text back onto the brand hex produces contrast: light --teal-text on --teal-soft is 3.92, needs 4.5. Both restore clean.

Every ratio was recomputed independently in review against the WCAG formula, including several not asked for. No discrepancy was found.

Known limits

The callsite check is a textual per-rule-block scan and misses JS-set backgrounds, color-mix()/gradient fills, and pairings split across a base rule and its :hover variant — now stated in its own output. A pre-existing typo in PriceChart.tsx's --pos fallback (#0d8259 vs the real #0d7259) is left alone as out of scope; it only fires if getComputedStyle fails to resolve the variable.

🤖 Generated with Claude Code

DCLXAI and others added 2 commits August 7, 2026 16:25
…d teal

Issue 1 — .al-badge and .al-row-status.hit painted a literal `color: #fff`
beside `background: var(--neg)`/`var(--pos)`, which is 3.16:1 / 2.33:1 in
dark and invisible to the token-pair gate. Introduced --neg-fill/--pos-fill
(identical to --neg/--pos in light, darkened in dark, same idiom as
--teal-btn) and pointed the two badges at them. Extended validate-tokens.ts
with findCallsiteContrastViolations, which reads each CSS rule block outside
global.css and checks a literal `color` against a same-block
`background: var(--token)` in both themes at 4.5:1 — it cannot see
JS-driven backgrounds (ui-logo's `bg ?? 'var(--x)'`), color-mix()/gradient
fills, or a pairing split across two selectors (a :hover rule that only
touches `color`); those are named in the function's doc comment.

Issue 2 — restored --teal to its literal brand hex (#20808d), reverting
P12's accessibility-driven darkening to #20708d. That darkening fixed
--teal-soft/--teal-softer text contrast but dragged the literal brand hex
(logo, focus ring, chart stroke) along with it. Split off --teal-text
(#20708d in light — P12's already-vetted value; unchanged from --teal in
dark, which already cleared 4.5:1) for every consumer that renders actual
text: the 8 places named plus ~30 more found by auditing every
`var(--teal)` call site — hover-link states, kickers on hero gradients,
summary/eyebrow labels, and two color-mix() tint chips — several of which
sit on --bg-hover/--bg-subtle/--bg-inset or --teal-softer, not just
--teal-soft, and would have newly failed AA had they stayed on the
restored brand hex. Added --teal to NON_TEXT_INKS (3:1 vs the five neutral
surfaces) and swapped SEMANTIC_PAIRS' teal entries from --teal to
--teal-text against both --teal-soft and --teal-softer (the latter pairing
was previously ungated). Also fixed LogoChip's fallback avatar
(bg ?? 'var(--teal)' with a literal `color: #fff` in ui.css) to use
--teal-btn instead — the identical white-on-solid-fill shape already
solved for .ui-btn.primary, discovered live-failing in dark (2.96:1) while
auditing --teal's consumers.

Every new/changed gate was watched to fail with the exact reported ratio,
then restored to green; a comment-wording bug in the token parser (a
"--teal:" substring inside prose broke the regex) was caught the same way.
Verified live in the browser in both themes: the alert badge and hit-status
colors, the teal-soft/-softer chip pairs, and the reverted brand hex on the
logo mark.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review Minor: the gate's JSON output said "callsiteContrast": "PASS" with
no signal that PASS means "no literal-colour-beside-a-single-var-background
pair failed" rather than "no callsite contrast problems exist" — the exact
failure mode this phase kept hitting, a harness reporting success while
structurally unable to ask the question it appears to answer.

Added a callsiteContrastScope field next to callsiteContrast, naming the
three shapes the check cannot see (JS-set backgrounds, color-mix()/gradient
backgrounds, base/:hover-split pairs) in the report a CI reader actually
sees, not just in a comment ninety lines up at the function.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DCLXAI
DCLXAI merged commit 0016174 into main Aug 7, 2026
6 checks passed
@DCLXAI
DCLXAI deleted the fix/contrast-callsite-and-brand-teal branch August 7, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant