Override width:100% from .btn base class with width:auto on both
back buttons. Add padding-bottom and border-bottom to leaderboard
header to match rules page styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Position the button absolutely on the left side of the header,
vertically centered with the title. Remove mobile fixed-position
override that placed it in the top bar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents auth bar from overlapping back buttons. Back buttons
align to start instead of stretching full width.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CPU turn chain was awaited inline inside game_lock, blocking the
WebSocket message loop. The end_game message couldn't be processed
until all CPU turns finished. Now check_and_run_cpu_turn launches a
background task and returns immediately, keeping the message loop
responsive. The end_game and leave handlers cancel the task on demand.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert CPU turn chain to a cancellable asyncio.Task tracked on Room,
so ending the game or leaving no longer blocks waiting for CPU sleeps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove game-screen padding and replace solid dark header background
with subtle dark-to-transparent gradient matching mobile treatment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The desktop #game-screen.active had padding:10px that was never
overridden in the mobile portrait styles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces background:none with a dark-to-transparent gradient so the
status message and mute button are visible against the green felt.
Reverts mute button circle in favor of the gradient approach.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The desktop game-header background was still showing on mobile,
creating a visible dark band with padding around the status bar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove left/right/top padding from notification bar so it spans edge
to edge, and increase bottom margin from 4px to 8px for more breathing
room before the opponents row.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace margin:auto on table-center with space-evenly on player-row
so the draw pile and player cards are equally spaced vertically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Increase horizontal padding on game-table (4px to 10px) and header
(8px to 12px) to prevent edge clipping. Change opponents-row overflow
to visible so dealer chips aren't cut off.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The swap animation defers state updates to pendingGameState, which
bypassed checkForNewPairs entirely. Now pair detection runs when the
deferred state is applied after the swap animation completes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sound was gated behind element check which may fail during swap
animation when card DOM elements are replaced by overlays.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bottom bar is hidden when the hole results modal opens and restored
when dismissed. Also adds mobile-specific compact styles for the
scoresheet: smaller cards, tighter spacing, reduced padding.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
firePairCelebration was only doing the visual animation but not playing
the pair sound. The sound was only played during score tallying.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Traefik gets a separate cert for www subdomain and uses
redirectregex middleware to 301 redirect to bare domain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove position:fixed from the bottom bar and make it a flex-shrink:0
child of the game screen flex column. This guarantees the game layout
gets exactly the remaining viewport height with no overlap, regardless
of how the browser calculates viewport units.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set --app-height CSS custom property from window.innerHeight via JS,
which is the only reliable way to get the actual visible viewport on
Chrome Android. Falls back to 100vh if JS hasn't loaded.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use position:fixed with inset:0 for the game screen instead of
height-based sizing. This bypasses the Chrome Android 100vh bug where
vh includes space behind the dynamic URL bar. Also adds
-webkit-fill-available fallback on body.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 100vh fallback before 100dvh, max-height constraints on every flex
container in the layout chain, and explicit flex-basis 0% to prevent
Chrome from letting flex children grow beyond viewport bounds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces fixed 120px width with calc((100% - 20px) / 3) so 3 opponents
always fit per row regardless of viewport width.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Also fix opponent areas shifting between rows on mobile by giving them
a fixed 120px width so name/score changes don't cause reflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduces from 38px to 22px and pulls offset from -10px to -4px so it
no longer overlaps the bottom bar buttons.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add bottom padding to game-table to reserve space for the fixed bottom
bar, and overflow:hidden on player-row so content respects flex bounds.
Also centers draw pile with equal spacing and adds dealer chip clearance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove transform: scale(0.75) from the bar container which broke the
full-width layout and margin-auto pinning. Instead shrink font sizes
and padding on individual buttons and round info by ~25%.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bumps z-index from 500 to 900 so the bottom bar stays above side panel
drawers (600) but below card animation overlays (1000). Scales the bar
to 75% in mobile portrait to reduce visual footprint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduces card sizes from 72×101 to 64×90 on mobile portrait to prevent
overlap with bottom bar when opponents wrap to 2 rows. Increases
horizontal gap between opponent hands from 4px to 10px for better
readability of player chips.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace onclick attributes with data-action/data-id attributes and
use event delegation. CSP script-src 'self' blocks inline handlers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin panel gets "Copy Link" button on active invites that copies
a signup URL with ?invite= param. Client auto-opens signup form
with invite code pre-filled when visiting that link.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Forgot password form in auth modal with email input
- Reset password form handles token from email link
- /reset-password route serves index.html for SPA
- EMAIL_FROM env var in docker-compose
- Success/error feedback for both flows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Hole indicator: margin-right auto, pill background, brighter text (0.9 opacity)
- End Game: margin-left auto, pinned to right edge
- Standings/Scores stay centered between them
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add round info and leave button to mobile-bottom-bar HTML
- Hide .round-info and #leave-game-btn from header on mobile
- Style round info as subtle text, leave button as red-tinted pill
- Slim down bottom bar: smaller gaps/padding to fit 4 items
- Sync round numbers and leave text via JS (renderGame + bindEvents)
- Frees up header space, reduces mobile crowding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove excessive 44px bottom padding on game-table (was eating vertical space)
- Tighten opponents-row: reduce gap 6px->4px, side padding 8px->4px
- Reduce opponent-area side padding 5px->4px
- Allow opponent areas to shrink (remove flex-shrink: 0)
- 3 opponents now fit in ~367px, well within 412px Pixel 10 Pro
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Position fixed bottom:0 so buttons are always at the very bottom
- Remove dark background that was picking up the green felt color
- Add bottom padding to game-table so player cards aren't hidden behind bar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>