Fix the contrast the audit could finally measure #54

Closed
jheaps wants to merge 1 commits from feature/casino-holdem-contrast-audit into feature/casino-holdem-layout-audit
Owner

Contrast is the one check I've got wrong twice, both times by being clever about backgrounds. The first version read only background-color, so text on any gradient-painted sheet was measured against transparency and the dealer puck's dark "D" was reported at 1.2:1 against nothing. The second over-corrected and treated low-alpha gradient stops as opaque, scoring white-on-dark at 1.0:1. Stacked on #53.

So this one is built to be incapable of false positives rather than exact. Backgrounds composite through alpha; where a gradient is involved every colour stop is tried and the most flattering one used. A finding means the text fails even under the reading most generous to it.

Calibrated before being believed

Case Expected Measured
black on white 21:1 21.00
white on white 1:1 1.00
#767676 on white (AA boundary) 4.54:1 4.54
white on a dark gradient 17.4:1 17.40
dark text on that same gradient ~1.1:1 1.09
white over 6% white on near-black 17.6:1 17.63

Nine cases, all correct — and building them found a real bug in the check: it walked straight past an opaque gradient and offered the page background as a candidate. That made it too lenient, which is as bad as the old false positives, since it would have waved real problems through.

What it found

Both blind badges failed against their own gradients, in 9px bold text a dealer is meant to read at a glance across a table. At the worst stop: small blind 3.52:1, big blind 2.15:1.

  • Small blind keeps its blue and darkens → 4.77:1
  • Big blind flips to dark text on brighter gold → 5.84:1

The big blind change is how a gold chip is marked anyway, and it has a real side benefit: the two badges are now far easier to tell apart at speed — one light-on-blue, one dark-on-gold, rather than two pale labels differing only in hue.

Quick Split's footnote names a control the dealer is being told to reach for, and that name inherited the muted grey the surrounding aside is deliberately set in — 3.39:1. Emphasised text carrying an instruction gets its own colour now.

The felt watermark came back at 1.19:1 and is meant to. It's decoration; holding it to a reading threshold would mean making it not a watermark. It's aria-hidden now — the same claim, expressed where it also does some good — and the audit skips aria-hidden subtrees.

Validation

32 contrast passes over the table, all five overlays and Quick Split at five viewports: zero findings, zero unmeasured. The layout audit from #53 still clean across the same sweep. 137 unit tests passing. No console errors.

Contrast is the one check I've got wrong **twice**, both times by being clever about backgrounds. The first version read only `background-color`, so text on any gradient-painted sheet was measured against transparency and the dealer puck's dark "D" was reported at 1.2:1 against nothing. The second over-corrected and treated low-alpha gradient stops as opaque, scoring white-on-dark at 1.0:1. Stacked on #53. So this one is built to be **incapable of false positives** rather than exact. Backgrounds composite through alpha; where a gradient is involved every colour stop is tried and the *most flattering* one used. A finding means the text fails even under the reading most generous to it. ## Calibrated before being believed | Case | Expected | Measured | | --- | --- | --- | | black on white | 21:1 | 21.00 | | white on white | 1:1 | 1.00 | | #767676 on white (AA boundary) | 4.54:1 | 4.54 | | white on a dark gradient | 17.4:1 | 17.40 | | dark text on that same gradient | ~1.1:1 | 1.09 | | white over 6% white on near-black | 17.6:1 | 17.63 | Nine cases, all correct — and building them **found a real bug in the check**: it walked straight past an opaque gradient and offered the page background as a candidate. That made it too *lenient*, which is as bad as the old false positives, since it would have waved real problems through. ## What it found **Both blind badges failed against their own gradients**, in 9px bold text a dealer is meant to read at a glance across a table. At the worst stop: small blind **3.52:1**, big blind **2.15:1**. - Small blind keeps its blue and darkens → **4.77:1** - Big blind flips to dark text on brighter gold → **5.84:1** The big blind change is how a gold chip is marked anyway, and it has a real side benefit: the two badges are now far easier to tell apart at speed — one light-on-blue, one dark-on-gold, rather than two pale labels differing only in hue. **Quick Split's footnote** names a control the dealer is being told to reach for, and that name inherited the muted grey the surrounding aside is deliberately set in — **3.39:1**. Emphasised text carrying an instruction gets its own colour now. **The felt watermark** came back at 1.19:1 and is *meant* to. It's decoration; holding it to a reading threshold would mean making it not a watermark. It's `aria-hidden` now — the same claim, expressed where it also does some good — and the audit skips `aria-hidden` subtrees. ## Validation **32 contrast passes** over the table, all five overlays and Quick Split at five viewports: **zero findings, zero unmeasured**. The layout audit from #53 still clean across the same sweep. 137 unit tests passing. No console errors.
jheaps added 1 commit 2026-09-01 08:39:34 -06:00
Contrast is the one check I've got wrong twice, both times by being clever about
backgrounds. The first version read only background-color, so text on any of the
gradient-painted sheets was measured against transparency and the dealer puck's
dark "D" was reported at 1.2:1 against nothing. The second over-corrected and
treated low-alpha gradient stops as opaque, scoring white-on-dark at 1.0:1.

So this one is built to be incapable of false positives rather than exact.
Backgrounds composite through alpha; where a gradient is involved every colour stop
is tried and the most flattering one used. A finding means the text fails even
under the reading most generous to it.

It's checked against known answers before being believed: black on white at 21:1,
white on white at 1:1, #767676 on white at the 4.54:1 AA boundary, white over a
dark gradient, dark text on that same gradient, white over a 6% white wash on a
near-black page. Nine cases, all correct — and building them found a real bug in
the check, which walked past an opaque gradient and offered the page background as
a candidate. That made it too lenient, which is as bad as the old false positives.

What it found:

Both blind badges failed against their own gradients, in 9px bold text a dealer
reads at a glance across a table. At the worst stop: small blind 3.52:1, big blind
2.15:1. The small blind keeps its blue and darkens to 4.77:1. The big blind flips
to dark text on brighter gold, 5.84:1 — how a gold chip is marked anyway, and it
makes the two badges far easier to tell apart at speed.

Quick Split's footnote names a control the dealer is told to reach for, and that
name inherited the muted grey of the surrounding aside: 3.39:1. Emphasised text
carrying an instruction gets its own colour now.

The felt watermark came back at 1.19:1 and is meant to. It's decoration; holding it
to a reading threshold would mean making it not a watermark. It's aria-hidden now,
which says the same thing where it also does some good, and the audit skips
aria-hidden subtrees.

32 contrast passes over the table, all five overlays and Quick Split at five
viewports: zero findings, zero unmeasured. Layout audit still clean. 137 tests pass.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
jheaps closed this pull request 2026-09-01 09:32:19 -06:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jheaps/JoshHeaps.Net#54