Commit Graph
2 Commits
Author SHA1 Message Date
jheapsandClaude Opus 5 c1d0105d12 Answer the press instead of eating it
The card picker greys out a card that is already dealt and hangs the reason
off a `title`. Measured on an iPhone with three hands out: seven of the
fifty-two were dead, none of them could take focus, and tapping one changed
nothing at all — no toast, no text, not a byte of DOM. The tool's answer to
"who has the ace of spades?" existed and was reachable only with a mouse.
The header's two buttons were the same, on a new dealer's first screen, and
Export CSV was greyed out with no explanation written anywhere.

`disabled` is the wrong attribute whenever there is something to say: it
drops the control out of the tab order, so a screen reader never lands on it
to hear the description, and it eats the tap on a touch screen, where the
hover that would have shown the `title` does not exist. `aria-disabled`
announces the same state and leaves the control reachable, so one capture
listener can turn the press into a sentence — in a toast, or inside a sheet
that is standing on top of the toast.

It paid for itself in the picker's keyboard too. The arrows hunted past
dealt cards because a `disabled` button cannot hold focus, and the hunting
did the exact thing the grid's no-wrap rule was written to prevent: Right
from A-spades over a dealt A-hearts landed on A-diamonds, so the column
shifted and the next press of Down walked a different suit. A cell that can
hold focus needs no hunting, and the APG asks for that inside a composite
widget anyway.

The line that answers is one line by measurement, not by taste. Its box is
318px on a Galaxy S8 at 20px of root text; the first wording drew 332px and
wrapped, shoving fifty-two targets 21px down mid-tap, and twenty-four capital
Ws draw 434px whatever the wording, so the box is what holds.

Two things the sweep found on the way. It opened the card picker by
un-hiding an overlay whose grid had never been painted, so for its whole
life it audited an empty sheet; it now opens it the way a dealer does, with
cards out and the answer showing. And the slot buttons above the grid were
named to a screen reader by the em dash they draw when empty.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
2026-09-13 22:41:06 -06:00
jheapsandClaude Opus 5 382238e708 Tell the browser the page is dark, and stop painting over it instead
Everything in this stylesheet is a colour it paints. `color-scheme` is the half
it cannot: the browser draws the checkboxes, the menu a <select> opens, the
scrollbars, the caret, the spellcheck underline and the autofill wash, and with
no scheme declared it draws every one of them for a light page. Measured,
`color-scheme: normal` on a #141414 ground — three checkboxes in Table Setup
rendering as bright white squares, the loudest objects on the screen and
brighter than the gold, and two more in the seat sheet doing it over the felt.

The comment on the pot wizard's hand-painted checkbox called it "the last raw
browser control in the tool". Six others were still the platform's, and three
of those were still 13x13 against a 24px floor this file had already written
down once — in a comment that explains the floor, attached to a rule naming one
checkbox by id.

One declaration on :root moves all six, and moves them natively, which is the
part worth having: a control the browser draws still answers Windows High
Contrast Mode, still matches the platform the dealer already knows, and cannot
lose its tick to a stylesheet. `accent-color` makes the checked state the green
this tool already uses for yes — the same #1e8449 the painted box fills with,
so the one drawn checkbox and the six native ones agree rather than nearly
agree.

The painted one stays painted, because it is not a setting: it is the box a
dealer ticks to move money with players watching, and it wants a fill that
reads across a table. But it now pays what painting costs. A tick drawn as a
`background` on a pseudo-element is not a colour forced-colors mode knows how
to replace, so it was simply gone — no visible checked state at all in Windows
High Contrast Mode, on the dialog that pays the table. System keywords are the
only colours guaranteed to survive, because they are the palette.

Three other things fell out of looking:

The id-scoped 24px rule existed three times over — once in the open, once under
`max-width: 700px`, once under `pointer: coarse` — and still reached one box of
six. Said about checkboxes instead, once.

A colour swatch declared 32px wide measured 22 with a mouse: flex-shrink, the
exact mechanism the coarse-pointer block had already been bitten by and written
a note about. It gets the same `flex: none` the touch case got.

Quick Split is the darker of the two pages and had never declared a scheme
either. It has no checkboxes to go white, but a dealer opening it from the felt
should not find a light scrollbar down the side of it.

1104 tests pass; the 418-audit sweep is clean.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
2026-09-11 18:00:05 -06:00