feature/casino-holdem-touch-mobile
Four measured problems, all of which only show up under a thumb. Every tap waited on the browser (53 of 53 controls) Not one interactive element set `touch-action`, so a mobile browser held every tap for ~300ms to see whether a second one was coming that would mean "zoom in". That is on the fold button, the call button, every seat, every card slot. Worse, this tool uses double-tap on a seat as the fold shortcut — which *is* the browser's zoom gesture. The dealer's fastest shortcut was fighting the page zooming under their thumb. A single seat tap cost ~300ms of browser hesitation before the app's own 220ms double-tap window even started. `touch-action: manipulation` everywhere keeps panning and pinch-zoom and drops only double-tap-to-zoom, which is precisely the one that was in the way. Press feedback was the OS grey box (1 `:active` rule in 2385 lines) Only `.actionBtn` had a pressed state. Everything else — seats, header buttons, card slots, picker cards, menu rows, toasts, wizard choices — relied on the translucent grey rectangle the browser paints on tap. So the tap highlight couldn't just be switched off; the controls needed real pressed states first. They press down 1px and brighten, in 0.04s, matching the action bar that already did. Then the grey box goes. Hover stuck after every tap (21 unguarded rules) `:hover` has no meaning on touch, but it still applies — and stays applied until you tap elsewhere. Tapping "Next hand" left it lifted and lightened as though still under a cursor, and it would have fought the new pressed states directly. All of them are behind `@media (hover: hover)` now. The one rule that shared a block with `:focus-visible` was split so keyboard focus survives. The notes field zoomed the page (iOS) `#tableNotes` was 13.3px. iOS zooms the viewport when a field under 16px takes focus, and the dealer is then pinching back out to see the table. Every other input here was already 16px; this was the straggler. Seats deliberately have no `:active` rule Worth writing down because it nearly went in. A seat's `transform` is what positions it around the felt, so a pressed state setting `transform` drops the `translate(-50%, -50%)` and throws every pressed seat ~38px off its spot. Validation caught it: seats already dip via `.seatPressing`, which `pointerdown` adds in render.js — earlier than `:active` resolves, and it restates the translate correctly. Validated with Playwright at 390x844: 53/53 controls off `touch-action: auto` and 0 tap-highlighted across the table, all four overlays and Quick Split; text fields still selectable and buttons not; 14/14 hover rules gated; presses measured live via mouse-down (fold reads translateY(1px)/brightness(1.3), a seat holds its translate with 2px of drift from the shrink alone). Hand played through the UI including a double-tap fold. No console errors. Unit tests 58/58. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
Description
No description provided
142 MiB
Languages
JavaScript
68.4%
CSS
14.1%
C#
8%
HTML
4.5%
C++
4.4%
Other
0.5%