Closes the spawn-time half of the replay-overlay redesign open in
SESSION_HANDOFF.md by adding the 1px cyan scrub bar called for in
docs/ui-mockups/replay-overlay-mobile.html. A track in BORDER_SUBTLE
spans the bottom edge of the banner and the cyan ACCENT_PRIMARY fill
mirrors cursor / total via a new ReplayOverlayScrubFill component +
update_scrub_fill system. The pure scrub_pct helper is shared between
the spawn path (initial fill width) and the per-frame updater so the
first paint already reflects state instead of popping 0 → cursor on
the first tick — same shape as the existing format_progress /
update_progress_text split.
Two new tests (1176 → 1178): scrub_pct_covers_state_corners pins the
helper's four corners (Inactive / cursor=0 / midpoint / Completed) and
overlay_scrub_fill_tracks_cursor drives ReplayPlaybackState end-to-end
and asserts Node.width on the unique scrub-fill entity. Same change-
detection guard as the text updaters, so an idle replay leaves the
node untouched.
Header text treatment, move-log scroll, MOVE chip, and WIN MOVE callout
from the same mockup are still open — separate commits.
- input_plugin's hint-source card tint moves from raw bright-yellow
`srgba(1.0, 1.0, 0.4, 1.0)` to the design-system STATE_WARNING
token, so the source card and the destination pile (which already
uses STATE_WARNING via HINT_PILE_HIGHLIGHT_COLOUR) wear the same
attention colour as a coherent pair.
- replay_overlay had two stale doc comments referencing the old
"loud yellow accent" — Primary is now cyan (ACCENT_PRIMARY).
Comments updated; no behaviour change.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Visible UI for the in-engine replay playback that just landed: a
thin top banner anchored to the window edge while
ReplayPlaybackState is Playing or Completed, surfacing the player's
current position in the move list and a way to abort.
Layout: full-width banner ~48 px tall with three children — a
"Replay" label in ACCENT_PRIMARY left-aligned, "Move N of M"
progress text centred, and a Tertiary Stop button right-aligned via
the existing spawn_modal_button helper so it gets focus rings and
hover/press states for free.
Z_REPLAY_OVERLAY = Z_DROP_OVERLAY + 5 (= 55) sits above HUD but
well below modal scrim (≥200), so Settings, Pause, and Help still
render on top of the overlay during a replay — the player can
adjust audio or pause mid-playback.
State-driven: the spawn system reacts to Changed<ReplayPlaybackState>
transitions, swapping the banner text to "Replay complete" when
state moves Playing → Completed and despawning entirely when state
returns to Inactive (either via the Stop button, completion linger
expiry, or external reset).
Five tests cover spawn-on-Playing, progress text, stop-button
clears state and despawns, despawn-on-Inactive, and Completed
banner text swap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>