Cut lastPlayPause to 2s and increase shake interval by 80% (3s→5.4s)
so the draw/discard nudge feels less nagging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Increase post_draw_settle timing (1.1s→1.3s) and swap retry delay
(100ms→350ms) to prevent draw animation from being cut short by the
arriving swap animation. Also make CPU go-out decisions consider
opponent scores and avoid swapping high cards (8+) into hidden slots.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tighten padding, gaps, card sizes, and margins across all scoresheet
elements so the full modal fits without scrolling on most viewports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two issues fixed:
1. renderGame() was called before the lastPlayPause delay, causing the
board to jump to final card positions while the swap animation was
still visually playing. Moved renderGame() to after the wait+pause.
2. When the local player makes the final play, their swap animation
defers the round_over game_state to pendingGameState. The deferred
state bypassed the round-end intercept, so preRevealState was never
set — causing the scoresheet to appear immediately without the
reveal animation. Now completeSwapAnimation checks for round_over
transitions and sets preRevealState. Also added a wait loop in
runRoundEndReveal for robustness.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Force discard pile DOM update before draw animation starts to prevent
stale card display when previous swap animation blocked renderGame.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move CPU +/- buttons inline into Players header row with "CPU:" label
- Tighten vertical spacing for mobile stacked layout (≤700px)
- Fit Decks/Holes/Card Backs settings in single row on mobile
- Reduce room code banner and auth bar edge margins
- Consistent spacing across all stacked viewport widths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Style the flip overlay's front face to match player hand cards (gradient
background, proper border/shadow) instead of using generic card-front
styles. Hide the underlying card during the animation so the green table
shows through the flip rather than a white card peeking behind it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The turn pulse shake was targeting .discard-stack, which is an ancestor of
#held-card-floating. A CSS transform on any ancestor breaks position:fixed,
causing the held card to render far from the deck area. Now target #discard
directly instead.
Also fix duplicate getCardPointValue methods — the 3-arg scoring version
shadowed the 1-arg tooltip version, leaving cardValues undefined on hover.
Add staging deploy script (rsync working tree, no git pull needed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix dumb AI knocks (e.g. Maya knocking on 13 points) by adding opponent
threat checks and a hard cap of 10 to should_knock_early(). Remove dead
should_go_out_early() call whose return value was never used. Retune knock
chance tiers to be more conservative at higher projected scores.
On the client side, fix round-end reveal sequencing so the last player's
swap/discard animation plays before the reveal sequence starts, and prevent
re-renders from clobbering swap animations during reveals. Also make the
turn-pulse shake configurable via timing-config and target only cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Default gradient on base .status-message (dark green)
- Add round-over/game-over (gold) and reveal (purple) gradient styles
- Tag action prompts (swap, flip, discard) as your-turn type
- Match final-turn badge font size and padding to status message on mobile
- Hide status message when empty
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align header-col-center to flex-start on mobile so the status and
final-turn badges sit flush left. Match final-turn-badge border-radius
and padding to status-message for consistent shape.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mute button in header-right throws off visual centering of the status
text. Left-aligning looks intentional rather than off-center.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
overflow:hidden on body.mobile-portrait was blocking scroll on all
screens. Scope it to only when the game screen is active using :has().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
game_ended, queue_left, and cancelMatchmaking were calling
showScreen('lobby') directly, bypassing the cancelAll() cleanup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Tag deal container with class so cleanup() can find and remove it
- Remove .traveling-card and .deal-anim-container overlays in cleanup()
- Restore opacity/visibility on cards hidden mid-animation
- Reset all animation flags (dealAnimationInProgress, etc.) in showLobby()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>