diff --git a/app/static/script.js b/app/static/script.js
index 8bbb3c9..9d48ecf 100644
--- a/app/static/script.js
+++ b/app/static/script.js
@@ -73,6 +73,7 @@ function renderLiveGame(game) {
${teamRow(game, 'Away', 'live')}
${teamRow(game, 'Home', 'live')}
+ ${ppIndicator(game)}
${hype}
`;
}
@@ -112,12 +113,10 @@ function teamRow(game, side, state) {
const logo = game[`${side} Logo`];
const score = game[`${side} Score`];
const sog = game[`${side} Shots`];
- const pp = game[`${side} Power Play`];
const record = game[`${side} Record`];
const sogHtml = (state === 'live' || state === 'final') && sog !== undefined
? `${sog} SOG` : '';
- const ppHtml = pp ? `${pp}` : '';
const right = state === 'pre'
? `${record}`
@@ -128,12 +127,31 @@ function teamRow(game, side, state) {
${name}
- ${sogHtml}${ppHtml}
+ ${sogHtml}
${right}
`;
}
+function ppIndicator(game) {
+ const awayPP = game['Away Power Play'];
+ const homePP = game['Home Power Play'];
+ const pp = awayPP || homePP;
+ if (!pp) return '';
+
+ const team = awayPP ? game['Away Team'] : game['Home Team'];
+ const timeStr = pp.replace('PP ', '');
+ const seconds = timeToSeconds(timeStr);
+ const attrs = `data-seconds="${seconds}" data-received-at="${Date.now()}" data-pp-clock`;
+
+ return `
+
+ PP
+ ${team}
+ ${timeStr}
+
`;
+}
+
// ── Gauge ────────────────────────────────────────────
function updateGauges() {
@@ -166,7 +184,7 @@ function secondsToTime(s) {
function snapshotClocks(grid) {
const snapshot = new Map();
grid.querySelectorAll('[data-game-key]').forEach(card => {
- const badge = card.querySelector('[data-seconds][data-received-at]');
+ const badge = card.querySelector('[data-seconds][data-received-at]:not([data-pp-clock])');
if (!badge) return;
const seconds = parseInt(badge.dataset.seconds, 10);
const receivedAt = parseInt(badge.dataset.receivedAt, 10);
@@ -181,7 +199,7 @@ function restoreClocks(grid, snapshot) {
grid.querySelectorAll('[data-game-key]').forEach(card => {
const prior = snapshot.get(card.dataset.gameKey);
if (!prior) return;
- const badge = card.querySelector('[data-seconds][data-received-at]');
+ const badge = card.querySelector('[data-seconds][data-received-at]:not([data-pp-clock])');
if (!badge) return;
// Only restore if we're outside the final sync window
if (prior.current > CLOCK_SYNC_THRESHOLD) {
diff --git a/app/static/styles.css b/app/static/styles.css
index 3fb1848..951ab88 100644
--- a/app/static/styles.css
+++ b/app/static/styles.css
@@ -209,6 +209,47 @@ main {
white-space: nowrap;
}
+/* ── Power Play Indicator ───────────────────────── */
+
+.pp-indicator {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ margin-top: 0.5rem;
+ padding: 0.35rem 0.5rem;
+ background: rgba(239, 68, 68, 0.1);
+ border: 1px solid rgba(239, 68, 68, 0.3);
+ border-radius: 6px;
+}
+
+.pp-label {
+ font-size: 0.6rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ color: var(--red);
+ text-transform: uppercase;
+ flex-shrink: 0;
+}
+
+.pp-team {
+ font-size: 0.72rem;
+ font-weight: 600;
+ color: var(--text);
+ flex: 1;
+ min-width: 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.pp-clock {
+ font-size: 0.72rem;
+ font-weight: 700;
+ color: var(--red);
+ flex-shrink: 0;
+ font-variant-numeric: tabular-nums;
+}
+
/* ── Hype Meter ─────────────────────────────────── */
.hype-meter {