Let overlay card start at deck size and smoothly scale down to opponent
card size during the arc, instead of instantly shrinking before animating.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parent #game-screen has align-items: center which shrink-wraps flex
children. Adding align-self: stretch makes the bottom bar span the
full screen width so space-between can distribute items properly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all flush-edge styling (negative margins, half-pills, border
removal). Restore original padding, justify-content, and pill shapes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zero padding was breaking game layout. Keep 12px padding for layout
stability and use margin-left: -12px / margin-right: -12px on the
edge items to push them flush against screen edges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zero horizontal padding on bottom bar, remove border on flush side,
use half-rounded pill shape so they sit against the screen edges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts flush-edge pill styling and restores horizontal padding to prevent
clipping. Rules drawer is now a sibling of bottom-bar, not inside game-layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows "S" (standard) or "!" (house rules) in the mobile bottom bar.
Tapping opens a drawer with the full active rules list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
markKnocker() was called before opponent areas were rebuilt by
innerHTML='', so the is-knocker class and OUT badge were immediately
destroyed. Move markKnocker to after opponent areas are created.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Makes the red border on the knocker's area more visible, especially
for opponents on mobile where the area is small.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Final results modal: keep BY POINTS and BY HOLES side-by-side on
mobile, compact spacing, buttons side-by-side, bottom padding for
mobile bar overlay.
Turn shake: delay 5s before first shake, 300ms every 2s.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Less aggressive draw hint: waits 5 seconds before first shake,
then shakes for 300ms every 2 seconds with slightly less movement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Position the button centered beneath the held card instead of to the
right side. Reset writing-mode to horizontal and add width:auto.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduce overlap offset from 1.15 to 0.65 so the held card sits at the
DRAW/DISCARD label level rather than up in the opponents area.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Position the held card a full card height above the deck (1.15x offset)
so it sits in the space between opponents and the draw/discard piles.
All three position calculations (app.js x2, card-animations.js) are
synced so draw animations land at the correct held position.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap each pile in a .pile-wrapper with a small label above it.
Fix direct child selectors that broke with the new wrapper nesting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Increase top padding from 5px to 20px so the deck/discard sit lower,
giving the held card more breathing room from the opponents row above.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update getHoldingRect() in card-animations.js and the second held card
positioning path in app.js to use the same reduced overlap offset on
mobile portrait. All three places that compute the held position now
use 0.15 on mobile-portrait vs 0.35 on desktop/landscape.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduce held card overlap offset from 0.35 to 0.15 on mobile portrait
so it doesn't cover the second row of opponents. Increase bottom
padding on opponents row from 6px to 12px for more breathing room.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The status was set without a type class in renderGame(), overriding
the styled version from updateStatusFromGameState() on every state
update. Now the purple background shows consistently for opponent turns.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove margin-top from base rules/leaderboard/matchmaking styles so
desktop and landscape layouts are unaffected. The 50px top margin is
now only applied via the mobile-portrait override.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>