Track a match: length, score sheet, and a clock that survives a quit

Match length is a new first row in the settings, 1 to 29 points, stepping by
2 so it can only ever be odd. The Time setting now means time *per point* and
each clock starts at time × points, which the settings sheet spells out.

The middle bar icon opens a score sheet. Edits are staged there and only
reach the state on Done, which then does one of three things:

  nothing changed  turn, delay position and moves all untouched
  score changed    displayed times become the reserves, then back to the
                   first tap with moves zeroed — the clocks keep their value
  clock changed    the spent delay is added back on so the panel shows
                   exactly what was typed, and the turn carries on

Tapping outside the sheet discards the staged edits, so a stray tap can't
restart a game.

reset() was called both by the Reset button and by every settings change, so
clearing the score in it would have wiped a live match whenever the delay was
nudged. It splits into resetClocks() and resetAll(); only the button clears
the score. Shortening a match clamps a score that no longer fits.

The whole game now persists, not just the settings: score, both reserves,
moves, whose turn and how much delay was left, saved on the discrete
transitions and on pagehide/visibilitychange. Time passing while the app is
dead can't be charged to anyone, so a running clock is stored as paused and
comes back on the play button. A malformed saved game is ignored rather than
half-applied.

Each panel shows its own score first, stacked above its move count at the
top left.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 14:39:32 +02:00
co-authored by Claude Opus 5
parent 64bc4a9a34
commit 92bb31b18e
3 changed files with 362 additions and 40 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
/* Cache-first: once installed the clock never touches the network again. */
const CACHE = "bgclock-v3";
const CACHE = "bgclock-v4";
const FILES = [
"./",
"./index.html",