lockRead-only — viewing only, changes are not saved
{{ !hasCreds ? 'NO SYNC' : syncing ? 'SYNC…' : readOnly ? 'RO' : syncError ? 'ERR' : 'LIVE' }}
⚠ No sync credentials Go to Setup tab to configure your JSONBin, or open with ?bin=ID&key=KEY
New Game
Game Name
Score Unit
Low score wins
Leaderboard sorts lowest first
Win Condition
sports_esports
No games yet
Start a new game above to track scores in real time.
{{ activeGame.name }}
{{ activeGame.unitLabel || 'Level' }} {{ currentUnit(activeGame) }} · {{ activeGame.players.length }} players · Low wins · Play till {{ activeGame.winValue }} pts · Play {{ activeGame.winValue }} {{ activeGame.unitLabel || 'Level' }}s
emoji_events {{ activeGame.winType === 'score' ? 'A player reached ' + activeGame.winValue + ' pts' : 'All players reached ' + (activeGame.unitLabel || 'Level') + ' ' + activeGame.winValue }} — Game Complete! Editing still allowed.
person_add
No players yet
Tap here to add players
{{ i+1 }}
{{ p.name }}
{{ activeGame.unitLabel || 'Level' }} {{ p.level || 1 }} {{ (p.level || 1) >= activeGame.winValue ? '✓ Done' : (activeGame.winValue - (p.level || 1)) + ' to go' }}
{{ calcScore(p.name) }}
{{ calcDelta(p.name) <= 0 ? '✓ Done' : calcDelta(p.name) + ' to go' }}
history
No history yet
Tap a player on the leaderboard to enter a score.
{{ activeGame.unitLabel || 'Level' }} {{ lvlGroup.level }}
Players
Global Roster
No players in roster yet.
{{ p }}check
Register New Player
Timer
{{ timerDisplay }}
{{ currentPreset }}s — tap to change
Buzzer
Tap to sound buzzer
Buzzer Style
Setup
Active JSONBin
Current Bin
CONNECTED CONNECTED RO NOT SET
{{ activeBinId || 'No bin configured' }}
Switch Bin
Sync Rate
How often to auto-sync when a game is active (seconds)
seconds (current: {{ syncRate }}s)
Share URL with Credentials
{{ shareUrl }}
Note Lookahead History
{{ noteHistory.length }} saved note{{ noteHistory.length !== 1 ? 's' : '' }} — {{ noteHistory.slice(0,3).join(', ') }}{{ noteHistory.length > 3 ? '…' : '' }}
{{ activeGame.name }}
{{ activeGame.unitLabel || 'Level' }} {{ (() => { const g = activeGame; if (!g.history.length || !g.players.length) return g.startUnit||1; const start = g.startUnit||1; let lvl = start; while(g.players.every(p=>g.history.some(h=>h.playerName===p.name&&h.level===lvl))) lvl++; return lvl > start ? lvl-1 : start; })() }}
emoji_events
{{ activeGame.winType === 'score' ? 'A player reached ' + activeGame.winValue + ' pts!' : 'All players reached ' + (activeGame.unitLabel || 'Level') + ' ' + activeGame.winValue + '!' }}
Game Complete
{{ i+1 }}
{{ p.name }}
{{ activeGame.unitLabel || 'Level' }} {{ Math.max(...activeGame.history.filter(h=>h.playerName===p.name).map(h=>h.level), p.level||1) }}
{{ calcScore(p.name) }}
{{ calcDelta(p.name) <= 0 ? '✓ Done' : calcDelta(p.name) + ' to go' }}
Timer
{{ timerDisplay }}
{{ currentPreset }}s — tap to change