Stand the felt up on a phone, and check which rule actually wins
A portrait phone got a square felt, so the vertical room the layout had already measured was published and then dropped: 522px of room under a 366px table on an iPhone 14, 638 under 406 on a Pro Max. The cost was seat names — 44px pucks with five of twelve clipped. --feltAspect: 1.5 spends it. Twelve seats at 390x844 go from a 44px puck with five names clipped to 66px with one; five seats go from three clipped to none; the Pixel 7's twelve-seat ring goes to zero. 1.6 and 1.7 measure byte-identical, so 1.5 is where the sweep stops paying. The three smaller phones are room-bound at any cap and measured identical from 1.15 to 1.7. The first version of this was a no-op. The rule went into @media (max-width: 700px), and @media (max-width: 900px) below it set the same property back to 1 — both match a phone, same specificity, later one wins. It measured as 1 on every phone while reading perfectly. The 900px rule is now a 701-900px range, and feltShape.test.js resolves --feltAspect through the media queries the way the cascade does so the next one of these is caught. Also tried and removed: a floor under the max-height, so a tall bar couldn't press the table flat. Twelve all in with nine side pots takes the bar to 341px, leaving 142px of room at 360x640; floored to 242 the felt keeps its shape by putting five of twelve seats behind the bar, unfloored it is flat with all twelve visible. The slit it defended against came from forcing the custom property by hand. A test asserts its absence with the numbers. Audit: 4 failing configurations and 5 offenders down to 2 and 3, both remaining ones pre-existing. 776 unit tests pass. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
This commit is contained in:
@@ -23,6 +23,7 @@ other in the page, in the load order from `TexasHoldem.cshtml`.
|
||||
| `handRank.test.js` | What beats what: categories, the wheel, kickers, best five of seven |
|
||||
| `readingTheShowdown.test.js` | The board, the picker that fills it, and who wins a side pot |
|
||||
| `theRail.test.js` | A phone on its side: which shape the bar is in, what it leaves under the felt, how a name is shortened, how the ring is pulled back onto the table |
|
||||
| `feltShape.test.js` | What shape the felt is at each phone size, resolved through the media queries in source order (see below) |
|
||||
| `invariants.test.js` | 1000 randomised hands per property (see below) |
|
||||
|
||||
## The layout audit
|
||||
@@ -155,6 +156,34 @@ something changed, and each time they only covered whatever had just been touche
|
||||
That is how the standings table shipped with a player-name column zero pixels wide
|
||||
and kept it for two rounds.
|
||||
|
||||
## Which rule wins
|
||||
|
||||
`feltShape.test.js` is here because of a change that measured as correct and was a
|
||||
no-op. The felt on a phone was made an upright oval by setting `--feltAspect` inside
|
||||
`@media (max-width: 700px)`, and forty lines below it `@media (max-width: 900px)` set
|
||||
the same property back to 1. Both queries match a phone, the declarations have the same
|
||||
specificity, and the later one wins — so the property was 1 on every phone on the site
|
||||
while the rule that was supposed to change it sat there reading perfectly.
|
||||
|
||||
Nothing in the suite could have caught it and nothing in review did. A stylesheet is not
|
||||
a list of rules for viewports; it is a list of rules in an order, and the question "what
|
||||
does a 390px phone get?" has an answer that no single rule knows. So the test walks the
|
||||
media queries the way the cascade does — every declaration of a property on a selector,
|
||||
in source order, keeping the last one whose query matches — and asks what each of five
|
||||
real phone sizes actually ends up with. It carries just enough of a media-query engine
|
||||
for the forms this stylesheet uses, and refuses loudly rather than guessing when it
|
||||
meets one it doesn't know.
|
||||
|
||||
The same file records a second thing, which is a floor that was added and removed. The
|
||||
`max-height` that keeps the felt above the action bar has no lower bound, so a tall
|
||||
enough bar presses the table flat; flooring it at the desktop oval looked obviously
|
||||
right. Measured, it was worse: twelve players all in with nine side pots takes the bar
|
||||
to 341px, which at 360x640 leaves 142px of room, and a felt floored to 242px keeps its
|
||||
shape by putting five of the twelve seats behind the bar. Unfloored it is flat and all
|
||||
twelve are visible. The slit the floor defended against turned out to be unreachable —
|
||||
it came from forcing the custom property by hand. A test now asserts the floor is
|
||||
*absent*, with the numbers, so it doesn't get re-added by someone reasoning the same way.
|
||||
|
||||
## Why the hand evaluator is tested the way it is
|
||||
|
||||
`handRank.js` is the only module here that can pay the wrong person without anybody
|
||||
|
||||
Reference in New Issue
Block a user