@page @model JoshHeaps.Net.Pages.Casino.TexasHoldemModel @{ ViewData["Title"] = "Texas Hold'em Dealer"; Layout = "_Layout"; }
@* Six equally-weighted buttons used to sit here in two rows, and on a 390px phone the felt did not start until 225px down — a quarter of the screen spent before the dealer saw the table. Only two of the six are per-hand controls. The rest have gone where they belong rather than into a "more" menu, which would have relocated the crowding rather than removed it: Reset Table down to the sidebar with the save/load pair — in a panel called Save & reset, so the danger is on the label rather than at the end of a scroll — Quick Split down with Common rulings where the other "open something else" link already lives, and the way back to the site up top where a back link goes. *@ @* The word is its own element so a phone can drop it and keep the arrow, and the aria-label is what a screen reader gets either way. It contains the visible text on the sizes that still show it, which is what WCAG 2.5.3 asks of a name that says more than the label does. *@
← Casino

Texas Hold'em Dealer

@* Not the accent any more. It is a shortcut to a sheet, available all night, and it is never the next step — the bar always has that, and at showdown the bar says so in as many words. See .actionAdvance in holdem.css. *@
@* The seat sheet was the only one of the tool's seven overlays with nothing behind it. On a phone it covers the felt from 250px down and the action bar with it, so it is modal in everything but appearance — and what stayed lit above it was the header, with Misdeal, Next Hand and Resolve Pot live under a thumb that was reaching for a name field. NN/g and Material both say the same thing about this: a modal sheet with an invisible scrim tells the user they can still touch what they can still see, and they can't. Not an `*Overlay` id, deliberately — Modal watches those and would take the sidebar panel this becomes on a desktop for a dialog. It is driven entirely by body.seatSheetOpen, and it is `display: none` above 700px where the panel is just a panel. *@
Pot $0

Quick Split

@* Four things stacked flat used to be five: name, in/out, two hole-card slots, stack, a five-box chip counter and a list of custom fields, every one of them at the same weight, all of it open at once. Measured on a 390px phone the sheet came to 594px, and the three controls a dealer touches on nearly every visit — the name, the two status boxes, the stack — were 132px of it. The chip counter alone was 174px, the tallest thing in the sheet, for a job most tables do once a night if at all; the two card slots were 62px of dashed grey on every table that never asked to be shown a card. So the flat list is now three rows and three disclosures, and which of the three stand open is a question about *this seat*, answered in renderSeatDisclosures: a seat holding cards opens its cards, a seat with chips counted opens its count, a seat with notes on it opens its notes. Anything with nothing in it stays a one-line summary that says so. Nothing was removed and nothing moved to another screen. *@ @* The value used to be a `title` attribute, which is a tooltip — and a tooltip is nothing at all on the device this is used on. Five coloured dots with five number boxes and no way to tell which one was the $25 without opening the Chip Legend and matching colours by eye. It is text now. *@ @* No aria-live here any more. This element's entire contents are rebuilt on every action, so a live region on it announced the whole bar every time — measured, after one tap: "PRE-FLOP Pot $15 9 players Bob · $250 behind 0:00 ↶ dealing the hand U Fold Call $10 Raise". That is what a screen reader read out after every single fold. A live region has to be a stable element whose *text* changes; the one below is. *@ @* Whose turn it is, in a sentence. Empty in the markup and only ever written to, so assistive tech is already watching it when the first update lands — a live region created at the moment it has something to say is one the screen reader misses. *@
@section Styles { @* Installable, and works with no signal — see the service worker registration at the foot of main.js. A dealer running a night in somebody's back room is on the worst network there is, and the tool being a *website* was the last thing that could take it away from them mid-game. *@ @* iOS reads none of the manifest's icons and only this. *@ @* The standard name first, then Apple's older one. Chrome has been printing " is deprecated" into this page's console on every load; the replacement is the unprefixed name, and Safari still wants the prefixed one, so both are here. *@ @* Paints the phone's chrome the same near-black as the felt's ground, so an installed copy doesn't sit under a white status bar. *@ } @* A note for whoever reads the ?v= below and assumes it works: it doesn't. ViewData ["cssVersion"] is assigned in _Layout's own code block, which runs after these sections are handed their values, so every one of these renders as a bare "?v=" — on this page and on Chess, Particles and Memory Lane too. It is inert rather than broken: Program.cs sends `Cache-Control: no-store` on every static file, so nothing is being browser-cached for a version string to bust in the first place. Left alone deliberately. Fixing it is a one-line change to a file every page on the site shares, and the service worker was the reason to care — that now uses stale- while-revalidate, which needs no version to stay current. *@ @section Scripts { @* After feedback.js, because the first lock it takes announces itself with a Toast. *@ }