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
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
- 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
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
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
- 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
- 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
Event-driven state machine to coordinate room code display, audio,
and a new player slot list. Fixes audio restart bug by centralizing
lifecycle management. Adds new shard-based WebSocket event handling.
Made-with: Cursor