room scroll-of-events: table-hex aperture binary scroll-snaps to the room provenance feed — TDD

From Role Select onwards, scrolling DOWN in the table-hex aperture swaps the entire hex view for the room's GameEvent feed (mirrors my_sky's wheel<->form; scroll-snap-stop:always = no partial scroll). Reuses the Billscroll query + core/_partials/_scroll.html so the feed renders identically.

room.html: #id_room_aperture wraps .room-hex-pane (existing .room-shell + the _table_positions strip moved INSIDE so the circles scroll away with the hex) + .room-scroll-pane (includes new _room_scroll.html); 'is-scrollable' added iff table_status set.

_room_scroll.html (new) = the DRY seam for my_sea; includes the shared scroll partial + a tiny dots-animation script (no scroll-position persistence). room_view adds events/viewer/scroll_position (same query as billboard.views.scroll).

_room.scss: .room-aperture + .room-pane (height:100%, not min-height); .is-scrollable engages scroll-snap-type:y mandatory + per-pane scroll-snap-align:start & scroll-snap-stop:always; .room-scroll-pane styles #id_drama_scroll + .scroll-buffer { margin-top:auto } (pure-CSS bottom-pin).

Trap: the aperture & panes set NO z-index/transform/opacity/filter -> NO stacking context, so the position strip's z-130 still resolves in the root context, above the gate/sig overlays (z-100/120). Verified by gatekeeper FTs (token drop + circle/modal layering).

Deferred INDEFINITELY (user): rising-game-cost + max room membership + max simultaneous CARTE slots + in-slot token combinations — until CARTE is anything but a secret type of Trinket.

Tests: RoomScrollOfEventsTest (5 ITs — aperture wraps hex+scroll panes, is-scrollable from Role Select, feed renders + scoped to room, no scroll pane in gate phase); functional_tests/test_game_room_scroll.py (2 FTs — computed scroll-snap props + scroll-down reveals the feed). 551 epic ITs/UTs green; 2 new FTs green; gatekeeper (token-drop + circle layering) + role-select (card fan) FTs green.

[[project-room-scroll-of-events]] [[project-position-circle-tooltips]]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-06-01 18:32:57 -04:00
parent 5229b9f96a
commit a4adf9664b
6 changed files with 303 additions and 3 deletions

View File

@@ -44,6 +44,90 @@ html.sea-open #id_aperture_fill {
opacity: 1;
}
// ─── Table-hex aperture: binary scroll-snap toggle ─────────────────────────
// Mirrors my_sky's wheel<->form swap (`_sky.scss` body.sky-saved block). The
// aperture fills .room-page; from Role Select onwards it holds TWO panes —
// the hex (default) and the room's provenance scroll — and scroll-snaps
// between them. CRITICAL: the aperture and panes set NO z-index / transform /
// opacity / filter, so they create NO stacking context — the position strip's
// z-130 (a hex-pane descendant) still resolves in the root context, above the
// gate/sig overlays (z-100/120), exactly as when it lived at room-page root.
.room-aperture {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
// Gate phase (single pane): static + clipped, like the old .room-page.
overflow: hidden;
}
.room-pane {
position: relative; // containing block for the position strip (z-auto)
flex: 0 0 auto;
width: 100%;
// EXACTLY one aperture tall (not min-height) so the snap stops land at
// integer multiples of the viewport — the binary toggle, no mid-scroll.
height: 100%;
}
.room-hex-pane {
display: flex;
align-items: center;
justify-content: center;
}
// Two panes present (table phase) → engage the binary snap. `is-scrollable`
// is added by the template iff `room.table_status` is set (Role Select on).
.room-aperture.is-scrollable {
overflow-y: auto;
overflow-x: hidden;
scroll-snap-type: y mandatory;
overscroll-behavior-y: contain;
-webkit-overflow-scrolling: touch;
.room-pane {
scroll-snap-align: start;
scroll-snap-stop: always; // hard stop each section — no coasting
}
}
.room-scroll-pane {
display: flex;
flex-direction: column;
padding: 0.75rem;
background: rgba(var(--duoUser), 1); // matches the aperture / billscroll bg
#id_drama_scroll {
flex: 1;
min-height: 0;
overflow-y: auto;
display: flex;
flex-direction: column;
// Pin the "What happens next…?" buffer to the bottom when the feed is
// short (pure-CSS equivalent of billscroll's rAF marginTop nudge).
.scroll-buffer {
margin-top: auto;
display: flex;
justify-content: center;
align-items: baseline;
padding: 2rem 0 1rem;
opacity: 0.4;
font-size: 0.8rem;
text-transform: uppercase;
.scroll-buffer-text { letter-spacing: 0.33em; }
.scroll-buffer-dots {
display: inline-flex;
letter-spacing: 0;
span { display: inline-block; width: 0.7em; text-align: center; }
}
}
}
}
.gate-backdrop {
position: fixed;
inset: 0;