diff --git a/client/app.js b/client/app.js index 768386b..25fdc1b 100644 --- a/client/app.js +++ b/client/app.js @@ -840,6 +840,33 @@ class GolfGame { const previousPlayerId = oldState.current_player_id; const wasOtherPlayer = previousPlayerId && previousPlayerId !== this.playerId; + // Detect which pile opponent drew from and pulse it + if (wasOtherPlayer && discardChanged) { + const oldPlayer = oldState.players.find(p => p.id === previousPlayerId); + const newPlayer = newState.players.find(p => p.id === previousPlayerId); + + if (oldPlayer && newPlayer && oldDiscard) { + // Check if any of their cards now matches the old discard top + // This means they took from discard pile + let tookFromDiscard = false; + for (let i = 0; i < 6; i++) { + const newCard = newPlayer.cards[i]; + if (newCard?.face_up && + newCard.rank === oldDiscard.rank && + newCard.suit === oldDiscard.suit) { + tookFromDiscard = true; + break; + } + } + + // Pulse the appropriate pile + this.pulseDrawPile(tookFromDiscard ? 'discard' : 'deck'); + } else { + // No old discard or couldn't detect - assume deck + this.pulseDrawPile('deck'); + } + } + if (discardChanged && wasOtherPlayer) { // Check if the previous player actually SWAPPED (has a new face-up card) // vs just discarding the drawn card (no hand change) @@ -886,6 +913,17 @@ class GolfGame { // The swap animation handles showing the card at the correct position } + // Pulse animation on deck or discard pile to show where opponent drew from + pulseDrawPile(source) { + const pile = source === 'discard' ? this.discard : this.deck; + pile.classList.remove('draw-pulse'); + // Trigger reflow to restart animation + void pile.offsetWidth; + pile.classList.add('draw-pulse'); + // Remove class after animation completes + setTimeout(() => pile.classList.remove('draw-pulse'), 600); + } + // Fire animation for discard without swap (card goes deck -> discard) fireDiscardAnimation(discardCard) { const deckRect = this.deck.getBoundingClientRect(); @@ -1546,14 +1584,10 @@ class GolfGame { // Update player name in header (truncate if needed) const displayName = me.name.length > 12 ? me.name.substring(0, 11) + '…' : me.name; const checkmark = me.all_face_up ? ' ✓' : ''; - // Remove old crown if exists - const existingCrown = this.playerHeader.querySelector('.winner-crown'); - if (existingCrown) existingCrown.remove(); - // Set content - crown goes at the start - this.playerHeader.firstChild.textContent = displayName + checkmark; - if (isRoundWinner) { - this.playerHeader.insertAdjacentHTML('afterbegin', '👑'); - } + // Update player name span with crown if winner + const playerNameSpan = this.playerHeader.querySelector('.player-name'); + const crownHtml = isRoundWinner ? '👑' : ''; + playerNameSpan.innerHTML = crownHtml + displayName + checkmark; } // Update discard pile (skip if holding a drawn card) diff --git a/client/index.html b/client/index.html index 2e08275..20a6e04 100644 --- a/client/index.html +++ b/client/index.html @@ -11,7 +11,7 @@

🏌️ Golf

-

6-Card Golf Card Game

+

6-Card Golf Card Game

@@ -247,7 +247,7 @@
-

You0

+

You0

diff --git a/client/style.css b/client/style.css index 231fbbc..c771b78 100644 --- a/client/style.css +++ b/client/style.css @@ -985,6 +985,24 @@ input::placeholder { box-shadow: none; } +/* Pulse animation when opponent draws from a pile */ +#deck.draw-pulse, +#discard.draw-pulse { + animation: draw-pulse 0.6s ease-out; +} + +@keyframes draw-pulse { + 0% { + box-shadow: 0 0 0 0 rgba(244, 164, 96, 0.8); + } + 50% { + box-shadow: 0 0 0 12px rgba(244, 164, 96, 0.4); + } + 100% { + box-shadow: 0 0 0 20px rgba(244, 164, 96, 0); + } +} + /* Card flip animation for discard pile */ .card-flip-in { animation: cardFlipIn 0.5s ease-out; @@ -2555,19 +2573,25 @@ input::placeholder { color: rgba(255, 255, 255, 0.85); } -/* Rules link button in lobby */ -.btn-link { - background: transparent; - border: none; - color: #f4a460; - text-decoration: underline; +/* Rules button in lobby */ +.btn-rules { + background: rgba(244, 164, 96, 0.2); + border: 1px solid #f4a460; + color: #ffb366; cursor: pointer; - font-size: 0.95rem; - margin-bottom: 15px; + font-size: 0.65rem; + padding: 2px 8px; + margin-left: 8px; + vertical-align: middle; + border-radius: 3px; + font-weight: 600; + transition: background 0.2s, border-color 0.2s; } -.btn-link:hover { - color: #fbbf24; +.btn-rules:hover { + background: rgba(244, 164, 96, 0.35); + border-color: #ffb366; + color: #ffc880; } /* Select option styling in advanced options */ diff --git a/server/games.db b/server/games.db index 112acbb..b6df76a 100644 Binary files a/server/games.db and b/server/games.db differ