diff --git a/public/frontend_poker.js b/public/frontend_poker.js index 46989a6..b4a867a 100644 --- a/public/frontend_poker.js +++ b/public/frontend_poker.js @@ -11,6 +11,9 @@ document.addEventListener("DOMContentLoaded", () => { const yourStack = document.getElementById("your-stack"); const currentTurn = document.getElementById("current-turn"); const turnState = document.getElementById("turn-state"); + const turnCountdown = document.getElementById("turn-countdown"); + const turnProgressBar = document.getElementById("turn-progress-bar"); + const turnAnnouncement = document.getElementById("turn-announcement"); const turnQueue = document.getElementById("turn-queue"); const lastAction = document.getElementById("last-action"); const showdownPanel = document.getElementById("showdown-panel"); @@ -89,8 +92,9 @@ document.addEventListener("DOMContentLoaded", () => { turnQueue.innerHTML = ""; queue.forEach((player, index) => { const item = document.createElement("li"); - item.textContent = index === 0 ? `${player} (now)` : player; + item.textContent = index === 0 ? `${player} · NOW` : index === 1 ? `${player} · NEXT` : player; item.classList.toggle("active", player === currentPlayer); + item.classList.toggle("next", index === 1); turnQueue.appendChild(item); }); }; @@ -157,12 +161,25 @@ document.addEventListener("DOMContentLoaded", () => { } }; + const setTurnTimer = (seconds, totalSeconds) => { + turnCountdown.textContent = String(seconds); + turnProgressBar.style.width = `${Math.max(0, Math.min(100, (seconds / Math.max(1, totalSeconds)) * 100))}%`; + document.querySelector(".turn-panel").classList.toggle("urgent", seconds <= 10 && seconds > 0); + }; + + const announceTurn = (message) => { + if (turnAnnouncement.textContent !== message) turnAnnouncement.textContent = message; + }; + const renderIntermissionCountdown = (startsAt, baseMessage) => { stopCountdown(); + const totalSeconds = Math.max(1, Math.ceil((Number(startsAt) - Date.now()) / 1000)); const updateCountdown = () => { const seconds = Math.max(0, Math.ceil((Number(startsAt) - Date.now()) / 1000)); - currentTurn.textContent = `${seconds}s`; - turnState.textContent = "Waiting for next round"; + currentTurn.textContent = "NEXT HAND"; + turnState.textContent = "TABLE RESET IN PROGRESS"; + setTurnTimer(seconds, totalSeconds); + announceTurn("The next hand is about to start."); lastAction.textContent = baseMessage || `Next round starts in ${seconds}s. Minimum stake: $${minimumStake}.`; if (seconds <= 0) { stopCountdown(); @@ -174,12 +191,15 @@ document.addEventListener("DOMContentLoaded", () => { const renderTurnCountdown = (startsAt, currentPlayer) => { stopCountdown(); + const totalSeconds = Math.max(1, Math.ceil((Number(startsAt) - Date.now()) / 1000)); const updateCountdown = () => { const seconds = Math.max(0, Math.ceil((Number(startsAt) - Date.now()) / 1000)); - currentTurn.textContent = `${currentPlayer || "Player"} (${seconds}s)`; + currentTurn.textContent = isYourTurn ? "YOUR TURN" : currentPlayer || "PLAYER TURN"; turnState.textContent = isYourTurn - ? `Your decision (${seconds}s)` - : `Waiting for other player (${seconds}s)`; + ? "ACT NOW — CHOOSE AN ACTION" + : `WAITING FOR ${currentPlayer || "PLAYER"}`; + setTurnTimer(seconds, totalSeconds); + announceTurn(isYourTurn ? "It is your turn. Choose an action before the timer expires." : `It is ${currentPlayer || "another player's"} turn.`); if (seconds <= 0) { stopCountdown(); } @@ -221,6 +241,9 @@ document.addEventListener("DOMContentLoaded", () => { } else { stopCountdown(); currentTurn.textContent = message.currentPlayer || "Round ended"; + turnCountdown.textContent = "--"; + turnProgressBar.style.width = "0%"; + document.querySelector(".turn-panel").classList.remove("urgent"); turnState.textContent = isSpectator ? "Spectating" : isYourTurn diff --git a/public/poker.html b/public/poker.html index 7c57267..802feec 100644 --- a/public/poker.html +++ b/public/poker.html @@ -25,8 +25,14 @@
- Turn: Waiting... - Waiting for table state + Waiting for table state + Waiting... +
+ -- + seconds remaining +
+ +
    diff --git a/public/styles_poker.css b/public/styles_poker.css index 41ff2d5..2b2471a 100644 --- a/public/styles_poker.css +++ b/public/styles_poker.css @@ -112,9 +112,9 @@ button:disabled:hover { } .turn-panel { - display: flex; - flex-wrap: wrap; - gap: 18px; + display: grid; + grid-template-columns: auto auto; + column-gap: 20px; align-items: center; justify-content: center; min-width: min(460px, calc(100vw - 32px)); @@ -122,10 +122,21 @@ button:disabled:hover { background: rgba(0, 0, 0, 0.78); box-shadow: 0 0 8px #0f0; color: #fff; - padding: 10px 16px; + padding: 14px 18px; font-family: monospace; } +.turn-kicker { grid-column: 1; color: #a8d8aa; font-size: 12px; letter-spacing: .08em; } +.turn-player { grid-column: 1; color: #fff; font-size: 24px; line-height: 1; text-shadow: 0 0 8px #0f0; } +.turn-timer { grid-column: 2; grid-row: 1 / span 2; display: grid; justify-items: center; min-width: 92px; border-left: 1px solid rgba(0, 255, 0, .45); padding-left: 18px; } +.turn-countdown { color: #0f0; font-size: 38px; font-weight: 800; line-height: 1; text-shadow: 0 0 12px #0f0; } +.turn-seconds { color: #d8ffd8; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; } +.turn-progress { grid-column: 1 / -1; height: 5px; background: #153019; overflow: hidden; } +.turn-progress span { display: block; width: 0; height: 100%; background: #0f0; box-shadow: 0 0 10px #0f0; transition: width .25s linear, background .2s; } +.turn-panel.urgent { border-color: #ff394d; box-shadow: 0 0 14px #ff394d; } +.turn-panel.urgent .turn-countdown { color: #ff5263; text-shadow: 0 0 14px #ff394d; } +.turn-panel.urgent .turn-progress span { background: #ff394d; box-shadow: 0 0 10px #ff394d; } + .turn-queue { display: flex; flex-wrap: wrap; @@ -150,6 +161,8 @@ button:disabled:hover { color: #000; } +.turn-queue li.next { border-color: #a8d8aa; color: #d8ffd8; } + .card { width: 78px; height: 116px; @@ -371,6 +384,10 @@ button:disabled:hover { padding: 12px 16px; } + .turn-panel { grid-template-columns: 1fr; justify-items: center; text-align: center; } + .turn-kicker, .turn-player { grid-column: 1; } + .turn-timer { grid-column: 1; grid-row: auto; border-left: 0; border-top: 1px solid rgba(0, 255, 0, .45); padding: 10px 0 0; } + .card { width: 58px; height: 88px;