Make the layout audit usable inside modals, and stop it passing what it can't measure #97

Closed
jheaps wants to merge 1 commits from fix/casino-holdem-audit-modal-blindspot into fix/casino-holdem-quicksplit-chop
Owner

This round found no user-facing bug — it fixed the instrument that was hiding whether there was one. Saying that up front because the diff is all test harness.

#96 turned up that Quick Split had never been audited. Chasing why, the dealer table's modals had never been audited either — and the reason is the harness, not neglect. It reported the pot wizard covering the seats as ten faults and the rulings sheet as seven. A modal covering the page is what a modal is for, and an instrument that calls that a fault is one nobody can use in those states.

What changed

The audit now finds whatever is open on top and scopes the reachability checks to it — the overlays, plus the phone seat sheet, which is a body class rather than an element. The seat-ownership check is skipped outright while a sheet is open: seats behind it aren't fighting each other for taps, nothing is meant to reach them at all.

Two worse faults came out of proving the fix rather than assuming it. I injected a 20×14 button into the open wizard. The contrast check caught it; the touch-target check did not:

  • effectiveTarget returns null when elementFromPoint can't find the control, and the check treated that as a pass. Silent skips are how faults hide — the same lesson as the aria-hidden and faded-text exemptions in earlier rounds. Unmeasurable controls are now reported as warnings.
  • The probe failed on anything scrolled out of its container, which was hiding a real control: "Confirm Winner(s)", the button that pays the pot out, had gone unmeasured for thirty-six rounds. It's scrolled into view before probing now — and passes.

A checkbox inside a label is measured by its label, since tapping the label is what activates it. Without that the dedicated-dealer toggle read as an unprobeable 24px target when it has a 335×44 label around it.

Verification

On a real touch context (hasTouch, isMobile, 390×844) at a 44px minimum, across the table, the pot wizard, the rulings sheet and the seat editor: 0 failures and 0 warnings in all four — down from 10 and 7 in two of them. The tool is genuinely clean in those states.

And the check demonstrably fires now, which is the part that matters: the injected 20×14 button is reported as touch targets at least 44px(1): hittable 19x14 (drawn 20x14), where the old check returned nothing at all.

Product test suite unchanged at 387 tests, 0 failures — no application code is touched.

Stacked on fix/casino-holdem-quicksplit-chop.

🤖 Generated with Claude Code

https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb

**This round found no user-facing bug — it fixed the instrument that was hiding whether there was one.** Saying that up front because the diff is all test harness. #96 turned up that Quick Split had never been audited. Chasing why, the dealer table's *modals* had never been audited either — and the reason is the harness, not neglect. It reported the pot wizard covering the seats as **ten faults** and the rulings sheet as **seven**. A modal covering the page is what a modal is for, and an instrument that calls that a fault is one nobody can use in those states. **What changed** The audit now finds whatever is open on top and scopes the reachability checks to it — the overlays, plus the phone seat sheet, which is a body class rather than an element. The seat-ownership check is skipped outright while a sheet is open: seats behind it aren't fighting each other for taps, nothing is meant to reach them at all. **Two worse faults came out of proving the fix rather than assuming it.** I injected a 20×14 button into the open wizard. The contrast check caught it; the touch-target check did not: - `effectiveTarget` returns null when `elementFromPoint` can't find the control, and the check treated that as **a pass**. Silent skips are how faults hide — the same lesson as the `aria-hidden` and faded-text exemptions in earlier rounds. Unmeasurable controls are now reported as warnings. - The probe failed on anything scrolled out of its container, which was hiding a real control: **"Confirm Winner(s)", the button that pays the pot out, had gone unmeasured for thirty-six rounds.** It's scrolled into view before probing now — and passes. A checkbox inside a label is measured by its label, since tapping the label is what activates it. Without that the dedicated-dealer toggle read as an unprobeable 24px target when it has a 335×44 label around it. **Verification** On a real touch context (`hasTouch`, `isMobile`, 390×844) at a 44px minimum, across the table, the pot wizard, the rulings sheet and the seat editor: **0 failures and 0 warnings** in all four — down from 10 and 7 in two of them. The tool is genuinely clean in those states. And the check demonstrably fires now, which is the part that matters: the injected 20×14 button is reported as `touch targets at least 44px(1): hittable 19x14 (drawn 20x14)`, where the old check returned nothing at all. Product test suite unchanged at 387 tests, 0 failures — no application code is touched. Stacked on `fix/casino-holdem-quicksplit-chop`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
jheaps added 1 commit 2026-09-02 00:38:14 -06:00
Last round turned up that Quick Split had never been audited. Chasing that, the reason
the dealer table's modals had never been audited either turns out to be the harness,
not neglect: it reported the pot wizard covering the seats as ten faults and the
rulings sheet as seven. A modal covering the page is what a modal is for, and an
instrument that calls that a fault is one nobody can use in those states.

It now finds whatever is open on top and scopes the reachability checks to it — the
overlays, plus the phone seat sheet, which is a body class rather than an element. The
seat-ownership check is skipped outright while a sheet is open: seats behind it aren't
fighting each other for taps, nothing is meant to reach them at all.

Two worse faults came out of proving the fix rather than assuming it. Injecting a 20x14
button into the open wizard, the contrast check caught it and the touch-target check
did not:

  * effectiveTarget returns null when elementFromPoint can't find the control, and the
    check treated that as a pass. Silent skips are how faults hide — the same lesson as
    the aria-hidden and faded-text exemptions before this. Unmeasurable controls are
    now reported as warnings.
  * The probe failed on anything scrolled out of its container. That was hiding a real
    control: "Confirm Winner(s)", the button that pays the pot out, had gone unmeasured
    for thirty-six rounds. It is scrolled into view before probing, and passes.

A checkbox inside a label is now measured by its label, since tapping the label is what
activates it. Without that, the dedicated-dealer toggle read as an unprobeable 24px
target when it has a 335x44 label around it.

The tool itself came out clean: no failures and no warnings across the table, the pot
wizard, the rulings sheet and the seat editor, on a real touch context at 44px. The
value here is that those states can be checked at all from now on — verified by
injection, which the fixed check catches and the old one did not.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
jheaps closed this pull request 2026-09-02 09:58:02 -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#97