Per-file content-hash versioning on every /static reference, immutable cache
headers on versioned URLs, no-cache on HTML, auto-bumped service worker cache
name with stale-while-revalidate for assets, and a controllerchange listener
that silently reloads the page when a new SW takes control.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tickClocks iterates every [data-seconds][data-received-at] element. Rendering the PP indicator with those attrs during an intermission made the clock bleed seconds even though play is paused and the penalty isn't running. Drop the ticking attrs when game['Intermission'] is true — render a plain static "PP MM:SS" that resumes ticking on the next live payload.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The header PP badge repeated the team name that was already visible a row below. Put the indicator on the team that actually has the advantage: "PP 01:47" appears inline next to SOG, and the old ppBadge + .badge-pp styling go away.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Browsers already gate Notification.requestPermission behind a native
prompt, so a dedicated button was redundant UI clutter. Prompting on
load (only when permission state is "default") keeps the flow and
clears space in the banner for future notification types.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The banner read "Day 1 of ~60" on day 2 of the playoffs because the old
anchor recorded whatever date we first polled a playoff game as Day 1.
Now round start dates come from /v1/schedule/playoff-series, so Day N
is authoritative and resets at each round boundary. Drops the noisy
"of ~60" denominator.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Turn a regular-season-looking Tuesday into a full playoff experience:
- Playoff banner with round + day + series + elimination counts, gold/silver
Cup theme toggled by body.playoff-mode
- Series context on each playoff card: round chip, series score, stake badges
(GAME 7, CLINCHER, PIVOTAL), and one-line blurb
- Game 7s pin to a new Spotlight section above Live
- Playoff OT renders with SUDDEN DEATH badge and pulsing gold border
- Client-side OT notifications via bell button in the banner
- New /series/<id> drill-down with headline, next-game, and game-by-game history
- New /bracket page: 7-column desktop grid, accordion on mobile
- Day N banner count auto-anchors on first playoff scoreboard hit
- SQLite cache for bracket + per-series schedules, stale-on-failure up to 24h
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Moves the PP team + countdown into the badges row next to period and
clock, freeing up a full line of vertical space on each live card.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Empty net detection: pulled goalie triggers +150-250 bonus, stacks with PP
- Playoff series importance: Game 7 Cup Final = 200, elimination games scale
by round; fallback of 100 when series data unavailable
- Period-aware score differential: 2-goal deficit penalty DECREASES in final
2 min of P3 (goalie-pull zone), 3+ goal games get harsher penalties late
- Persistent comeback narrative: tracks max deficit, sustained bonus for 2+
goal recoveries instead of one-shot spike (0-3 to 3-3 = 150 persistent)
- Shootout special handling: flat base 550 with no time component; ranks below
dramatic close P3 games (skills competition, not hockey)
- Multi-man advantage: parses situationCode for 5v3/4v3, applies 1.6x PP mult
- Non-linear time priority: elapsed^1.5 curve weights final minutes more
- Matchup multiplier rebalance: P1/P2 from 2.0/1.65 to 1.5, tiebreaker not
dominant factor
- Frontend gauge max raised from 700 to 1000 with adjusted color thresholds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Games in intermission now appear in their own section between Live and
Scheduled. The section is hidden when no games are in intermission,
matching the behavior of the other section headings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds full PWA compliance: web app manifest, service worker with
cache-first static / network-first scoreboard strategy, and a
generated hockey puck icon (512, 192, 180, 32px) on the app's
dark navy background. Includes all required meta tags for iOS
standalone mode and a /favicon.ico route.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows a red pill below the team rows when a PP is active, displaying
the team on the power play and a ticking countdown. PP clock always
resyncs from the API (no local anchoring) since 2-minute penalties
are short enough that accuracy matters throughout. Removed the old
inline PP text from team rows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Snapshot the locally-computed clock state before each re-render and
restore it afterwards, so the API response doesn't cause a visible
jump. Only resync to the API value in the final 60 seconds, where
accuracy matters.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store seconds + received-at timestamp on time badge. A 1s interval
decrements locally so the clock never stutters between API polls.
Drift-corrected: always computed from the anchored API value, not
accumulated ticks. Re-render on each API response reanchors to the
real value.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- larger scores (1.6rem), logos (40px), and card width (290px)
- green top border accent on live game cards
- section headings reduced to small muted caps
- more breathing room in team rows
- slightly larger card radius and gap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>