aperture architecture: lift the page-locking foundation (html/body/.container overflow:hidden + flex-column + min-height:0; .row flex-shrink:0) from 5 per-page SCSS files into _base.scss — was opt-in per page via `body.page-billboard` / `page-dashboard` / `page-gameboard` / `page-sky` / `page-wallet` etc., with 5 near-identical `html:has(body.page-X) { overflow: hidden }` + `body.page-X { … }` blocks duplicating the same rules; any page that forgot to set `page_class` in its view context (e.g. `epic.tarot_deck` — never set) rendered without the aperture, letting applet borders + titles clip past the fixed navbar/footer sidebars at narrower viewports; foundation now universal, page-specific overrides stay scoped — gameboard keeps `.container { overflow: clip }` (Firefox seat-tooltip scroll-anchoring quirk) + billboard/dashboard/gameboard keep `.row { margin-bottom: -1rem }` (h2-row tightening); page_class context vars + body class hooks preserved (FTs at test_bud_btn.py:370 / :379 still assert on them); regression gate: 60 layout-sensitive FTs (billboard, my_buds, bud_btn, applet_my_posts, dashboard, wallet, gameboard, layout_and_styling, jasmine) + 43 room FTs (gatekeeper_bud_btn, room_gatekeeper, room_sky_select, sharing) all green
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:16:12 -04:00
|
|
|
// Aperture foundation (html/body/.container overflow + flex-column) lives
|
|
|
|
|
// universally in _base.scss. Gameboard's only divergence: `overflow: clip`
|
|
|
|
|
// on .container instead of `hidden` — `clip` prevents the seat tooltip
|
|
|
|
|
// scroll-anchoring quirk Firefox triggers under overflow:hidden. The
|
|
|
|
|
// `.row { margin-bottom: -1rem }` pull mirrors the billboard/dashboard
|
|
|
|
|
// h2-row tightening.
|
2026-03-09 21:52:54 -04:00
|
|
|
|
|
|
|
|
body.page-gameboard {
|
|
|
|
|
.container {
|
2026-03-16 00:07:52 -04:00
|
|
|
overflow: clip;
|
2026-03-09 21:52:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.row {
|
|
|
|
|
margin-bottom: -1rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.gameboard-page {
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-width: 425px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 550px) {
|
|
|
|
|
.gameboard-page {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (min-width: 738px) {
|
|
|
|
|
.gameboard-page {
|
|
|
|
|
min-width: 666px;
|
|
|
|
|
}
|
2026-03-11 00:58:24 -04:00
|
|
|
|
|
|
|
|
body.page-gameboard .container {
|
|
|
|
|
overflow: visible;
|
|
|
|
|
}
|
2026-03-09 21:52:54 -04:00
|
|
|
}
|
|
|
|
|
|
2026-04-06 01:30:31 -04:00
|
|
|
@media (orientation: landscape) {
|
2026-03-23 01:06:14 -04:00
|
|
|
// Restore clip in landscape — overrides the >738px overflow:visible above,
|
|
|
|
|
// preventing the gameboard applets from bleeding into the footer sidebar.
|
|
|
|
|
body.page-gameboard .container {
|
|
|
|
|
overflow: clip;
|
|
|
|
|
}
|
|
|
|
|
// Reset the 666px min-width so gameboard-page shrinks to fit within the
|
|
|
|
|
// sidebar-bounded container rather than overflowing into the footer sidebar.
|
|
|
|
|
.gameboard-page {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-09 23:48:20 -04:00
|
|
|
#id_applet_game_kit {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
#id_game_kit {
|
|
|
|
|
flex: 1;
|
|
|
|
|
position: relative;
|
2026-03-09 21:52:54 -04:00
|
|
|
display: flex;
|
2026-03-09 23:48:20 -04:00
|
|
|
flex-direction: row;
|
2026-03-24 22:25:25 -04:00
|
|
|
flex-wrap: wrap;
|
2026-03-09 23:48:20 -04:00
|
|
|
align-items: center;
|
2026-03-24 22:25:25 -04:00
|
|
|
justify-content: center;
|
|
|
|
|
gap: 0.75rem;
|
2026-03-09 23:48:20 -04:00
|
|
|
overflow-x: visible;
|
|
|
|
|
scrollbar-width: none;
|
|
|
|
|
&::-webkit-scrollbar { display: none; }
|
2026-03-09 22:42:30 -04:00
|
|
|
|
2026-03-09 23:48:20 -04:00
|
|
|
.token { position: static; }
|
2026-03-09 22:42:30 -04:00
|
|
|
|
2026-04-15 22:39:01 -04:00
|
|
|
.token:hover .token-tooltip,
|
|
|
|
|
.token:hover .tt { display: none; } // JS portal handles show/hide
|
2026-03-09 23:48:20 -04:00
|
|
|
|
|
|
|
|
.token,
|
|
|
|
|
.kit-item { font-size: 1.5rem; }
|
|
|
|
|
|
|
|
|
|
.kit-item { opacity: 0.6; }
|
2026-03-09 22:42:30 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#id_applet_new_game,
|
|
|
|
|
#id_applet_my_games {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
ul {
|
|
|
|
|
flex: 1;
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
|
|
small {
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
font-style: italic;
|
2026-03-09 21:52:54 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-14 00:34:07 -04:00
|
|
|
#id_applet_my_games {
|
|
|
|
|
|
|
|
|
|
ul {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-09 23:48:20 -04:00
|
|
|
#id_tooltip_portal {
|
|
|
|
|
position: fixed;
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
|
2026-04-16 00:14:47 -04:00
|
|
|
padding: 0.75rem 1.5rem;
|
|
|
|
|
|
2026-04-21 15:46:30 -04:00
|
|
|
@extend %tt-token-fields;
|
2026-04-16 00:14:47 -04:00
|
|
|
|
|
|
|
|
.tt-equip-btns {
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: -1rem;
|
|
|
|
|
top: -1rem;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 0.25rem;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
|
|
|
|
.btn { margin: 0; }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 21:18:09 -04:00
|
|
|
// Tray sig-card tooltip (Phase 2) — PRV / NXT btns pinned to the bottom
|
|
|
|
|
// corners of the portal, 1rem outside the panel so the btn centres land
|
|
|
|
|
// exactly on the corners. The shared @stat-block-shared mixin in
|
|
|
|
|
// _card-deck.scss already does this for fan / sig / sea contexts; the
|
|
|
|
|
// portal isn't covered by that mixin so we re-state the rules here.
|
|
|
|
|
.fyi-prev,
|
|
|
|
|
.fyi-next {
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: -1rem;
|
|
|
|
|
margin: 0;
|
|
|
|
|
z-index: 70;
|
|
|
|
|
}
|
|
|
|
|
.fyi-prev { left: -1rem; }
|
|
|
|
|
.fyi-next { right: -1rem; }
|
|
|
|
|
|
2026-03-09 23:48:20 -04:00
|
|
|
&.active { display: block; }
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-16 00:07:52 -04:00
|
|
|
#id_mini_tooltip_portal {
|
|
|
|
|
position: fixed;
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
font-size: 0.8em;
|
|
|
|
|
font-style: italic;
|
|
|
|
|
width: fit-content;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
|
|
|
|
&.active { display: block; }
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-09 21:52:54 -04:00
|
|
|
@media (max-height: 500px) {
|
|
|
|
|
body.page-gameboard {
|
|
|
|
|
.container {
|
|
|
|
|
.row {
|
|
|
|
|
padding: 0.25rem 0;
|
|
|
|
|
.col-lg-6 h2 {
|
|
|
|
|
margin-bottom: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|