14 Commits

Author SHA1 Message Date
cottongin
18d66c2dba fix: meter gradient now scales correctly across resolutions
The header element was width:100% so the gradient filled relative to
the viewport, not the visible text. With centered text, low fill
percentages fell entirely outside the text bounds — making the first
player (12.5%) invisible and causing shifts at different resolutions.
Changed to width:fit-content with translateX(-50%) centering so the
gradient maps 1:1 to the text content.

Made-with: Cursor
2026-03-20 23:06:45 -04:00
cottongin
fa7363bc78 fix: convert ES modules to classic scripts for file:// compatibility
Browsers block ES module imports over the file:// protocol due to CORS.
Users opening the overlay by double-clicking the HTML file saw all JS
fail to load. Replace import/export with a window.OBS global namespace
and classic <script> tags so the overlay works without a local server.

Made-with: Cursor
2026-03-20 22:20:12 -04:00
cottongin
a8b7df48a6 fix: restore lobby state on refresh, handle game.status heartbeat
- Extract maxPlayers from game object in #applyGameAdded so the meter
  works immediately when a game is added
- Read playerName field in lobby.player-joined (matches API payload)
- Handle game.status 20s heartbeat to keep overlay in sync
- Restore in-progress game on page refresh using status-live endpoint
  for full shard state including player names

Made-with: Cursor
2026-03-20 17:55:07 -04:00
cottongin
06e375ccdc feat: continuous pulse glow when lobby is full, add horizontal offset for player list
Make the header meter pulse animation loop indefinitely (1.2s
ease-in-out) while playerCount equals maxPlayers. Stops when a
player leaves. Also add horizontal offset control for the player
list positioning.

Made-with: Cursor
2026-03-20 15:15:09 -04:00
cottongin
4c56b7f8f9 feat: show meter fill percentage in dashboard status
Made-with: Cursor
2026-03-20 15:03:16 -04:00
cottongin
7a2f8419d5 feat: add animated gradient meter to header text based on player count
CSS background-clip: text with dynamic linear-gradient replaces flat
header color. Fill sweeps left-to-right (pink to white) proportional
to playerCount/maxPlayers. Pulse glow fires when lobby is full.

Made-with: Cursor
2026-03-20 15:02:46 -04:00
cottongin
88a4ac9889 fix: player list styling and positioning tweaks
- Empty slots use subtle gray dashed line instead of solid characters
- Left/Right positions anchor to screen edges, never obscuring room code
- Player list enabled by default
- Fix VALID_TRANSITIONS.get() crash (plain object, not Map)

Made-with: Cursor
2026-03-20 14:10:48 -04:00
cottongin
875153ef63 fix: address code review issues from final review
- Override modes now actually affect component visibility (force_show,
  force_hide, auto respected in transitions and updates)
- RoomCodeDisplay.update() guarded by #active flag to prevent
  re-activation outside lobby state
- broadcastUpdate() only sends to components when in lobby state
- Relaxed idle→playing/ended transitions for out-of-order events
- room.disconnected now clears room code, players, lobby state context
- Empty room codes clear input fields instead of leaving stale values
- Removed dead auto-mode-toggle UI and associated CSS
- Fixed player list vertical centering when offset is applied

Made-with: Cursor
2026-03-20 13:08:52 -04:00
cottongin
f754b227b3 feat: add controls module with debug dashboard and override support
Made-with: Cursor
2026-03-20 13:00:22 -04:00
cottongin
cddfe9125d feat: add player list component with slot-based display
Made-with: Cursor
2026-03-20 12:58:29 -04:00
cottongin
f0db0e8642 feat: extract audio controller into ES module, fix restart bug
Made-with: Cursor
2026-03-20 12:57:07 -04:00
cottongin
6b78928269 feat: extract room code display into ES module component
Made-with: Cursor
2026-03-20 12:55:01 -04:00
cottongin
1ed647208e feat: extract WebSocket client into ES module
Made-with: Cursor
2026-03-20 12:52:59 -04:00
cottongin
284830a24b feat: add OverlayManager state machine module
Made-with: Cursor
2026-03-20 12:50:48 -04:00