spreadlab/web/src
Justin Visser 0e3a14a0b3 web: playback, slice 4 of M3
usePlayback drives one global round on a rAF timer: 700 ms per round at
1x, speed pill cycling 0.5/1/2, play-once autoplay after the first load,
no looping; at the final round the play button becomes replay. Under
prefers-reduced-motion there is no autoplay, the page settles on the
final round, and the cadence slows to 1000 ms.

The PlayerBar is the mockup's centered pill with a native range
scrubber (one tick per round, aria-valuetext, seeking pauses) and the
global keyboard map: Space toggles, arrows step, Home/End jump; text
inputs and native control handling are left alone. A single polite live
region announces run updates, pauses, scrub releases, and the final
state.

Nodes reached in the current round pop in (scale 0.6 to 1, 250 ms
ease-out) with a small deterministic stagger so each round reads as a
wave. Per Justin's feedback the panel percentage and reached count now
follow the playhead instead of sitting on the final outcome; the hero
keeps the final numbers, since its sentence claims outcomes.
2026-06-10 17:15:38 +02:00
..
assets web: the dashboard page, slice 3 of M3 2026-06-10 16:55:14 +02:00
components web: playback, slice 4 of M3 2026-06-10 17:15:38 +02:00
composables web: playback, slice 4 of M3 2026-06-10 17:15:38 +02:00
lib web: the dashboard page, slice 3 of M3 2026-06-10 16:55:14 +02:00
presets web: the dashboard page, slice 3 of M3 2026-06-10 16:55:14 +02:00
types api: POST /api/scenario returns result plus graph topology (M3 slice 1) 2026-06-10 15:48:48 +02:00
App.vue web: playback, slice 4 of M3 2026-06-10 17:15:38 +02:00
main.ts web: scaffold Vue 3 + Vite app (create-vue, lean options) 2026-06-10 12:55:43 +02:00