Fix held card displacement in landscape and tooltip crash

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>
This commit is contained in:
adlee-was-taken 2026-02-23 19:16:20 -05:00
parent 8d5b2ee655
commit e2c7a55dac
3 changed files with 29 additions and 5 deletions

View File

@ -379,7 +379,7 @@ class GolfGame {
// Only show tooltips on your turn // Only show tooltips on your turn
if (!this.isMyTurn() && !this.gameState?.waiting_for_initial_flip) return; if (!this.isMyTurn() && !this.gameState?.waiting_for_initial_flip) return;
const value = this.getCardPointValue(cardData); const value = this.getCardPointValueForTooltip(cardData);
const special = this.getCardSpecialNote(cardData); const special = this.getCardSpecialNote(cardData);
let content = `<span class="tooltip-value ${value < 0 ? 'negative' : ''}">${value} pts</span>`; let content = `<span class="tooltip-value ${value < 0 ? 'negative' : ''}">${value} pts</span>`;
@ -409,14 +409,15 @@ class GolfGame {
if (this.tooltip) this.tooltip.classList.add('hidden'); if (this.tooltip) this.tooltip.classList.add('hidden');
} }
getCardPointValue(cardData) { getCardPointValueForTooltip(cardData) {
const values = this.gameState?.card_values || this.getDefaultCardValues(); const values = this.gameState?.card_values || this.getDefaultCardValues();
return values[cardData.rank] ?? 0; const rules = this.gameState?.scoring_rules || {};
return this.getCardPointValue(cardData, values, rules);
} }
getCardSpecialNote(cardData) { getCardSpecialNote(cardData) {
const rank = cardData.rank; const rank = cardData.rank;
const value = this.getCardPointValue(cardData); const value = this.getCardPointValueForTooltip(cardData);
if (value < 0) return 'Negative - keep it!'; if (value < 0) return 'Negative - keep it!';
if (rank === 'K' && value === 0) return 'Safe card'; if (rank === 'K' && value === 0) return 'Safe card';
if (rank === 'K' && value === -2) return 'Super King!'; if (rank === 'K' && value === -2) return 'Super King!';

View File

@ -765,7 +765,7 @@ class CardAnimations {
// Quick shake animation - target cards only, not labels // Quick shake animation - target cards only, not labels
const T = window.TIMING?.turnPulse || {}; const T = window.TIMING?.turnPulse || {};
const cards = element.querySelectorAll(':scope > .pile-wrapper > .card, :scope > .pile-wrapper > .discard-stack'); const cards = element.querySelectorAll(':scope > .pile-wrapper > .card, :scope > .pile-wrapper > .discard-stack > #discard');
const doShake = () => { const doShake = () => {
if (!this.activeAnimations.has(id)) return; if (!this.activeAnimations.has(id)) return;

23
scripts/deploy-staging.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
set -e
DROPLET="root@129.212.150.189"
REMOTE_DIR="/opt/golfgame"
echo "Syncing to staging ($DROPLET)..."
rsync -az --delete \
--exclude='.git' \
--exclude='__pycache__' \
--exclude='node_modules' \
--exclude='.env' \
--exclude='internal/' \
server/ "$DROPLET:$REMOTE_DIR/server/"
rsync -az --delete \
--exclude='.git' \
--exclude='__pycache__' \
--exclude='node_modules' \
client/ "$DROPLET:$REMOTE_DIR/client/"
echo "Rebuilding app container..."
ssh $DROPLET "cd $REMOTE_DIR && docker compose -f docker-compose.staging.yml up -d --build app"
echo "Staging deploy complete."