#id_kit_btn { position: fixed; bottom: 0.5rem; right: 0.5rem; // In landscape, kit btn relocates to the TOP of the right sidebar // — anchored at right: 0.5rem (same as portrait), so the gear-to-the- // LEFT-of-kit gap (in _applets.scss) reads as 0.7rem edge-to-edge, // matching portrait's vertical gear-above-kit gap. Sidebar-centring // via calc((--sidebar-w - 3rem) / 2) = 1rem would tighten that gap // to 0.2rem, which reads visually wider than portrait. @media (orientation: landscape) { right: 0.5rem; top: 0.5rem; bottom: auto; } z-index: 318; font-size: 1.75rem; cursor: pointer; color: rgba(var(--secUser), 1); display: inline-flex; align-items: center; justify-content: center; width: 3rem; height: 3rem; border-radius: 50%; background-color: rgba(var(--priUser), 1); border: 0.15rem solid rgba(var(--secUser), 1); &.active { color: rgba(var(--quaUser), 1); border-color: rgba(var(--quaUser), 1); } } #id_kit_bag_dialog { // Override dialog's native display:none so we can drive visibility via max-height display: block !important; position: fixed; bottom: 0; left: 0; right: 0; width: 100%; max-width: none; margin: 0; padding: 0; border: none; border-top: 0.1rem solid rgba(var(--quaUser), 1); background: rgba(var(--priUser), 0.97); // Below kit_btn + burger_btn (both z-318) so those btns stay visible // when the dialog opens — user can re-click kit_btn to close + the // burger fan stays accessible alongside an open dialog. z-index: 316; overflow: hidden; // Closed state — portrait: grow from below the footer (max-height) max-height: 0; visibility: hidden; transition: max-height 0.25s ease-out, visibility 0s 0.25s; &[open] { max-height: 5rem; visibility: visible; transition: max-height 0.25s ease-out, visibility 0s; display: flex !important; flex-direction: row; gap: 1.5rem; align-items: center; padding: 0.4rem 1rem; } // In landscape, the dialog slides in from off-viewport to the RIGHT, // landing ATOP the right sidebar (covers kit + gear + burger + bud // when open). Full viewport height. Width matches sidebar-w so the // closed→open width animation reads like the portrait grow-UPWARD- // from-bottom rotated 90° — closed has zero width, open spans the // sidebar column from right edge inward. @media (orientation: landscape) { top: 0; bottom: 0; right: 0; left: auto; width: var(--sidebar-w); height: auto; // Opaque in landscape — the dialog covers the sidebar btns + the // burger + bud area when open; transparency would let those btns // bleed through the dialog content. background: rgba(var(--priUser), 0.97); // Closed state — width animates from 0 (grows leftward from right) max-width: 0; max-height: none; transition: max-width 0.25s ease-out, visibility 0s 0.25s; // Top-edge accent → left-edge accent (border on the aperture-facing side) border-top: none; border-left: 0.1rem solid rgba(var(--quaUser), 1); &[open] { max-width: var(--sidebar-w); max-height: none; transition: max-width 0.25s ease-out, visibility 0s; display: flex !important; // DOM order is Deck→Dice→Trinket→Tokens; column-reverse paints // them visually bottom→top so Deck rests at the bottom of the // bar and Tokens at the top. flex-direction: column-reverse; gap: 1rem; align-items: center; padding: 1rem 0.25rem; } } } .kit-bag-section { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; flex-shrink: 0; // Landscape — stack icon row ABOVE label. DOM order is label → row; // column-reverse paints row at top + label at bottom (icon above title). @media (orientation: landscape) { flex-direction: column-reverse; align-items: center; gap: 0.25rem; } } .kit-bag-label { font-size: 0.6rem; font-weight: 700; text-transform: uppercase; text-decoration: underline; letter-spacing: 0.2em; color: rgba(var(--secUser), 0.5); writing-mode: vertical-rl; text-orientation: mixed; transform: rotate(180deg) scaleX(1.3); padding: 0 0.25rem 0 0.5rem; // Landscape — undo vertical writing-mode + rotation; label reads // horizontally beneath its icon in the column-reverse section. @media (orientation: landscape) { writing-mode: horizontal-tb; text-orientation: mixed; transform: none; padding: 0; font-size: 0.5rem; text-align: center; } } .kit-bag-row { display: flex; flex-direction: row; gap: 0.75rem; } #id_kit_bag_dialog { .token { font-size: 1.5rem; cursor: pointer; transition: filter 0.15s; padding: 0 0.125rem; &:hover .token-tooltip, &:hover .tt { display: none; } // JS positions these as fixed } .token-tooltip, .tt { z-index: 9999; @extend %tt-token-fields; // Buttons positioned on left edge of the fixed inline tooltip .tt-equip-btns { position: absolute; left: -1rem; top: 0; display: flex; flex-direction: column; gap: 1.25rem; z-index: 1; .btn { margin: 0; } } } .kit-bag-deck { font-size: 1.5rem; cursor: pointer; padding: 0 0.125rem; color: rgba(var(--terUser), 1); } .kit-bag-placeholder { font-size: 1.5rem; padding: 0 0.125rem; color: rgba(var(--quaUser), 0.3); } } .kit-bag-section--tokens { flex: 1; min-width: 0; overflow: hidden; } .kit-bag-row--scroll { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; &::-webkit-scrollbar { display: none; } // Landscape — the dialog runs vertically, so the Tokens row also // flips to a vertical column + scrolls along the y-axis instead. @media (orientation: landscape) { flex-direction: column; overflow-x: visible; overflow-y: auto; } } .kit-bag-empty { font-size: 0.7rem; color: rgba(var(--secUser), 0.4); } // ── Game Kit page ──────────────────────────────────────────────────────────── #id_game_kit_applets_container { flex: 1; min-height: 0; display: flex; flex-direction: column; } #id_game_kit_applets_container section { display: flex; flex-direction: column; h2 { flex-shrink: 0; } .gk-items { flex: 1; overflow-y: auto; } } .gk-items { display: flex; flex-direction: row; flex-wrap: wrap; gap: 1rem; align-items: center; } // `.gk-deck-card` + `.gk-trinket-card` + `.gk-token-card` dropped from this // multi-class rule — the gk-decks/trinkets/tokens sections all render as // bare `.token` icons (FA glyph or SVG card-stack) sized by their own rules // in `_gameboard.scss`; no border + no padding-shell since the hover-portal // tooltip carries the name/count/description. Pronoun cards still use the // bordered card-shell shape via this rule. // // Icon-row treatment for Trinkets / Tokens / Card Decks — the small icons // look lonely huddled on the left edge of the wider applet rectangle, so // center them along the main axis + bump the gap. Scoped to the 3 specific // section IDs so it doesn't bleed to Pronouns (whose cards fill the row + // look fine left-anchored). #id_gk_trinkets .gk-items, #id_gk_tokens .gk-items, #id_gk_decks .gk-items { justify-content: center; gap: 2rem; } // `#id_game_kit` wraps every section in `_game_kit_sections.html` so // `gameboard.js`'s `getElementById('id_game_kit')` finds ONE scope covering // trinkets + tokens + decks. But that wrapper sits between `#id_gk_sections // _container` (the CSS-grid parent — see `_applets.scss:268`) and its // `
` children, breaking the `grid-column: span var(--applet-cols)` // layout that needs the sections as DIRECT children. `display: contents` // makes the wrapper transparent to layout — sections still resolve as grid // children of `#id_gk_sections_container` — while keeping the wrapper a // real DOM element JS can query + read data-attrs off. #id_gk_sections_container > #id_game_kit { display: contents; } // My Wallet applet (`_applet-wallet.html` on /dashboard/) uses the same // `#id_game_kit` wrapper so `gameboard.js` picks up its `.token` icons + // fires the hover-portal tooltips. Lay items out as a centered flex row // (parity w. the standalone game_kit.html sections — see `#id_gk_trinkets // .gk-items, #id_gk_tokens .gk-items, #id_gk_decks .gk-items` above). // `height: 100%` keeps the row vertically centered inside the applet box // since the section's body has the h2 absolute-positioned + claims full // box height. #id_applet_wallet > #id_game_kit.wallet-items { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2rem; height: 100%; } // `.token` is a flex child of `.gk-items` — make it a positioning context // so the `.shop-badge` (position: absolute, top: -0.8rem, right: -1.2rem) // anchors off the icon, NOT off some grandparent. Also pin `font-size: // 1.5rem` so the standalone game_kit.html icons match the gameboard's // Game Kit applet sizing — `_gameboard.scss:79` sets this for `#id_applet // _game_kit #id_game_kit .token` (only fires on /gameboard/ since `#id_ // applet_game_kit` doesn't exist on this page); we re-state at the same // 1.5rem so the visual weight is identical across the two surfaces. #id_game_kit .token { position: relative; font-size: 1.5rem; } .gk-pronoun-card { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; padding: 0.75rem 1rem; border-radius: 0.5rem; border: 0.1rem solid rgba(var(--secUser), 0.3); cursor: pointer; font-size: 1.5rem; min-width: 6rem; text-align: center; transition: border-color 0.15s; span { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; } small { font-size: 0.6rem; opacity: 0.5; } &:hover { border-color: rgba(var(--secUser), 0.8); } } .gk-pronoun-card { // Card shows the ideology slug (pluralism, bawlmorese, …) in italic; // the guard portal previews the actual slash trio above OK|NVM via JS. // Active card is filled with the secondary tint so the user can see at a // glance which preference is currently in effect. .gk-pronoun-label { font-size: 0.85rem; letter-spacing: 0.05em; text-transform: lowercase; font-style: italic; } &.active { border-color: rgba(var(--secUser), 1); background: rgba(var(--secUser), 0.18); } } #id_guard_portal .guard-pronoun-trio { display: block; margin-top: 0.25rem; font-size: 0.75rem; letter-spacing: 0.06em; opacity: 0.75; text-align: center; } .gk-placeholder { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; padding: 0.75rem 1rem; border-radius: 0.5rem; border: 0.1rem dashed rgba(var(--secUser), 0.2); font-size: 1.5rem; min-width: 6rem; text-align: center; opacity: 0.4; span { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; } } .gk-empty { font-size: 0.8rem; opacity: 0.45; }