// ── Burger btn + fan-of-5 (room.html only) ─────────────────────────── // // Sits parallel to .gear-btn-above-#id_kit_btn, but on the bud-side: // portrait : bottom-left, above #id_bud_btn // landscape: right sidebar, to the LEFT of #id_bud_btn (same horizontal // pair as gear ← kit at the top) // // Active state opens a fanning arc of 5 sub-btns 30deg apart, each // centred --r from the burger centre. R=7.75rem reads as a comfortable // spread w. ~0.4rem edge-to-edge gaps between adjacent sub-btns. // portrait : arc 12→4 o'clock (sky, earth, sea, voice, text) // landscape: arc 9→1 o'clock (same icon order, rotated CCW 90°) // // Sub-btns are pure scaffolding — no click handlers in this sprint. // // Landscape btn relocation rules for kit / gear / bud / kit_dialog / bud // panel / applet menus DON'T live in this partial — they're owned by // their respective `_game-kit.scss`, `_bud.scss`, `_applets.scss`, // `_room.scss` partials. _burger.scss only owns burger-specific styling. #id_burger_btn { position: fixed; bottom: 4.2rem; left: 0.5rem; // Match .gear-btn page-level z (314) — keeps burger BELOW kit_btn + // bud_btn (both z-318) + bud_panel (z-317) so those naturally cover // burger when they overlap. Dialog (z-316) covers burger too. z-index: 314; 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); transition: opacity 0.15s ease; &.active { color: rgba(var(--quaUser), 1); border-color: rgba(var(--quaUser), 1); } // Landscape: burger sits to the LEFT of #id_bud_btn (same bottom // anchor as bud). Mirrors gear-to-the-LEFT-of-kit at the top of the // right sidebar (see _applets.scss for the gear placement). @media (orientation: landscape) { left: auto; right: 4.2rem; // bud_btn right (0.5) + 3.7rem centre-to-centre delta bottom: 0.5rem; top: auto; } } // Fan anchor — sits at the burger centre. Sub-btns inside translate // outward radially when #id_burger_btn carries the .active class. #id_burger_fan { position: fixed; bottom: 5.7rem; // burger bottom (4.2) + half-btn (1.5) left: 2rem; // burger left (0.5) + half-btn (1.5) width: 0; height: 0; z-index: 313; // below #id_burger_btn (314) so burger stays clickable pointer-events: none; @media (orientation: landscape) { left: auto; right: 5.7rem; // burger right (4.2) + half-btn (1.5) → burger centre bottom: 2rem; // burger bottom (0.5) + half-btn (1.5) → burger centre top: auto; } } .burger-fan-btn { --r: 7.75rem; --i: 0; --base: 0deg; // portrait: arc starts at 12 o'clock --angle: calc(var(--base) + var(--i) * 30deg); position: absolute; left: -1.5rem; // centre 3rem btn on parent's 0,0 origin top: -1.5rem; width: 3rem; height: 3rem; border-radius: 50%; background-color: rgba(var(--priUser), 1); border: 0.15rem solid rgba(var(--secUser), 1); color: rgba(var(--secUser), 1); font-size: 1.25rem; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; // Closed state — collapsed onto burger centre, invisible transform: rotate(var(--angle)) translateY(0) rotate(calc(-1 * var(--angle))); opacity: 0; pointer-events: none; transition: transform 0.25s ease-out, opacity 0.2s ease; // Landscape: arc rotates CCW 90° — start at 9 o'clock instead of 12. @media (orientation: landscape) { --base: -90deg; } } // Per-btn arc index (clockwise from arc start) — voice leads, then sky, // earth, sea, text. Portrait arc: voice at 12, text at 4 o'clock. // Landscape arc: voice at 9, text at 1 o'clock. #id_voice_btn { --i: 0; } #id_sky_btn { --i: 1; } #id_earth_btn { --i: 2; } #id_sea_btn { --i: 3; } #id_text_btn { --i: 4; } // Open state — sub-btns swing out to their arc positions. #id_burger_btn.active ~ #id_burger_fan .burger-fan-btn { transform: rotate(var(--angle)) translateY(calc(-1 * var(--r))) rotate(calc(-1 * var(--angle))); pointer-events: auto; } // Active sub-btn = fully visible; inactive (default) = 0.6 opacity hint. // Active conditions are wired one-by-one in later sprints. #id_burger_btn.active ~ #id_burger_fan .burger-fan-btn.active { opacity: 1; } #id_burger_btn.active ~ #id_burger_fan .burger-fan-btn:not(.active) { opacity: 0.6; } // Icon swap — every sub-btn renders BOTH the real icon (.burger-fan-icon--on) // + a fa-ban placeholder (.burger-fan-icon--off). Real icon shows by // default in BOTH .active + inactive states; fa-ban only surfaces during // the .flash-inactive pulse below. Stacked absolute-position so swapping // doesn't shift the layout box. .burger-fan-btn { .burger-fan-icon--on, .burger-fan-icon--off { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .burger-fan-icon--on { display: inline-block; } .burger-fan-icon--off { display: none; } } // Click-while-inactive flash — burger-btn.js toggles .flash-inactive // twice in quick succession (~180ms on / 120ms off) for a brief --priRd // glow on the border + icon, AND swaps the real icon for fa-ban during // each pulse-on phase. Modeled on sig-select.js's SAVE SIG countdown // glow but tighter cadence + only 2 pulses. .burger-fan-btn.flash-inactive { border-color: rgba(var(--priRd), 1); color: rgba(var(--priRd), 1); box-shadow: 0 0 0.5rem 0.1rem rgba(var(--priRd), 0.75), 0 0 1.2rem 0.3rem rgba(var(--priRd), 0.35); .burger-fan-icon--on { display: none; } .burger-fan-icon--off { display: inline-block; } } // Burger hides when bud_panel is open — LANDSCAPE only. In portrait the // burger sits ABOVE the bud panel (bottom:4.2rem vs panel at bottom:0.5 // + height:3rem); no visual conflict. In landscape they share the // bottom-right area + the bud OK btn ends up obscured / pointer-events // races against the burger even at the lower z-index — explicit fade // keeps the bud_panel apparatus clean. @media (orientation: landscape) { html.bud-open #id_burger_btn { opacity: 0; pointer-events: none; } }