diff --git a/web/src/components/BattlePhase.tsx b/web/src/components/BattlePhase.tsx index 31271f8..6da84f9 100644 --- a/web/src/components/BattlePhase.tsx +++ b/web/src/components/BattlePhase.tsx @@ -180,12 +180,25 @@ export function BattlePhase({ view, send }: Props) { const done = step >= events.length const lastEvent = step > 0 ? events[step - 1] : null + // paused freezes auto-advance so the player can walk the log manually. + const [paused, setPaused] = useState(false) + useEffect(() => { - if (done) return + if (done || paused) return const delay = EVENT_MS[events[step].type] ?? 1000 const t = window.setTimeout(() => setStep((s) => s + 1), delay) return () => window.clearTimeout(t) - }, [step, done, events]) + }, [step, done, paused, events]) + + // Manual controls. Stepping by hand pauses playback so it doesn't fight you. + const stepTo = (n: number) => { + setPaused(true) + setStep(Math.max(0, Math.min(events.length, n))) + } + const restart = () => { + setPaused(false) + setStep(0) + } const sides = useMemo( () => replay(events, battle.stackSizes, step), @@ -318,11 +331,43 @@ export function BattlePhase({ view, send }: Props) {

Battle! Round {battle.round}

- {!done && ( - - )} + + + + + {Math.min(step, events.length)} / {events.length} + + {!done && ( + + )} +
diff --git a/web/src/styles.css b/web/src/styles.css index 008e175..2bf0b76 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -726,6 +726,21 @@ h3 { justify-content: center; align-items: center; gap: 14px; + flex-wrap: wrap; +} + +.battle-controls { + display: flex; + align-items: center; + gap: 6px; +} + +.battle-step { + font-family: var(--font-display); + font-size: 0.85rem; + color: rgba(253, 243, 220, 0.7); + min-width: 3.5em; + text-align: center; } .battle-names {