Phase 3 of the room GATE VIEW + seat-renewal sprint. When the viewer's
own FILLED gate-slot cost has lapsed (filled_at past the cost-current
window), the center hex shows a GATE VIEW button (→ room gate-view)
instead of the phase affordances, so they must renew before advancing.
- _role_select_context: adds viewer_cost_current / viewer_in_grace from
the viewer's FILLED slot (no slot → current, defensive)
- room.html: the ROLE card-stack renders OUTSIDE the cost gate (the
gamer's own role pick survives the renewal grace — deposit privilege);
GATE VIEW supersedes the rest of .table-center; #id_pick_sigs_wrap
(SCAN SIGS, advancing the whole table) is gated on viewer_cost_current;
the SIG/SKY/SEA overlays are gated too (they embed their trigger-btn
ids in JS, so they must not render alongside GATE VIEW)
- per user-spec: only the ROLE pick stays in grace; SCAN SIGS + every
later phase get GATE VIEW
Tests: RoomCenterSupersessionTest (9) — GATE VIEW supersedes sig overlay
/ CAST SKY / DRAW SEA / SCAN SIGS when lapsed, normal buttons when
current; RoomRoleStackGraceTest (1) — card-stack (eligible) kept
alongside GATE VIEW when lapsed. 838 epic+gameboard ITs green.
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.8 (1M context) <noreply@anthropic.com>