Hold'em dealer: blind fix, design tokens, and the decrowd #116
Merged
jheaps
merged 3 commits from 2026-09-03 10:26:51 -06:00
fix/naming-a-blind-deals-the-hand into master
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2e9c55af21 |
Give the felt back the screen the chrome was using
Measured on a 390x844 phone, six-handed, same table before and after:
before after
header 193px 120px
felt starts at 225px 152px
controls on screen 27 18
bordered elements 37 22
text elements 61 49
A quarter of the screen went on chrome before the dealer saw the table.
**The header.** Six equally weighted buttons in two rows, of which two are
per-hand controls. The other four have gone where they belong rather than into
a "more" menu — that relocates crowding instead of removing it. Reset Table is
in the Session panel now, beside Clear history and the save/load pair: it is
the control that throws the night away and it was sitting in the same weight as
Resolve Pot, the most-pressed button in a session. Quick Split is down with
Common rulings, where the other "open something else" link already lived. The
way back to the site is a quiet link at the top, where a back link goes.
The subtitle is gone. It was one sentence of orientation on a tool used
nightly, and the landscape and short-phone rules already hid it — the layout
had decided it was expendable on every screen this is actually used on.
**Teaching copy, once.** Table Setup shipped open, so the first screen was the
most crowded one; it now opens only on a table nobody has set up yet, decided
once at load so it cannot reopen itself under a dealer who just shut it. The
gesture hint under the felt goes after the first deal of the session — keyed to
the hand number, not to bettingOpen, which was the obvious test and the wrong
one: it would have appeared and disappeared twice a hand, shunting the panel
stack up and down all night.
**Borders.** Panels had a border, a lighter background and a shadow — three
ways of drawing one edge. The standings had a rule under every row, which is
what makes a list read as ruled paper. Both drop the line and keep the
grouping; the standings header keeps its rule, because that one marks a change
of kind. Fields and buttons keep theirs: those say "interactive", which is not
decoration.
**The felt itself.** Names wrap to two lines instead of ellipsising, so
"Christopher" and "Mike from work" are readable rather than "Chri..." and "Mike
fro..." — the truncation was eating exactly the half a dealer typed to tell two
Mikes apart. And a stack of $1,234,567 rendered at 7px; it now drops the
thousands separators before it drops the type size, so the same number is eight
characters at 10px with every digit intact. The comment above fitAmount was
right that abbreviating loses precision — but precision the dealer cannot read
is not precision.
Two things tried and reverted, both measured:
* Reserving the second name line made every puck the height of the tallest
(69-73px became a uniform 88). Fifteen pixels on all nine seats is felt
spent on chrome, which is what this round is trying to give back.
* Dropping the name a type step to fit more on one line still did not fit
"Christopher" on the button seat, where the dealer chip takes 22px of the
row — so it cost legibility and bought nothing.
Known limit: a single word too long for a puck breaks across the two lines, and
gets a hyphen only where the browser has hyphenation dictionaries. Real phones
do; headless Chromium does not, so audit screenshots show "Christo / pher". The
whole name is visible either way, which it was not before.
599 tests, 0 failures. 52 layout audits across 13 viewports x 4 table sizes
(2, 6, 9, 12 seats) and 20 across the five overlays: 0 failures, and the action
bar still does not change height mid-hand at any of them. The back link was
caught by the audit at 56x13 when it stopped being a button; its hit area is
44px now, paid for with negative margins so the header keeps the 73px.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
|
||
|
|
8b43614b1c |
Give the stylesheet a vocabulary, and stop the bar moving
The tool read as crowded on screens where nothing overlapped, and the reason turned out to be arithmetic rather than taste: holdem.css used 42 different spacing values, 31 font sizes, 14 border-radii and 139 colours, and defined three custom properties. Every number had been picked by hand at the moment it was needed. A 0.42rem gap beside a 0.45rem gap beside a 0.5rem gap gives the eye no rhythm to lock onto, so it reads the whole surface as noise. So: constrained scales, and everything snapped to them. Seven spacing steps on an 8px rhythm, eight type sizes, four corners, and a four-step surface ramp that stays off pure black — shadows are invisible on #000 and white-on-black smears on the OLED phone this is used on. 661 values rewritten; colour mentions halved, 381 to 174. Nothing here changes what the tool does. Two things were measurably moving under the dealer's thumb, and both are fixed by reserving space rather than by animating anything: * The undo pill named the last action, so it resized on every single tap. Measured across one hand: 148, 110, 109, 108, 109, 110, 120px. It is now a fixed 10rem, with the label in its own element so it can ellipsize without truncating through the keycap beside it. * The action bar is fixed to the bottom, so anything that changes its height moves its top edge. The status row wraps, and it wrapped differently as the street and pot changed. It now holds two lines' worth of room whenever a hand is running. Across 13 viewports x 3 table sizes, the bar no longer changes height mid-hand at all. Numbers that change while the dealer watches — pot, stacks, bets, standings — are now set in tabular figures, so a pot ticking $18 to $21 stops shuffling its digits sideways. Two regressions the sweeps caught on the way, both from the snapping: * The Add Chips field cleared 44px by way of its font size plus its padding, so moving either dropped it to 42. It states its own min-height now; a touch target shouldn't be an accident of two other numbers. * The bar came out 2px shorter in landscape, which grew the felt, which lifted the top seat's dealer button 2px into the header. That clearance was structurally 1-7px, so the top seat inset became a floor rather than a ceiling instead of chasing the 2px. tests/holdem/designTokens.test.js keeps the scales honest — a new value has to be a step or an exception with a reason. Fault-injected four ways. 599 tests, 0 failures. 39 layout audits across 13 viewports and 3 table sizes, plus 35 across the five overlays: 0 failures. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb |
||
|
|
42b9e83e8f |
Don't deal the hand when the dealer names a blind
The seat menu's "Make small blind" / "Make big blind" / "Blinds follow the button again" all re-posted the blinds whenever `Betting.onlyBlindsIn(state)` was true. That condition means "nothing has happened in this hand except the blinds" — which is true of a hand one second old and equally true of a table sitting in setup with no cards out and nothing committed. So naming a blind before the deal ran repostBlinds -> beginHand: betting opened, two stacks docked, the action bar up and waiting on the seat after the big blind. The dealer had said where the blinds go and the tool heard "deal". Betting.blindsArePosted() is the question these three actually wanted — the blinds are down only once a hand is open — and it's the guard makeDealer was already using by hand. Before the deal, naming a blind now moves a badge and nothing else; the toast says "Dee has the small blind next hand." rather than claiming she posted it. Mid-hand behaviour is unchanged: chips come back and go in again from the new positions, and the chip count stays straight. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb |