- Shipped
- September 8, 2026 at 7:13 AM UTC
- Author
- Kamo
- Commit
- 7be21a3
Two genuinely different layouts, a lobby, an invite path that reaches anyone in the organization, and the wallet readout that appears whenever Games does. ## The two layouts are two designs, not one design resized Chosen by the window's SHAPE — read from the real viewport when maximized, because `width` is the STORED size and a maximized window still reports it, so a width breakpoint is silently false for a maximized window docked at 460. compact a rail seat: a scannable strip of opponents, the board at full size, and YOUR two cards large at the bottom where your hands would be felt the table: ten seats on an ellipse, rotated so the reader is always at the bottom, with the hand history and empty-seat invites beside it At 460px an ellipse of ten seats is ten unreadable specks, so the compact layout is the right design for that shape rather than a fallback. ## The design A late-night private card room, not a casino floor: bottle-green cloth, oxblood, brass, and one warm lamp over the centre with the board and pot inside it. The lamp BRIGHTENS while somebody is all-in — the only ambient state change on the table, and the whole of the boldness budget spent in one place. NOTHING on the felt is brand-derived, and that is a rule. Chess derived both the square and the piece from `--color-primary` and produced, on a mid-grey brand, a black piece measurably the colour of the square under it. The felt has more exposure, not less. The brand appears only in chrome, where a card never sits beside it. The 52 faces are generated from a rank/suit spec rather than drawn, so the same component is the 38px card at a seat and the 70px card in your hand — and the pip LAYOUTS are the standard ones, because a player reads a seven by its shape long before they read the corner index. ## The browser owns no poker Every frame carries `you.legalActions` with exact minimum and maximum amounts, the way chess carries `legalMoves`. The action bar cannot disagree with the server about a minimum raise because it was never asked. Amounts are TOTALS for the street — an increment has to be interpreted against a bet that may have moved between the frame being drawn and the click landing. Hole cards a member is not entitled to never enter a frame addressed to them, so there is no client flag that could reveal one. ## The wallet A 🧀 chip in the fixed right-hand chrome, drawn on exactly the condition `useGamesSections()` draws the Games menu on — one source, so the two cannot drift. Click opens a statement covering the WHOLE wallet: land purchases and claw plays alongside buy-ins, because it is one wallet. It ticks live during play with no request of its own: every Hold'em frame carries the reader's balance, dispatched across the tool-dock boundary as an event. An unreachable wallet renders as an em dash and never as zero — zero is a fact about somebody's money and null is a fact about the network. ## Also * `gameCatalogue` grew from an exact `participants` count to a RANGE, so a group chat now offers something where it used to offer nothing. * KAMO_UNIVERSE and CHESS had no `appServiceIcons` entry either, so all three Games children drew the anonymous app-grid square on the Features screen. Fixed with them. * The compact rail asks for no scrollbar of its own — `data-kamo-scrollbar="off"` is the app's one vocabulary for that, and styling a bar here would make it the app's second.