/* Game room: the in-game layout behind the game_room_v2 flag
 * (docs/superpowers/specs/2026-10-02-game-room-phase1-design.md).
 *
 * Scope (A7): every rule sits under a room marker: #screen-game.game-room,
 * its data-room-layout / data-room-sheet attributes, or body.game-room-active.
 * With the flag off none of them exist, so the classic screen is untouched.
 *
 * Names: Task 16's class contract table in the implementation plan is the one
 * authority (ruling D-5). Tasks 23, 25 and 26 append their own scoped blocks
 * (the chat's player names, the Controls tab, Clips & Replays); this file
 * styles everything else, including the Achievements tab and the leave dialog.
 *
 * Load order (A8): after home.css and before accessibility.css. Classic rules
 * in style.css and game.css restyle moved elements under body.is-touch,
 * (max-width: 800px), (max-width: 800px), (max-height: 599px) and the touch
 * full screen classes; the overrides below state the room's own value for
 * every such property, unconditionally, so every layout gets the room value.
 *
 * Containing blocks (A9): nothing that is an ancestor of the dock, the edge
 * tabs or the stage's top corner overlays sets transform, translate, rotate,
 * scale, perspective, filter, backdrop-filter, contain, container-type,
 * container, content-visibility or will-change. The one exception is the
 * well, a size container for picture sizing (L4): nothing inside it is
 * position: fixed in room mode (L11). game-room-css.test.js enforces both.
 *
 * Geometry: room-edges.js (Task 17) measures the stage, dock, pad and site
 * chrome and writes the --room-chrome-h, --room-stage-*, --room-dock-h and
 * --room-pad-h values on body.game-room-active from a room-owned <style>.
 * The defaults below hold until the first measurement.
 *
 * Type (TH3): Press Start 2P only at 8, 16 and 24px; the reading face at 11px
 * (meta) and 13px (body and control labels); weights 400 and 600 only.
 * Motion (TH5): every animation and transition sits in a
 * prefers-reduced-motion: no-preference block.
 * Indicators (TH2, ruling D-6): the selected tab, badges and the Controls dot
 * use --focus-ring, never the raw accent.
 */

/* ── 1. Tokens ─────────────────────────────────────────────────────────── */

body.game-room-active {
  --room-safe-top: env(safe-area-inset-top, 0px);
  --room-safe-right: env(safe-area-inset-right, 0px);
  --room-safe-bottom: env(safe-area-inset-bottom, 0px);
  --room-safe-left: env(safe-area-inset-left, 0px);
  --room-rail-w: clamp(280px, 19vw, 320px);
  --room-duo-w: clamp(296px, 34vw, 340px);
  --room-strip-w: 56px;
  --room-target: 24px;
  --room-edge-h: 24px;
  --room-edge-w: 56px;
  --room-topbar-h: 54px;
  --room-fs-meta: 11px;
  --room-fs-body: 13px;
  --room-px-tag: 8px;
  --room-px-title: 16px;
  --room-px-big: 24px;
  --room-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --room-chrome-h: 48px;
  --room-pad-h: 0px;
  --room-dock-h: 70px;
  --room-stage-top: 48px;
  --room-stage-left: 0px;
  --room-stage-right: 0px;
  --room-stage-bottom: 70px;
}

@media (pointer: coarse), (max-width: 640px) {
  body.game-room-active {
    --room-target: 44px;
    --room-edge-h: 44px;
  }
}

/* ── 2. Page frame (L10) ───────────────────────────────────────────────── */

/* The page never scrolls during play; the room fills the space below the
   visible site chrome (header, and the verify banner when shown). */
body.game-room-active {
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  overscroll-behavior: none;
}

body.game-room-active #app-main {
  flex: 1 1 auto;
  min-height: 0;
}

/* The locked frame: #screen-game is the room's only scroller, with nothing
   to scroll while the room fits, and a fallback that keeps every control
   reachable should a rail layout ever outgrow it. Where the room's minimum
   content can exceed the viewport (320x256 at 400% zoom, and high zoom in
   general), section 2b's reflow frame lifts the page's scroll lock instead
   (L10). */
body.game-room-active #screen-game.game-room {
  position: static;
  inset: auto;
  z-index: auto;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  grid-template-columns: none;
  grid-template-rows: none;
  width: 100%;
  height: auto;
  min-height: 0;
  max-height: none;
  padding: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  font-synthesis-weight: none;
}

/* The site header stays during play (H1). The header tab hides it through
   the room's own marker class on its shell (ruling D-6; always in the
   fullscreen layout, L9), so the header's classic .hidden class stays
   _showScreen's alone. */
body.game-room-active:has(.room-shell.room-header-hidden) #site-header {
  display: none;
}

/* chat-open is never set in room mode (CH3); neutralize it anyway. */
body.game-room-active #screen-game.game-room.chat-open {
  display: flex;
  grid-template-columns: none;
  padding: 0;
}

/* The touch full screen modes keep today's fixed full-viewport screen. */
body.game-room-active #screen-game.game-room[data-room-layout="fullscreen"] {
  position: fixed;
  inset: 0;
  z-index: 9000;
  overflow: hidden;
  background: #000;
}

/* Classic elements hidden in room mode ("What moves where"). */
#screen-game.game-room #chat-sidebar-backdrop,
#screen-game.game-room #game-controls-hint,
#screen-game.game-room .below-canvas-links,
#screen-game.game-room #stat-cheevos,
#screen-game.game-room #cheevo-panel,
#screen-game.game-room #btn-chat {
  display: none !important;
}

/* The hidden attribute always hides inside the room: style.css only handles
   .hidden, and a room display rule would otherwise beat the UA's [hidden]. */
#screen-game.game-room [hidden],
body.game-room-active .room-layer-host [hidden] {
  display: none !important;
}

/* ── 2b. Reflow (L10) ──────────────────────────────────────────────────── */

/* The room exactly fills the viewport and the page does not scroll, except
   when the room's minimum content is taller than the viewport: then the
   page's scroll lock lifts and the room stacks, so every control stays
   reachable. The stacked layouts without the sheet (portrait and phone: the
   stage, the dock, then panels of at least 280px or 200px) are where that
   happens, and where 320x256 at 400% zoom lands (a phone layout whose stack
   needs about 640px). In them the frame grows instead of clipping: <body>,
   #app-main, #screen-game and the shell size to at least the viewport and
   to the room's minimum content, the panel row grows to fill whatever is
   left, and the page scrolls, only when the room is taller than the
   viewport, because the room otherwise fills it exactly. contain: size on
   the panels keeps their content (a long chat) from sizing the room; it
   scrolls inside the panel. overflow-y: scroll keeps the layout viewport's
   width steady, so L1 never flips layouts as a classic scrollbar comes and
   goes (overlay scrollbars on iOS, Android and macOS show nothing). The
   header scrolls away with the room instead of covering it, and the
   overlays placed over the stage scroll with it. The rail layouts, sheet
   mode and the fullscreen layout keep the locked frame; landscape stacks at
   359px tall or less, below. Only sizes, grid, overflow, the rails' size
   containment and the header's and overlays' position change (A9: no
   protected surface gains a containing block). */
body.game-room-active:has(#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"]),
body.game-room-active:has(#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"]) {
  height: auto;
  min-height: 100dvh;
  overflow-x: hidden;
  overflow-y: scroll;
}

body.game-room-active:has(#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"]) #app-main,
body.game-room-active:has(#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"]) #app-main {
  flex: 1 0 auto;
}

body.game-room-active:has(#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"]) #site-header,
body.game-room-active:has(#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"]) #site-header {
  position: relative;
}

body.game-room-active #screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"],
body.game-room-active #screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] {
  flex: 1 0 auto;
}

#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"] .room-shell,
#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .room-shell {
  flex: 1 0 auto;
}

/* The phone panel folded to its tab bar keeps its natural height. */
#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"] .room-shell:not([data-left="folded"]) .room-rail-left,
#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .room-rail {
  contain: size;
}

/* L11 while the page scrolls: the body-level overlays section 15 places
   over the stage scroll with it, so none stays over the panels. Task 17
   measures the stage as at the top of the page, which is where an absolute
   box sits: no ancestor of these <body> children is positioned, so their
   containing block is the initial one. The C64-anchored disk picker keeps
   the placement its script gives it. */
body.game-room-active:has(#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"]) :is(#chat-panel-fab, #clip-toast, .play-invite-toast, #ghost-race, #replay-hud, #cheatsheet, #disk-picker:not(.c64-anchored)),
body.game-room-active:has(#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"]) :is(#chat-panel-fab, #clip-toast, .play-invite-toast, #ghost-race, #replay-hud, #cheatsheet, #disk-picker:not(.c64-anchored)) {
  position: absolute;
}

/* Landscape at 359px tall or less: the stage needs about 306px for the
   header, the edge tabs and three dock rows at 640px wide before any
   picture, so the rail stacks under the stage, as in phone, and the frame
   grows the same way. Desktop needs 600px, so it never reflows; touch
   landscape this short is the fullscreen layout. */
@media (max-height: 359px) {
  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"]) {
    height: auto;
    min-height: 100dvh;
    overflow-x: hidden;
    overflow-y: scroll;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"]) #app-main {
    flex: 1 0 auto;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"]) #site-header {
    position: relative;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"]) :is(#chat-panel-fab, #clip-toast, .play-invite-toast, #ghost-race, #replay-hud, #cheatsheet, #disk-picker:not(.c64-anchored)) {
    position: absolute;
  }

  body.game-room-active #screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"] {
    flex: 1 0 auto;
  }

  #screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"] .room-shell {
    --room-panels-min: 200px;
    flex: 1 0 auto;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(200px, 1fr);
    grid-template-areas: "stage" "left";
  }

  #screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"] .room-rail-left {
    contain: size;
    border-top: 1px solid var(--border);
    border-left: 0;
  }

  /* The picture takes its height from its width here, as in the other
     stacked layouts. */
  #screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"] .room-well {
    container-type: normal;
  }

  #screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"] .room-well > .game-main {
    height: auto;
  }

  #screen-game.game-room[data-room-layout="landscape"][data-room-sheet="off"] .game-main > #canvas-container:not(:fullscreen) {
    width: min(100%, max(60%, calc((100dvh - var(--room-stack-reserve)) * var(--game-ar-w) / var(--game-ar-h)))) !important;
  }
}

/* ── 3. Shell grid (L5) ────────────────────────────────────────────────── */

/* The shell fills #screen-game exactly. In the stacked layouts a grid that
   needs more than that overflows it, and #screen-game scrolls (L10). */
#screen-game.game-room .room-shell {
  --room-left-w: var(--room-rail-w);
  --room-right-w: var(--room-rail-w);
  --room-panels-min: 0px;
  --room-well-gap: 6px;
  --room-stack-reserve: calc(var(--room-stage-top) + 2 * (var(--room-edge-h) + var(--room-well-gap)) + var(--room-dock-h) + var(--room-panels-min));
  display: grid;
  flex: 1 1 0;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "stage";
  min-width: 0;
  min-height: 0;
  padding: 0 0 var(--room-pad-h);
  background: var(--stage);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  line-height: 1.5;
}

/* While the header is hidden the room meets the top edge: start below the
   notch cover (body::after in style.css) (L13). */
#screen-game.game-room .room-shell.room-header-hidden {
  padding-top: var(--room-safe-top);
}

#screen-game.game-room[data-room-layout="desktop"] .room-shell {
  grid-template-columns: var(--room-left-w) minmax(0, 1fr) var(--room-right-w);
  grid-template-areas: "left stage right";
}

#screen-game.game-room[data-room-layout="desktop"] .room-shell[data-left="collapsed"] {
  --room-left-w: var(--room-strip-w);
}

#screen-game.game-room[data-room-layout="desktop"] .room-shell[data-right="collapsed"] {
  --room-right-w: var(--room-strip-w);
}

#screen-game.game-room[data-room-layout="landscape"] .room-shell {
  --room-left-w: var(--room-duo-w);
  grid-template-columns: minmax(0, 1fr) var(--room-left-w);
  grid-template-areas: "stage left";
}

#screen-game.game-room[data-room-layout="landscape"] .room-shell[data-left="collapsed"] {
  --room-left-w: var(--room-strip-w);
}

#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .room-shell {
  --room-left-w: minmax(0, 1fr);
  --room-right-w: minmax(0, 1fr);
  --room-panels-min: 280px;
  grid-template-columns: var(--room-left-w) var(--room-right-w);
  grid-template-rows: auto minmax(280px, 1fr);
  grid-template-areas: "stage stage" "left right";
}

#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .room-shell[data-left="collapsed"] {
  --room-left-w: var(--room-strip-w);
}

#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .room-shell[data-right="collapsed"] {
  --room-right-w: var(--room-strip-w);
}

#screen-game.game-room[data-room-layout="phone"] .room-shell {
  --room-well-gap: 0px;
}

#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"] .room-shell {
  --room-panels-min: 200px;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(200px, 1fr);
  grid-template-areas: "stage" "left";
}

/* The phone panel folds down to its tab bar (L6). */
#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"] .room-shell[data-left="folded"] {
  --room-panels-min: 44px;
  grid-template-rows: auto auto;
  align-content: start;
}

/* Sheet mode and the fullscreen layout: the stage only (L8, L9). */
#screen-game.game-room[data-room-sheet="on"] .room-shell,
#screen-game.game-room[data-room-layout="fullscreen"] .room-shell {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "stage";
}

#screen-game.game-room[data-room-layout="fullscreen"] .room-shell {
  padding: 0;
  background: #000;
}

/* Fallbacks for the .hidden state room-edges.js applies to absent rails. */
#screen-game.game-room[data-room-sheet="on"] .room-rail,
#screen-game.game-room[data-room-layout="fullscreen"] .room-rail,
#screen-game.game-room[data-room-layout="landscape"] .room-rail-right,
#screen-game.game-room[data-room-layout="phone"] .room-rail-right {
  display: none;
}

/* ── 4. Stage, well and picture (L4) ───────────────────────────────────── */

#screen-game.game-room .room-stage {
  grid-area: stage;
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background:
    radial-gradient(ellipse 75% 65% at 50% 45%, transparent 40%, color-mix(in srgb, #000 28%, transparent) 100%),
    var(--stage);
}

#screen-game.game-room .room-stage:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: -3px;
}

#screen-game.game-room[data-room-layout="fullscreen"] .room-stage {
  background: #000;
}

/* The well reserves the edge tabs' height above and below the picture. */
#screen-game.game-room .room-well {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 0;
  padding: calc(var(--room-edge-h) + var(--room-well-gap)) 16px;
}

#screen-game.game-room[data-room-layout="landscape"] .room-well {
  padding-right: 8px;
  padding-left: 8px;
}

/* Phones: the picture spans the viewport width (L14). */
#screen-game.game-room[data-room-layout="phone"] .room-well {
  padding-right: 0;
  padding-left: 0;
}

/* Phone sheet mode with the dock showing: the toolbar tab is the dock row's
   last control (ruling D-6), so the well reserves no band under the picture
   and a 4:3 picture spans the width at 375x548 and 360x560 (V5). */
#screen-game.game-room[data-room-layout="phone"][data-room-sheet="on"] .room-shell[data-toolbar="shown"] .room-well {
  padding-bottom: 0;
}

#screen-game.game-room[data-room-layout="fullscreen"] .room-well {
  padding: 0;
}

/* A size container wherever the stage's height comes from the grid; the
   stacked layouts without the sheet size the picture from the viewport. */
#screen-game.game-room[data-room-layout="desktop"] .room-well,
#screen-game.game-room[data-room-layout="landscape"] .room-well,
#screen-game.game-room[data-room-layout="fullscreen"] .room-well,
#screen-game.game-room[data-room-sheet="on"] .room-well {
  container-type: size;
}

#screen-game.game-room .room-well > .game-main {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: auto;
  min-width: 0;
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: visible;
}

#screen-game.game-room[data-room-layout="desktop"] .room-well > .game-main,
#screen-game.game-room[data-room-layout="landscape"] .room-well > .game-main,
#screen-game.game-room[data-room-layout="fullscreen"] .room-well > .game-main,
#screen-game.game-room[data-room-sheet="on"] .room-well > .game-main {
  height: 100%;
}

/* The picture: the system's aspect ratio (inline --game-ar-w/--game-ar-h),
   the largest size that fits. !important beats the classic touch and full
   screen size rules, whatever their specificity. Native full screen
   (:fullscreen) keeps today's rules (L9). Nothing here animates. */
#screen-game.game-room .game-main > #canvas-container:not(:fullscreen) {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: min(100cqw, calc(100cqh * var(--game-ar-w) / var(--game-ar-h))) !important;
  height: auto !important;
  /* No content-based minimum: the canvas's own pixel ratio must never
     stretch the box (L4). */
  min-width: 0 !important;
  min-height: 0 !important;
  max-width: 100% !important;
  max-height: none !important;
  aspect-ratio: var(--game-ar-w) / var(--game-ar-h) !important;
  margin: 0;
  border: 0 !important;
  border-radius: 2px;
  background: #000;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 14%, transparent), 0 30px 70px -26px rgba(0, 0, 0, 0.9);
}

/* Stacked without the sheet: as wide as the well, but short enough to leave
   the panels their minimum; never under 60% of the well (the room scrolls
   in #screen-game when even that does not fit, L10). */
#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .game-main > #canvas-container:not(:fullscreen),
#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"] .game-main > #canvas-container:not(:fullscreen) {
  width: min(100%, max(60%, calc((100dvh - var(--room-stack-reserve)) * var(--game-ar-w) / var(--game-ar-h)))) !important;
}

#screen-game.game-room[data-room-layout="fullscreen"] .game-main > #canvas-container:not(:fullscreen) {
  border-radius: 0;
  box-shadow: none;
}

/* object-fit: cover in every layout: the container is system-shaped, so GB,
   GBC and GBA pictures are not letterboxed inside their box. */
#screen-game.game-room #canvas-container:not(:fullscreen) #nes-canvas {
  width: 100% !important;
  height: 100% !important;
  max-width: none;
  max-height: none;
  object-fit: cover;
}

#screen-game.game-room #canvas-container:not(:fullscreen) #guest-video {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
}

/* Side-by-side race stage, sized inside the well (L4). */
#screen-game.game-room .game-main > #sbs-stage {
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 8px;
}

#screen-game.game-room .sbs-stage.sbs-layout-side .sbs-panel-media {
  max-height: calc(100cqh - 48px);
}

#screen-game.game-room .sbs-stage.sbs-layout-topbottom .sbs-panel-media {
  height: min(calc(50cqh - 40px), 69cqw);
}

#screen-game.game-room .sbs-stage.sbs-layout-pip .sbs-panel-self .sbs-panel-media {
  max-height: calc(100cqh - 56px);
}

/* ── 5. Overlays inside .game-main: absolute against the stage (L11) ───── */

/* Round 1 (b12): these rules name the classic classes, so every element that
   carries one (today #sys-status, #c64-drive-control-wrap, #hud, the three
   prompts, #rewind-indicator and the idle prompt) gets the room's values, and
   the #room-stage id keeps them above the classic chat-open rules. */
#screen-game.game-room #room-stage .game-main > .sys-status {
  position: absolute;
  top: 8px;
  right: auto;
  bottom: auto;
  left: 8px;
  z-index: 3;
  margin: 0;
}

#screen-game.game-room #room-stage .game-main > .c64-drive-control-wrap {
  position: absolute;
  top: 44px;
  right: auto;
  bottom: auto;
  left: 8px;
  z-index: 3;
}

#screen-game.game-room #room-stage .game-main > .hud,
#screen-game.game-room #room-stage .game-main > .hud-parity {
  position: absolute;
  top: 8px;
  right: 8px;
  bottom: auto;
  left: auto;
  z-index: 3;
  width: auto;
  justify-content: flex-start;
  gap: 12px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

#screen-game.game-room .game-main > #chat {
  position: absolute;
  top: auto;
  right: auto;
  bottom: 12px;
  left: 12px;
  z-index: 3;
  width: min(280px, calc(100% - 24px));
}

/* Centered prompts, centered without transforms: every element with a classic
   prompt class (#swap-prompt and #upgrade-prompt carry .swap-prompt,
   #game-change-prompt carries .rematch-prompt). */
#screen-game.game-room #room-stage .game-main > .swap-prompt,
#screen-game.game-room #room-stage .game-main > .rematch-prompt,
#screen-game.game-room #room-stage .game-main > .rewind-indicator {
  position: absolute;
  top: 12px;
  right: 0;
  bottom: auto;
  left: 0;
  z-index: 4;
  width: max-content;
  max-width: calc(100% - 24px);
  margin: 0 auto;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  padding: 8px 16px;
  transform: none;
  font-size: var(--room-fs-body);
}

#screen-game.game-room #room-stage .game-main > .rewind-indicator {
  animation: none;
  font-size: var(--room-px-tag);
}

/* The idle prompt carries the classic .exit-confirm; #exit-confirm itself
   lives in the layer host in room mode (section 14), so inside .game-main
   this names the idle prompt and any later element of that class. */
#screen-game.game-room #room-stage .game-main > .exit-confirm {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: max-content;
  height: max-content;
  max-width: calc(100% - 24px);
  margin: auto;
  transform: none;
  font-size: var(--room-fs-body);
}

/* Classic pixel text inside the stage, brought onto the type scale (TH3). */
#screen-game.game-room .game-main .hud-label,
#screen-game.game-room .game-main .parity-toggle-label,
#screen-game.game-room .game-main .c64-drive-id,
#screen-game.game-room .game-main .sbs-panel-label {
  font-size: var(--room-px-tag);
}

#screen-game.game-room .game-main .hud-value {
  font-size: var(--room-fs-body);
}

#screen-game.game-room .game-main .c64-drive-state {
  font-size: var(--room-fs-meta);
}

/* ── 6. Edge tabs (H2, H3) ─────────────────────────────────────────────── */

/* Both tabs sit in the stage's flex column: the header tab first, the
   toolbar tab between the well and the dock. A negative margin overlays the
   band the well reserves, so neither tab covers the picture. */
#screen-game.game-room .room-edge {
  position: relative;
  z-index: 2;
  display: grid;
  flex: none;
  align-self: center;
  place-items: center;
  width: var(--room-edge-w);
  min-width: var(--room-edge-w);
  height: var(--room-edge-h);
  min-height: var(--room-edge-h);
  margin: 0;
  padding: 0;
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
}

#screen-game.game-room .room-edge svg {
  width: 14px;
  height: 14px;
}

#screen-game.game-room .room-header-tab {
  margin-bottom: calc(-1 * var(--room-edge-h));
  border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--bg);
}

#screen-game.game-room .room-toolbar-tab {
  margin-top: calc(-1 * var(--room-edge-h));
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--surface);
}

/* Phone sheet mode while the dock shows (L14, H3, ruling D-6): room-edges.js
   moves the toolbar tab into the dock after #game-controls, so it is the dock
   row's last control and the row keeps the full width. */
#screen-game.game-room .room-dock > .room-toolbar-tab {
  align-self: center;
  width: var(--room-edge-h);
  min-width: var(--room-edge-h);
  margin: 0 calc(4px + var(--room-safe-right)) 0 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

/* Full screen: the dock overlays the top edge; the toolbar tab hangs under
   it, or at the top edge while the dock is hidden (L9). */
#screen-game.game-room[data-room-layout="fullscreen"] .room-toolbar-tab {
  position: absolute;
  top: calc(var(--room-safe-top) + var(--room-topbar-h));
  right: 0;
  left: 0;
  z-index: 4;
  margin: 0 auto;
  border-top: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
}

#screen-game.game-room[data-room-layout="fullscreen"]:has(#game-controls.tap-hidden) .room-toolbar-tab {
  top: var(--room-safe-top);
}

#screen-game.game-room #room-header-tab:focus-visible,
#screen-game.game-room #room-toolbar-tab:focus-visible {
  outline-offset: -4px !important;
}

/* ── 7. Dock and toolbar (T1, T2, L14) ─────────────────────────────────── */

#screen-game.game-room .room-dock {
  display: flex;
  flex: none;
  align-items: stretch;
  justify-content: center;
  min-width: 0;
  padding: 8px 16px 10px;
  padding-bottom: calc(10px + max(0px, var(--room-safe-bottom) - var(--room-pad-h)));
  background: var(--surface);
  border-top: 1px solid var(--border);
}

#screen-game.game-room[data-room-layout="portrait"][data-room-sheet="off"] .room-dock,
#screen-game.game-room[data-room-layout="phone"][data-room-sheet="off"] .room-dock {
  padding: 10px 12px;
}

/* #game-controls (the dock strip, Task 19): every classic fixed-bar, top-bar,
   dock-hidden and tap-hidden property gets the room's value (A8). */
#screen-game.game-room #game-controls {
  position: static;
  inset: auto;
  z-index: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 2px;
  box-sizing: border-box;
  width: auto;
  max-width: 100%;
  height: auto;
  margin: 0;
  padding: 0;
  overflow: visible;
  background: transparent;
  border: 0;
  box-shadow: none;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  transition: none;
  scrollbar-width: none;
}

#screen-game.game-room #game-controls::-webkit-scrollbar {
  display: none;
}

#screen-game.game-room #game-controls.dock-hidden,
#screen-game.game-room #game-controls.tap-hidden {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}

#screen-game.game-room #game-controls > #game-more-wrap {
  position: relative;
  display: inline-flex;
  flex: none;
}

#screen-game.game-room #room-dock .room-dock-btn {
  position: relative;
  display: inline-flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  box-sizing: border-box;
  width: auto;
  height: auto;
  min-width: max(var(--room-target), 60px);
  min-height: max(var(--room-target), 52px);
  margin: 0;
  padding: 6px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  box-shadow: none;
  opacity: 1;
  font-family: var(--font-mono);
  font-size: 0;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  cursor: pointer;
  transition: none;
}

/* Tap and press never leave a toggle looking pressed (T2). */
#screen-game.game-room #room-dock .room-dock-btn:hover,
#screen-game.game-room #room-dock .room-dock-btn:active {
  background: transparent;
  border-color: transparent;
  transform: none;
}

#screen-game.game-room #room-dock .room-dock-icon {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 20px;
  height: 20px;
  color: var(--text-dim);
}

#screen-game.game-room #room-dock .room-dock-icon svg {
  width: 20px;
  height: 20px;
}

#screen-game.game-room #room-dock .room-dock-label {
  display: block;
  font-size: var(--room-fs-body);
  line-height: 1.2;
}

/* Decoration never replaces existing children (A5): the classic glyph spans
   stay in place, hidden. */
#screen-game.game-room #game-controls .gm-icon,
#screen-game.game-room #game-controls .gm-label,
#screen-game.game-room #game-controls .c64-guide-toolbar-key,
#screen-game.game-room #game-controls .c64-guide-toolbar-label {
  display: none;
}

#screen-game.game-room #room-dock .room-dock-btn[aria-pressed="true"] .room-dock-icon {
  color: var(--warning-ink);
}

#screen-game.game-room #game-controls #btn-clip .room-dock-icon {
  color: var(--accent2-ink);
}

#screen-game.game-room #game-controls #btn-replay .room-dock-icon {
  color: var(--replay-ink);
}

/* The recording dot is a persistent indicator: static in the room (TH5). */
#screen-game.game-room #game-controls .clip-rec-dot {
  top: 4px;
  right: 6px;
  background: var(--danger);
  animation: none;
}

#screen-game.game-room #game-controls #btn-voice {
  opacity: 1;
  transition: none;
}

/* The Panels button's unread count and Controls dot (CH5, K8). */
#screen-game.game-room #game-controls #btn-room-panels .room-dock-badge {
  position: absolute;
  top: 2px;
  right: 4px;
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--focus-ring);
  color: var(--on-accent);
  font-size: var(--room-fs-meta);
  font-weight: 600;
  line-height: 1;
}

#screen-game.game-room #game-controls #btn-room-panels .room-dock-dot {
  position: absolute;
  top: 6px;
  right: 10px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--focus-ring);
  box-shadow: 0 0 0 2px var(--surface);
}

#screen-game.game-room #game-controls .room-dock-sep {
  flex: none;
  align-self: center;
  width: 1px;
  height: 32px;
  margin: 0 6px;
  background: var(--border);
}

#screen-game.game-room #game-controls #c64-runtime-controls {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 8px;
  min-height: max(var(--room-target), 52px);
  padding: 0 8px;
}

#screen-game.game-room #game-controls .c64-speed-label {
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--room-fs-meta);
  letter-spacing: 0;
  text-transform: none;
}

#screen-game.game-room #game-controls #c64-speed-select {
  min-width: var(--room-target);
  min-height: max(var(--room-target), 32px);
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
}

#screen-game.game-room #game-controls .c64-port-control {
  height: auto;
  min-height: 32px;
}

/* The 44px buttons end in the pill's half-circle cap. This inset keeps the last
   button's corners inside the curve instead of crossing the pill's outline. */
@media (pointer: coarse), (max-width: 640px) {
  #screen-game.game-room #game-controls .c64-port-control {
    padding-inline-end: calc(var(--room-target) / 2 - 4px);
  }
}

#screen-game.game-room #game-controls .c64-port-btn {
  min-width: max(var(--room-target), 32px);
  min-height: max(var(--room-target), 32px);
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
}

#screen-game.game-room #game-controls .c64-port-btn[aria-pressed="true"] {
  border-color: var(--focus-ring);
  background: var(--focus-ring);
  color: var(--on-accent);
}

/* Icon-only dock: the "Speed" and "Port" text hides visually; the controls keep their names. */
#screen-game.game-room #game-controls[data-room-dock-icons="on"] #c64-runtime-controls .c64-speed-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Icon-only dock (data-room-dock-icons="on"): Task 19 picks it only for a
   fine pointer when the labels do not fit; names then show as tooltips. */
#screen-game.game-room #game-controls[data-room-dock-icons="on"] .room-dock-btn {
  min-width: max(var(--room-target), 42px);
  min-height: max(var(--room-target), 42px);
  padding: 0 10px;
}

#screen-game.game-room #game-controls[data-room-dock-icons="on"] .room-dock-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Coarse targets: 44px controls with a visible 11px caption inside (T2,
   PL5). */
@media (pointer: coarse), (max-width: 640px) {
  #screen-game.game-room #room-dock .room-dock-btn {
    gap: 3px;
    min-width: 56px;
    min-height: 44px;
    padding: 3px 6px;
  }

  #screen-game.game-room #room-dock .room-dock-label {
    font-size: var(--room-fs-meta);
  }
}

/* Grid (data-room-dock="grid", phone without the pad): rows of four with
   Exit and More ending the last row (T2). */
#screen-game.game-room #game-controls[data-room-dock="grid"] {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
  width: 100%;
}

#screen-game.game-room #game-controls[data-room-dock="grid"] .room-dock-btn,
#screen-game.game-room #game-controls[data-room-dock="grid"] > #game-more-wrap,
#screen-game.game-room #game-controls[data-room-dock="grid"] > #c64-runtime-controls {
  width: 100%;
  min-width: 0;
}

#screen-game.game-room #game-controls[data-room-dock="grid"] > #c64-runtime-controls {
  grid-column: 1 / -1;
  flex-wrap: wrap;
  justify-content: center;
}

#screen-game.game-room #game-controls[data-room-dock="grid"] .room-dock-btn {
  border-color: var(--border);
  white-space: normal;
  text-align: center;
}

#screen-game.game-room #game-controls[data-room-dock="grid"] .room-dock-sep {
  display: none;
}

#screen-game.game-room #game-controls[data-room-dock="grid"] > #btn-exit {
  grid-column: 3;
}

#screen-game.game-room #game-controls[data-room-dock="grid"] > #game-more-wrap {
  grid-column: 4;
}

/* Scroll (data-room-dock="scroll"): one horizontally scrolling row; nothing
   moves to More (L14). The block padding keeps focus rings inside. */
#screen-game.game-room #game-controls[data-room-dock="scroll"] {
  flex: 1 1 auto;
  flex-wrap: nowrap;
  justify-content: flex-start;
  min-width: 0;
  padding: 6px 4px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
}

#screen-game.game-room[data-room-layout="phone"][data-room-sheet="on"] .room-dock {
  justify-content: flex-start;
  /* The scrolling row already pads its focus rings. Four extra pixels here
     leave the 375x548 NES well too short for a viewport-width 4:3 picture. */
  padding: 0;
}

#screen-game.game-room[data-room-layout="phone"][data-room-sheet="on"] #game-controls {
  padding: 6px 8px 6px calc(8px + var(--room-safe-left));
}

/* Keep Exit reachable while the remaining phone controls scroll. */
#screen-game.game-room #room-dock > .room-dock-exit-pinned {
  margin: 6px 0 6px calc(4px + var(--room-safe-left));
}

/* Full screen: the dock overlays the top edge, clear of the pad, and is
   revealed on tap or through the toolbar tab. While hidden it is
   visibility: hidden (room-edges.js adds inert); no transform (L9). */
#screen-game.game-room[data-room-layout="fullscreen"] .room-dock {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: 4;
  display: block;
  padding: 0;
  border: 0;
  background: transparent;
  pointer-events: none;
}

/* A bar of known height, so the toolbar tab can hang right under it. */
#screen-game.game-room[data-room-layout="fullscreen"] #game-controls {
  flex-wrap: nowrap;
  justify-content: flex-start;
  width: 100%;
  height: calc(var(--room-safe-top) + var(--room-topbar-h));
  padding: calc(4px + var(--room-safe-top)) calc(8px + var(--room-safe-right)) 4px calc(8px + var(--room-safe-left));
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  border-bottom: 1px solid var(--border);
  pointer-events: auto;
}

#screen-game.game-room[data-room-layout="fullscreen"] #room-dock .room-dock-btn {
  min-height: 44px;
}

#screen-game.game-room[data-room-layout="fullscreen"] #game-controls.tap-hidden {
  visibility: hidden;
}

/* ── 8. Rails, strips and collapse controls (L5, L6) ───────────────────── */

/* No overflow clip on the rail: focus rings at its edges stay visible. */
#screen-game.game-room .room-rail {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--surface);
}

#screen-game.game-room .room-rail-left {
  grid-area: left;
  border-right: 1px solid var(--border);
}

#screen-game.game-room .room-rail-right {
  grid-area: right;
  border-left: 1px solid var(--border);
}

#screen-game.game-room[data-room-layout="landscape"] .room-rail-left {
  border-right: 0;
  border-left: 1px solid var(--border);
}

#screen-game.game-room[data-room-layout="portrait"] .room-rail,
#screen-game.game-room[data-room-layout="phone"] .room-rail {
  border-top: 1px solid var(--border);
}

#screen-game.game-room[data-room-layout="phone"] .room-rail-left {
  border-right: 0;
}

#screen-game.game-room .room-rail-head {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 44px;
  padding: 0 6px 0 16px;
  border-bottom: 1px solid var(--border);
}

#screen-game.game-room .room-rail-title {
  margin: 0;
  color: var(--text);
  font-size: var(--room-fs-body);
  font-weight: 600;
}

/* Off desktop the tab bar heads the left rail; its h2 stays for screen
   readers (room-edges.js hides the head's collapse button there). */
#screen-game.game-room:not([data-room-layout="desktop"]) .room-rail-left > .room-rail-head {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

#screen-game.game-room .room-rail-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}

#screen-game.game-room .room-rail-right > .room-rail-body {
  display: block;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: max(0px, var(--room-safe-bottom) - var(--room-pad-h));
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

#screen-game.game-room .room-strip {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-height: 0;
  padding: 8px 0;
  padding-bottom: calc(8px + max(0px, var(--room-safe-bottom) - var(--room-pad-h)));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

/* Safari 17 ignores scrollbar-width (PL1): hide the strip's scrollbar there too. */
#screen-game.game-room .room-strip::-webkit-scrollbar {
  display: none;
}

#screen-game.game-room .room-strip-sep {
  flex: none;
  width: 24px;
  height: 1px;
  margin: 4px 0;
  background: var(--border);
}

/* The right strip's separator shows only above a visible quick capture
   button (Task 26 shows and hides them). */
#screen-game.game-room .room-strip-right > .room-strip-sep:not(:has(~ :not(.hidden))) {
  display: none;
}

#screen-game.game-room .room-strip-btn,
#screen-game.game-room .room-collapse {
  position: relative;
  display: grid;
  flex: none;
  place-items: center;
  width: 40px;
  height: 40px;
  min-width: var(--room-target);
  min-height: var(--room-target);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
}

#screen-game.game-room .room-collapse {
  width: 36px;
  height: 36px;
}

#screen-game.game-room .room-strip-btn svg,
#screen-game.game-room .room-collapse svg {
  width: 18px;
  height: 18px;
}

/* The chat strip button's unread count (Task 17) sits on its corner. */
#screen-game.game-room .room-strip-btn .room-tab-badge {
  position: absolute;
  top: 2px;
  right: 0;
  margin: 0;
}

/* ── 9. Game card (C1 to C3; classes per ruling D-5) ───────────────────── */

body.game-room-active .room-game-card {
  display: grid;
  flex: none;
  grid-template-columns: 64px minmax(0, 1fr);
  grid-template-areas: "art text" "link link";
  align-items: center;
  column-gap: 14px;
  padding: 16px 16px 0;
}

body.game-room-active .room-game-art {
  --home-fs-tag: 8px;
  --home-fs-title: 8px;
  grid-area: art;
  position: relative;
  display: block;
  width: 64px;
  height: 64px;
  overflow: hidden;
  border-radius: 4px;
  box-shadow: 0 0 0 1px var(--border), 0 8px 18px -6px rgba(0, 0, 0, 0.6);
}

body.game-room-active .room-game-cover,
body.game-room-active .room-game-label,
body.game-room-active .room-game-label > .home-cover-label {
  display: block;
  width: 100%;
  height: 100%;
}

body.game-room-active .room-game-cover {
  object-fit: cover;
}

body.game-room-active .room-game-label > .home-cover-label {
  display: flex;
  box-sizing: border-box;
}

body.game-room-active .room-game-text {
  grid-area: text;
  min-width: 0;
}

body.game-room-active .room-game-card-title {
  margin: 0;
  color: var(--text);
  font-family: var(--font-pixel);
  font-size: var(--room-px-title);
  font-weight: 400;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

body.game-room-active .room-game-sys {
  margin: 6px 0 0;
  color: var(--text);
}

body.game-room-active .room-game-session {
  margin: 0;
}

body.game-room-active .room-game-mode {
  color: var(--accent2-ink);
  font-size: var(--room-fs-meta);
  font-weight: 600;
}

body.game-room-active .room-game-link {
  grid-area: link;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: max(var(--room-target), 44px);
  margin: 16px -16px 0;
  padding: 0 14px 0 16px;
  border-top: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
}

/* The mock's chevron, drawn with borders (decorative). */
body.game-room-active .room-game-link::after {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-top: 2px solid var(--text-dim);
  border-right: 2px solid var(--text-dim);
  rotate: 45deg;
}

/* One row at the top of the rail in landscape and portrait, and in the More
   menu (C1 to C3, M1). */
#screen-game.game-room[data-room-layout="landscape"] .room-game-card,
#screen-game.game-room[data-room-layout="portrait"] .room-game-card,
body.game-room-active .room-layer-host .room-game-card {
  grid-template-columns: 40px minmax(0, 1fr);
  grid-template-areas: "art text" "link link";
  column-gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}

#screen-game.game-room[data-room-layout="landscape"] .room-game-art,
#screen-game.game-room[data-room-layout="portrait"] .room-game-art,
body.game-room-active .room-layer-host .room-game-art {
  width: 40px;
  height: 40px;
}

#screen-game.game-room[data-room-layout="landscape"] .room-game-link,
#screen-game.game-room[data-room-layout="portrait"] .room-game-link,
body.game-room-active .room-layer-host .room-game-link {
  margin: 8px -12px -10px;
  padding: 0 14px 0 12px;
}

/* Score rankings share the right rail with captures; compact layouts move
   the same panel into the main tab strip or Panels sheet. */
body.game-room-active .room-score-tabs {
  flex: none;
  border-bottom: 1px solid var(--border);
}
body.game-room-active .room-leaderboard { min-width: 0; padding: 12px; }
body.game-room-active .room-score-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
body.game-room-active .room-score-title { margin: 0; font-family: var(--font-mono); font-size: var(--room-fs-body); font-weight: 600; }
body.game-room-active .room-score-retry { min-height: 44px; padding: 6px 10px; font: inherit; }
body.game-room-active .room-score-status { font-size: var(--room-fs-body); color: var(--text-dim); }
body.game-room-active .room-score-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: var(--room-fs-body); }
body.game-room-active .room-score-table th,
body.game-room-active .room-score-table td { padding: 10px 4px; text-align: left; border-bottom: 1px solid var(--border); }
body.game-room-active .room-score-table th:first-child { width: 44px; }
body.game-room-active .room-score-table th:last-child { width: 88px; }
body.game-room-active .room-score-table th:nth-child(2) { padding-left: 36px; }
body.game-room-active .room-score-person { display: flex; align-items: center; gap: 8px; min-width: 0; }
body.game-room-active .room-score-avatar { flex: none; width: 24px; height: 24px; }
body.game-room-active .room-score-name { min-width: 0; overflow-wrap: anywhere; }
body.game-room-active .room-score-row-self { background: var(--surface2); color: var(--text); box-shadow: inset 2px 0 var(--focus-ring); }
body.game-room-active .room-score-row-self .room-score-rank { color: var(--accent-ink); font-weight: 600; }
body.game-room-active .room-score-table th:last-child,
body.game-room-active .room-score-table .room-score-value { text-align: right; font-variant-numeric: tabular-nums; }
body.game-room-active .room-score-tab:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ── 10. Tabs and panels (TB1, X1) ─────────────────────────────────────── */

body.game-room-active .room-tabbar {
  display: flex;
  flex: none;
  align-items: stretch;
  min-width: 0;
  border-bottom: 1px solid var(--border);
}

#screen-game.game-room[data-room-layout="desktop"] .room-tabbar {
  border-top: 1px solid var(--border);
}

body.game-room-active .room-tabs {
  display: flex;
  flex: 1 1 auto;
  gap: 2px;
  min-width: 0;
  padding: 0 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

body.game-room-active .room-tabs::-webkit-scrollbar {
  display: none;
}

body.game-room-active .room-tab {
  position: relative;
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 6px;
  min-width: var(--room-target);
  min-height: max(var(--room-target), 44px);
  margin: 0;
  padding: 0 10px;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

body.game-room-active .room-tab-label {
  display: inline;
}

/* The unread count on the Chat tab (Task 20) and on the chat strip button
   (Task 17): a ring-token badge (TH2, ruling D-6). */
body.game-room-active .room-tab-badge {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--focus-ring);
  color: var(--on-accent);
  font-size: var(--room-fs-meta);
  font-weight: 600;
  line-height: 1;
}

body.game-room-active .room-tab[aria-selected="true"] {
  color: var(--text);
}

/* The selected tab's indicator uses the ring token (TH2, ruling D-6). */
body.game-room-active .room-tab[aria-selected="true"]::after {
  content: "";
  position: absolute;
  right: 8px;
  bottom: -1px;
  left: 8px;
  height: 2px;
  background: var(--focus-ring);
  box-shadow: 0 0 10px color-mix(in srgb, var(--focus-ring) 60%, transparent);
}

body.game-room-active .room-tabbar > .room-collapse {
  align-self: center;
  margin: 0 4px;
}

body.game-room-active .room-panels {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}

body.game-room-active .room-panel {
  flex: 1 1 auto;
  min-height: 0;
  padding: 16px;
  padding-bottom: calc(16px + max(0px, var(--room-safe-bottom) - var(--room-pad-h)));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* Chat (Task 23), Controls (Task 25) and Clips & Replays (Task 26) pad their
   own content; the panel keeps only the bottom safe area. */
body.game-room-active .room-panel-chat {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

body.game-room-active .room-panel-controls,
body.game-room-active .room-panel-clips {
  padding: 0 0 max(0px, var(--room-safe-bottom) - var(--room-pad-h));
}

/* Inside the panels sheet the sheet carries the safe-area padding. */
body.game-room-active .room-layer-host .room-panel {
  padding-bottom: 16px;
}

body.game-room-active .room-layer-host .room-panel-chat,
body.game-room-active .room-layer-host .room-panel-controls,
body.game-room-active .room-layer-host .room-panel-clips {
  padding-bottom: 0;
}

/* ── 11. Chat tab: heading row and the moved sidebar (A8, L10, L13, CH2) ─── */

/* Task 23's heading row above the moved sidebar: "Room chat", the moved mic
   and the watching count. */
body.game-room-active .room-chat-head {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}

body.game-room-active .room-chat-title {
  margin: 0 auto 0 0;
  color: var(--text);
  font-size: var(--room-fs-body);
  font-weight: 600;
}

body.game-room-active .room-chat-watching {
  color: var(--text-dim);
  font-size: var(--room-fs-meta);
}

body.game-room-active #btn-sidebar-mic {
  display: grid;
  place-items: center;
  min-width: var(--room-target);
  min-height: var(--room-target);
  border: 1px solid transparent;
  border-radius: var(--radius);
  opacity: 1;
  filter: none;
  transition: none;
}

body.game-room-active #btn-sidebar-mic[aria-pressed="true"] {
  border-color: var(--focus-ring);
}

/* Every drawer and column property gets the room value, including the touch
   rules' display: flex !important (A8). */
body.game-room-active #chat-sidebar {
  position: static;
  inset: auto;
  z-index: auto;
  display: flex !important;
  flex: 1 1 auto;
  flex-direction: column;
  width: auto;
  height: auto;
  min-height: 0;
  max-height: none;
  overflow: hidden;
  border: 0;
  background: transparent;
  box-shadow: none;
  transform: none;
  transition: none;
}

body.game-room-active #chat-sidebar.hidden {
  display: none !important;
}

body.game-room-active #chat-sidebar.drawer-open {
  transform: none;
  box-shadow: none;
}

/* The classic title bar and its close button stay in the sidebar, hidden:
   the heading row replaces them (room code never toggles their classes). */
body.game-room-active #chat-sidebar .chat-sidebar-header {
  display: none;
}

body.game-room-active #chat-sidebar .sidebar-messages {
  flex: 1 1 auto;
  min-height: 0;
  gap: 8px;
  padding: 12px 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

body.game-room-active #chat-sidebar .sidebar-messages .chat-msg {
  font-size: var(--room-fs-body);
  line-height: 1.45;
}

/* Spectator names (ruling D-6): the name renders in --text, and the
   spectator's own hue (the inline color room-chat.js sets) shows as a small
   marker before it, so the name meets 4.5:1 in every theme. Classic is
   unchanged. */
body.game-room-active #chat-sidebar .chat-name-spec {
  -webkit-text-fill-color: var(--text);
}

body.game-room-active #chat-sidebar .chat-name-spec[style]::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 1px;
}

body.game-room-active #chat-sidebar .chat-sidebar-input {
  gap: 8px;
  padding: 12px 16px;
  padding-bottom: calc(12px + max(0px, var(--room-safe-bottom) - var(--room-pad-h)));
  border-top: 1px solid var(--border);
  background: transparent;
}

/* Inside the panels sheet the sheet carries the safe-area padding. */
body.game-room-active .room-layer-host #chat-sidebar .chat-sidebar-input {
  padding-bottom: 12px;
}

body.game-room-active #chat-sidebar #sidebar-input {
  min-height: max(var(--room-target), 40px);
  padding: 0 12px;
  border-radius: var(--radius);
  font-size: var(--room-fs-body);
}

body.game-room-active #chat-sidebar #btn-sidebar-send {
  min-width: max(var(--room-target), 40px);
  min-height: max(var(--room-target), 40px);
  border-radius: var(--radius);
  color: var(--on-accent);
  font-size: var(--room-fs-body);
}

body.game-room-active #chat-sidebar .presence-name {
  font-size: var(--room-fs-body);
}

body.game-room-active #chat-sidebar .presence-role,
body.game-room-active #chat-sidebar .presence-toggle-label,
body.game-room-active #chat-sidebar .presence-avatar-placeholder,
body.game-room-active #chat-sidebar .spectator-invite-btn,
body.game-room-active #chat-sidebar .spectator-invite-pending {
  font-size: var(--room-px-tag);
}

body.game-room-active #chat-sidebar .presence-toggle {
  min-height: var(--room-target);
}

/* ── 12. Achievements tab (AC1, AC3, AC5; Task 24 builds it) ──────────── */

body.game-room-active .room-ach-off {
  display: flex;
  gap: 10px;
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--warning) 45%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--warning) 8%, transparent);
  color: var(--text);
  font-size: var(--room-fs-meta);
}

body.game-room-active .room-ach-sum {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

body.game-room-active .room-ach-frac {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0;
  color: var(--text-dim);
}

body.game-room-active .room-ach-frac b {
  color: var(--text);
  font-family: var(--font-pixel);
  font-size: var(--room-px-title);
  font-weight: 400;
  line-height: 1;
}

body.game-room-active .room-ach-pct,
body.game-room-active .room-ach-points {
  margin: 0;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

body.game-room-active .room-ach-points {
  font-size: var(--room-fs-meta);
}

body.game-room-active .room-ach-bar {
  height: 8px;
  margin: 14px 0 8px;
  overflow: hidden;
  border-radius: 2px;
  background: var(--surface2);
  box-shadow: inset 0 0 0 1px var(--border);
}

/* The progress fill is an indicator: the ring token (TH2, ruling D-6). */
body.game-room-active .room-ach-bar-fill {
  display: block;
  height: 100%;
  background: var(--focus-ring);
}

body.game-room-active .room-seg {
  display: flex;
  gap: 2px;
  margin: 14px 0 8px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}

body.game-room-active .room-seg [role="radio"] {
  display: inline-flex;
  flex: 1 1 0;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-width: var(--room-target);
  min-height: max(var(--room-target), 32px);
  margin: 0;
  padding: 0 8px;
  border: 0;
  border-radius: max(0px, calc(var(--radius) - 2px));
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

body.game-room-active .room-seg [role="radio"][aria-checked="true"] {
  background: var(--surface2);
  color: var(--text);
  box-shadow: 0 0 0 1px var(--focus-ring);
}

body.game-room-active .room-seg-count {
  color: var(--text-dim);
  font-size: var(--room-fs-meta);
  font-weight: 400;
}

/* The classic renderer's rows, moved with #cheevo-panel-list. */
body.game-room-active #cheevo-panel-list {
  padding: 0;
  overflow: visible;
}

body.game-room-active #cheevo-panel-list .cheevo-row {
  padding: 12px 0;
  border-top: 1px solid var(--border);
  opacity: 1;
  transition: none;
}

body.game-room-active #cheevo-panel-list .cheevo-row:first-child {
  border-top: 0;
}

body.game-room-active #cheevo-panel-list .cheevo-name {
  font-size: var(--room-fs-body);
}

body.game-room-active #cheevo-panel-list .cheevo-row.locked .cheevo-name {
  color: var(--text-dim);
}

body.game-room-active #cheevo-panel-list .cheevo-desc,
body.game-room-active #cheevo-panel-list .cheevo-meta,
body.game-room-active #cheevo-panel-list .cheevo-panel-empty {
  font-size: var(--room-fs-meta);
}

/* Empty, loading and server-error text shares the rail/sheet surface. Use
   the stronger reading ink and suppress inherited theme CRT text shadows. */
body.game-room-active #cheevo-panel-list .cheevo-panel-empty {
  color: var(--text);
  text-shadow: none;
}

/* The classic Retry carries .btn-primary, whose translucent default-green
   fill and raw accent ink do not form a readable pair in every theme. */
body.game-room-active #cheevo-panel-list .cheevo-panel-retry {
  min-height: max(var(--room-target), 44px);
  padding: 0 12px;
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  font-size: var(--room-fs-body);
  line-height: 1.2;
  text-shadow: none;
  box-shadow: none;
  opacity: 1;
  transition: none;
}

body.game-room-active #cheevo-panel-list .cheevo-points {
  color: var(--accent-ink);
}

/* The filter (AC3): Task 24 writes the list's data-room-filter. */
body.game-room-active #cheevo-panel-list[data-room-filter="unlocked"] .cheevo-row.locked,
body.game-room-active #cheevo-panel-list[data-room-filter="locked"] .cheevo-row:not(.locked) {
  display: none;
}

/* ── 13. Game options and More menu rows (O1, M1, M2) ──────────────────── */

#screen-game.game-room .room-options-host {
  padding: 8px 8px 12px;
}

#screen-game.game-room .room-options-title {
  margin: 6px 8px 8px;
  color: var(--text);
  font-size: var(--room-fs-meta);
  font-weight: 400;
  text-shadow: none;
}

/* Rows in #room-options and in the More menu: the moved buttons keep their
   classic classes; the room's icon and label wrappers carry the text. */
body.game-room-active .room-more-row {
  display: flex;
  align-items: center;
  gap: 12px;
  box-sizing: border-box;
  width: 100%;
  min-height: max(var(--room-target), 44px);
  margin: 0;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
  cursor: pointer;
}

body.game-room-active .room-more-row .gm-icon {
  display: none;
}

body.game-room-active .room-more-icon {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 20px;
  height: 20px;
  color: var(--text-dim);
}

body.game-room-active .room-more-icon svg {
  width: 20px;
  height: 20px;
}

body.game-room-active .room-more-row .gm-label,
body.game-room-active .room-more-label {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

body.game-room-active #btn-favorite.active .room-more-icon {
  color: var(--warning-ink);
}

body.game-room-active .room-layer-host #game-more-menu .game-more-group-title {
  padding: 6px 10px 3px;
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--room-fs-meta);
  letter-spacing: 0;
  text-transform: none;
}

/* ── 14. Layer host and layers: confirms, the leave dialog, sheets, More ─ */
/*        (A9, T5, L8, M2, G6)                                              */

/* Never display: none: a popover under a display: none ancestor does not
   render in the top layer (ruling D-6). The host has no box of its own. */
body.game-room-active .room-layer-host {
  position: static;
  display: block;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
}

/* Every presented layer: the room's box replaces the UA popover box. Popovers
   are placed by script (inline left, top or bottom and max-height); sheets by
   the sheet rule below. The moved classic menu and confirms get the same box
   (and every property their classic trigger rules set, A8). */
body.game-room-active .room-layer-host > [data-room-present],
body.game-room-active .room-layer-host #game-more-menu,
body.game-room-active .room-layer-host #exit-confirm,
body.game-room-active .room-layer-host #rewind-confirm,
body.game-room-active .room-layer-host #c64-speed-confirm {
  position: fixed;
  inset: auto;
  z-index: auto;
  box-sizing: border-box;
  width: max-content;
  min-width: 0;
  max-width: min(340px, calc(100vw - 16px));
  max-height: calc(100dvh - 16px);
  margin: 0;
  padding: 16px;
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 22px 48px -14px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(0, 0, 0, 0.15);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  line-height: 1.5;
  text-align: left;
  font-synthesis-weight: none;
  transform: none;
  backdrop-filter: none;
}

body.game-room-active .room-layer-host #game-more-menu {
  width: 264px;
  max-height: min(72dvh, 560px);
  padding: 6px;
}

body.game-room-active .room-layer-host #exit-confirm {
  align-items: stretch;
  gap: 12px;
}

/* Bottom sheets: phone layout and sheet mode (L8, M2, T5). The id
   selectors outrank the More menu's popover width above. */
body.game-room-active .room-layer-host > [data-room-present="sheet"],
body.game-room-active .room-layer-host #game-more-menu[data-room-present="sheet"],
body.game-room-active .room-layer-host #exit-confirm[data-room-present="sheet"],
body.game-room-active .room-layer-host #rewind-confirm[data-room-present="sheet"],
body.game-room-active .room-layer-host #c64-speed-confirm[data-room-present="sheet"] {
  top: auto;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  max-width: none;
  max-height: 84dvh;
  padding: 12px calc(12px + var(--room-safe-right)) calc(16px + var(--room-safe-bottom)) calc(12px + var(--room-safe-left));
  border-bottom: 0;
  border-radius: 16px 16px 0 0;
}

body.game-room-active .room-layer-host > [popover]::backdrop {
  background: transparent;
}

body.game-room-active .room-layer-host > [data-room-present="sheet"]::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

/* The panels sheet (Task 20): its head, then the moved tab bar and panels;
   the tab bar spans the sheet, inset only by the safe areas. */
body.game-room-active .room-layer-host > .room-panels-sheet[data-room-present="sheet"] {
  display: flex;
  flex-direction: column;
  height: min(84dvh, 640px);
  padding: 0 var(--room-safe-right) var(--room-safe-bottom) var(--room-safe-left);
}

body.game-room-active .room-sheet-head {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 8px 8px 16px;
  border-bottom: 1px solid var(--border);
}

body.game-room-active .room-sheet-title {
  margin: 0;
  color: var(--text);
  font-size: var(--room-fs-body);
  font-weight: 600;
}

body.game-room-active .room-sheet-close {
  min-width: max(var(--room-target), 44px);
  min-height: max(var(--room-target), 44px);
  margin: 0;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  cursor: pointer;
}

body.game-room-active .room-sheet-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

body.game-room-active .room-sheet-body > .room-tabs {
  flex: none;
  border-bottom: 1px solid var(--border);
}

/* The room's confirm (Task 18), the leave dialog (Task 27, built from the
   same classes) and the moved classic confirms (T5, G6, G9). */
body.game-room-active .room-confirm-title {
  margin: 0;
  color: var(--text);
  font-size: var(--room-fs-body);
  font-weight: 600;
}

body.game-room-active .room-confirm-body,
body.game-room-active .room-confirm-status {
  margin: 6px 0 0;
  color: var(--text-dim);
}

body.game-room-active .room-confirm-status {
  color: var(--text);
}

body.game-room-active .room-confirm-actions,
body.game-room-active .room-layer-host #exit-confirm .exit-confirm-actions,
body.game-room-active .room-layer-host #rewind-confirm,
body.game-room-active .room-layer-host #c64-speed-confirm {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

body.game-room-active .room-confirm-actions {
  margin-top: 14px;
}

body.game-room-active .room-confirm-ok,
body.game-room-active .room-confirm-cancel,
body.game-room-active .room-layer-host #exit-confirm .btn-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--room-target);
  min-height: max(var(--room-target), 36px);
  margin: 0;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  opacity: 1;
  cursor: pointer;
}

/* The confirm button: an accent fill, a danger fill for Reset (T5). */
body.game-room-active .room-confirm-ok {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
}

body.game-room-active .room-confirm[data-confirm-id="reset"] .room-confirm-ok,
body.game-room-active .room-layer-host #exit-confirm-ok {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--on-danger);
}

/* Shared dialog buttons (the leave dialog's actions). */
body.game-room-active .room-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: var(--room-target);
  min-height: max(var(--room-target), 36px);
  margin: 0;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-body);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

body.game-room-active .room-btn-primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
}

body.game-room-active .room-btn-danger {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--on-danger);
}

body.game-room-active .room-btn:disabled {
  border-style: dashed;
  border-color: var(--border);
  background: var(--surface2);
  color: var(--text-dim);
  cursor: default;
}

body.game-room-active .room-layer-host #rewind-confirm,
body.game-room-active .room-layer-host #c64-speed-confirm {
  align-items: center;
  color: var(--text);
  font-size: var(--room-fs-body);
}

body.game-room-active .room-layer-host #rewind-confirm .btn-tiny,
body.game-room-active .room-layer-host #c64-speed-confirm .btn-tiny {
  min-width: max(var(--room-target), 36px);
  min-height: max(var(--room-target), 36px);
}

/* ── 15. Body-level overlays placed over the stage (L11) ───────────────── */

body.game-room-active #flash {
  top: calc(max(var(--room-chrome-h), var(--room-safe-top)) + var(--room-edge-h) + 8px);
}

body.game-room-active #replay-saved-callout {
  top: calc(max(var(--room-chrome-h), var(--room-safe-top)) + var(--room-edge-h) + 8px) !important;
}

body.game-room-active #replay-hud {
  top: calc(var(--room-stage-top) + var(--room-edge-h) + 8px);
  right: calc(var(--room-stage-right) + 8px);
  left: auto;
  max-width: calc(100vw - var(--room-stage-left) - var(--room-stage-right) - 16px);
}

@media (max-width: 600px) {
  body.game-room-active #replay-hud {
    left: calc(var(--room-stage-left) + 8px);
  }
}

body.game-room-active #ghost-race {
  right: auto;
  bottom: calc(var(--room-stage-bottom) + 12px);
  left: calc(var(--room-stage-left) + 12px);
}

body.game-room-active #chat-panel-fab {
  right: calc(var(--room-stage-right) + 12px);
  bottom: calc(var(--room-stage-bottom) + 12px);
}

body.game-room-active #clip-toast {
  right: calc(var(--room-stage-right) + 76px);
  bottom: calc(var(--room-stage-bottom) + 12px);
  width: min(280px, calc(100vw - var(--room-stage-left) - var(--room-stage-right) - 88px));
  animation: none;
}

body.game-room-active .play-invite-toast {
  right: calc(var(--room-stage-right) + 76px);
  bottom: calc(var(--room-stage-bottom) + 12px);
  max-width: min(320px, calc(100vw - var(--room-stage-left) - var(--room-stage-right) - 88px));
  animation: none;
  transition: none;
}

/* The C64 guide and Disk Management center over the stage. */
body.game-room-active #cheatsheet {
  top: calc(var(--room-stage-top) + (100dvh - var(--room-stage-top) - var(--room-stage-bottom)) / 2);
  left: calc(var(--room-stage-left) + (100% - var(--room-stage-left) - var(--room-stage-right)) / 2);
  width: min(800px, calc(100% - var(--room-stage-left) - var(--room-stage-right) - 32px));
  max-height: calc(100dvh - var(--room-stage-top) - var(--room-stage-bottom) - 24px);
}

body.game-room-active #cheatsheet.c64-guide-sheet {
  width: min(1160px, calc(100% - var(--room-stage-left) - var(--room-stage-right) - 32px));
  max-width: none;
  max-height: min(820px, calc(100dvh - var(--room-stage-top) - var(--room-stage-bottom) - 24px));
}

body.game-room-active #disk-picker:not(.c64-anchored) {
  bottom: calc(var(--room-stage-bottom) + 12px);
  left: calc(var(--room-stage-left) + (100% - var(--room-stage-left) - var(--room-stage-right)) / 2);
}

/* The pad stays a full-width row at the bottom (L7); the room reserves its
   height through --room-pad-h. Full screen draws it over the picture. */
body.game-room-active #touch-gamepad {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 150;
  padding-bottom: max(30px, calc(var(--room-safe-bottom) + 22px));
}

/* X2: the reused pad's SELECT/START, N64 directions and C cluster obey
   the same 24px floor and 44px coarse target as the room controls. */
body.game-room-active #touch-gamepad .touch-btn,
body.game-room-active #touch-gamepad .touch-joystick,
body.game-room-active #touch-gamepad .touch-dpad {
  min-width: var(--room-target);
  min-height: var(--room-target);
}

/* SELECT/START must remain readable over any picture. An opaque surface and
   verified text ink replace the classic translucent pad label styling. */
body.game-room-active #touch-gamepad .meta-btn {
  background: var(--surface2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--room-fs-meta);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0;
  text-shadow: none;
  opacity: 1;
  transition: none;
}

body.game-room-active #touch-gamepad .meta-btn.active {
  background: var(--surface);
  color: var(--text);
}

body.game-room-active #touch-gamepad .n64-dpad {
  grid-template-columns: repeat(3, max(30px, var(--room-target)));
  grid-template-rows: repeat(3, max(30px, var(--room-target)));
}

body.game-room-active #touch-gamepad .touch-c-cluster {
  grid-template-columns: repeat(3, max(40px, var(--room-target)));
  grid-template-rows: repeat(3, max(40px, var(--room-target)));
}

/* Keep shoulder targets inside the measured pad row. */
body.game-room-active #touch-gamepad.n64 {
  padding-top: 60px;
}

body.game-room-active #touch-gamepad.n64 .touch-n64-triggers {
  top: 6px;
}

/* The three phone zones need 132 + 58 + 144px. Narrow the outer gutters
   and Start's padding instead of adding another 100px row below the pad;
   that row left the picture at zero height at 375x548. */
@media (max-width: 640px) {
  body.game-room-active #touch-gamepad.n64 {
    flex-wrap: nowrap;
    padding-left: max(10px, var(--room-safe-left));
    padding-right: max(10px, var(--room-safe-right));
  }
  body.game-room-active #touch-gamepad.n64 .n64-start {
    padding: 7px 4px;
  }
}

/* Short, wide landscape has room for the stick beside the D-pad and face
   buttons beside the C diamond. The central two rows hold shoulders above
   Start/Z, so every input belongs to the measured pad instead of projecting
   over the dock/rail. No input or 44px target is removed. */
@media (min-width: 800px) and (max-height: 700px) {
  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"]) #touch-gamepad.n64 {
    display: grid;
    grid-template-columns: max-content max-content max-content;
    grid-template-rows: auto auto;
    grid-template-areas: "left triggers right" "left center right";
    column-gap: 12px;
    row-gap: 12px;
    align-items: center;
    padding-top: 6px;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"]) #touch-gamepad.n64 .touch-n64-left {
    grid-area: left;
    flex-direction: row;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"]) #touch-gamepad.n64 .touch-n64-right {
    grid-area: right;
    flex-direction: row;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"]) #touch-gamepad.n64 .touch-n64-center {
    grid-area: center;
    flex-direction: row;
    gap: 12px;
    padding-bottom: 0;
  }

  body.game-room-active:has(#screen-game.game-room[data-room-layout="landscape"]) #touch-gamepad.n64 .touch-n64-triggers {
    grid-area: triggers;
    position: static;
    top: auto;
    right: auto;
    left: auto;
    align-self: start;
    gap: 8px;
    padding: 0;
  }
}

body.game-room-active.mobile-fullscreen #touch-gamepad,
body.game-room-active.landscape-fs #touch-gamepad {
  z-index: 9002;
}

/* Body-level overlays stay above the room, including the full screen
   layout's raised screen (L11, H7). */
body.game-room-active.mobile-fullscreen #game-change-overlay,
body.game-room-active.landscape-fs #game-change-overlay,
body.game-room-active.mobile-fullscreen #auth-modal,
body.game-room-active.landscape-fs #auth-modal {
  z-index: 9005;
}

/* ── 16. Keyboard focus (TH2) ──────────────────────────────────────────── */

/* Overrides accessibility.css's !important ring with --focus-ring: the room
   rules carry an id or more classes, so they win at equal importance. */
#screen-game.game-room :is(a[href], button, input, select, textarea, [role="button"], [role="tab"], [role="radio"], [role="switch"], [tabindex]:not([tabindex="-1"])):focus-visible,
body.game-room-active .room-layer-host :is(a[href], button, input, select, textarea, [role="button"], [role="tab"], [role="radio"], [role="switch"], [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 3px solid var(--focus-ring) !important;
  outline-offset: 2px !important;
}

/* The tab list scrolls, so it clips outside rings: draw tab rings inside. */
#screen-game.game-room .room-tabs > .room-tab:focus-visible,
body.game-room-active .room-layer-host .room-tabs > .room-tab:focus-visible {
  outline-offset: -3px !important;
}

/* ── 17. Hover (fine pointers only, T2) ────────────────────────────────── */

@media (hover: hover) and (pointer: fine) {
  #screen-game.game-room #room-dock .room-dock-btn:hover {
    border-color: transparent;
    background: var(--surface2);
  }

  #screen-game.game-room #room-dock .room-dock-btn:hover .room-dock-icon {
    color: var(--accent-ink);
  }

  #screen-game.game-room #room-dock #btn-exit:hover .room-dock-icon {
    color: var(--danger-ink);
  }

  #screen-game.game-room .room-edge:hover,
  #screen-game.game-room .room-strip-btn:hover,
  #screen-game.game-room .room-collapse:hover {
    color: var(--accent-ink);
  }

  body.game-room-active .room-tab:hover {
    color: var(--text);
  }

  body.game-room-active .room-game-link:hover,
  body.game-room-active .room-more-row:hover {
    border-color: transparent;
    background: var(--surface2);
  }

  body.game-room-active .room-confirm-cancel:hover,
  body.game-room-active .room-sheet-close:hover,
  body.game-room-active .room-btn:not(.room-btn-primary, .room-btn-danger, :disabled):hover {
    border-color: var(--text-dim);
  }

  body.game-room-active .room-seg [role="radio"]:hover {
    color: var(--text);
  }
}

/* ── 18. Motion (TH5) ──────────────────────────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {
  #screen-game.game-room #room-dock .room-dock-btn,
  body.game-room-active .room-tab,
  body.game-room-active .room-more-row {
    transition: background-color 0.15s var(--room-ease), border-color 0.15s var(--room-ease), color 0.15s var(--room-ease);
  }

  #screen-game.game-room #game-controls #btn-voice {
    transition: box-shadow 0.12s ease;
  }

  body.game-room-active #clip-toast {
    animation: clip-toast-in 0.3s ease-out;
  }

  body.game-room-active .play-invite-toast {
    animation: toast-in 0.25s ease-out;
  }
}

/* ── 19. Forced colors ─────────────────────────────────────────────────── */

@media (forced-colors: active) {
  body.game-room-active .room-tab[aria-selected="true"]::after,
  body.game-room-active .room-ach-bar-fill,
  #screen-game.game-room #game-controls #btn-room-panels .room-dock-dot {
    background: Highlight;
  }

  #screen-game.game-room #game-controls #btn-room-panels .room-dock-badge,
  body.game-room-active .room-tab-badge,
  #screen-game.game-room .room-edge {
    border: 1px solid CanvasText;
  }

  #screen-game.game-room #game-controls .c64-port-btn[aria-pressed="true"] {
    border-color: Highlight;
    background: Highlight;
    color: HighlightText;
  }
}

/* ── 20. On-screen keyboard (L10) ─────────────────────────────────────── */

/* While the chat input has focus, room-chat-embed.js (Task 23) sets
   room-vv-active, with the visual viewport's height and top offset
   (--room-vv-height, --room-vv-top, in px), on the shell and on the layer
   host, at most once per frame. The rail that holds the focused field and
   the panels sheet then fit inside the visual viewport, so an on-screen
   keyboard (iOS Safari, Android Chrome's default resizes-visual) never
   covers the input. In the portrait and phone layouts the panels under the
   stage are these same rails. The sheet keeps its bottom edge on the visual
   viewport's bottom: 100% is the layout viewport (the fixed sheet's
   containing block), less the viewport's top offset and height, so with no
   on-screen keyboard it stays at 0 and the sheet does not move. Insets and
   max-height keep the sheet inside. The focused rail is fixed to that same
   top and height; its input row stays inside the visible border box while
   its messages shrink. Per-layout rules preserve its horizontal slot. No
   protected surface gains a transform (A9). Without window.visualViewport
   nothing sets the class, and nothing here applies. */
#screen-game.game-room .room-shell.room-vv-active .room-rail:focus-within {
  position: fixed;
  top: var(--room-vv-top);
  right: 0;
  bottom: auto;
  left: 0;
  height: var(--room-vv-height);
  max-height: var(--room-vv-height);
  box-sizing: border-box;
  z-index: 6;
}

/* Preserve the rail's inline size and side while its vertical box follows
   the visual viewport. Phone is full width; portrait is the left half. */
#screen-game.game-room[data-room-layout="desktop"] .room-shell.room-vv-active .room-rail-left:focus-within {
  right: auto;
  width: var(--room-left-w);
}

#screen-game.game-room[data-room-layout="landscape"] .room-shell.room-vv-active .room-rail-left:focus-within {
  left: auto;
  width: var(--room-left-w);
}

#screen-game.game-room[data-room-layout="portrait"] .room-shell.room-vv-active .room-rail-left:focus-within {
  right: auto;
  width: 50%;
}

@media (max-height: 359px) {
  #screen-game.game-room[data-room-layout="landscape"] .room-shell.room-vv-active .room-rail-left:focus-within {
    right: 0;
    left: 0;
    width: auto;
  }
}

body.game-room-active .room-layer-host.room-vv-active > .room-panels-sheet[data-room-present="sheet"] {
  top: auto;
  bottom: max(0px, 100% - var(--room-vv-top) - var(--room-vv-height));
  max-height: var(--room-vv-height);
}

/* ── Chat tab player names (Task 23: CH2, TH1) ─────────────────────────── */

/* Player names use the text inks (TH1). Spectator names are Task 16's (D-6:
   --text with the hue as a marker). The floating overlay (#chat) keeps
   today's colours on its own dark backing. */
body.game-room-active #chat-sidebar .chat-name-p1 {
  color: var(--accent-ink);
}

body.game-room-active #chat-sidebar .chat-name-p2 {
  color: var(--accent2-ink);
}

/* ── Clips & Replays (Task 26: CR1 to CR8, L6) ─────────────────────────── */

/* The panel and the right strip's quick buttons. Text uses the inks and the
   type tokens (TH1, TH3); borders use the role colours. The Recording
   indicator is static (TH5). Task 16 leaves the Clips panel unpadded. */
body.game-room-active .room-captures { display: grid; }
body.game-room-active .room-cap-sec { padding: 16px; border-bottom: 1px solid var(--border); }
body.game-room-active .room-cap-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
body.game-room-active .room-cap-h { margin: 0; font-size: var(--room-fs-body); font-weight: 600; }
body.game-room-active .room-cap-clips .room-cap-h { color: var(--accent2-ink); }
body.game-room-active .room-cap-replays .room-cap-h { color: var(--replay-ink); }
body.game-room-active .room-cap-text { margin: 4px 0 0; font-size: var(--room-fs-body); color: var(--text); }
body.game-room-active .room-cap-link { display: inline-flex; align-items: center; min-height: 24px; font-weight: 600; color: var(--accent-ink); }
body.game-room-active .room-cap-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 44px; margin-top: 12px; padding: 0 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface2); color: var(--text); font: inherit; font-size: var(--room-fs-body); font-weight: 600; cursor: pointer; }
body.game-room-active .room-cap-clips .room-cap-btn { border-color: var(--accent2); color: var(--accent2-ink); }
body.game-room-active .room-cap-replays .room-cap-btn { border-color: var(--replay); color: var(--replay-ink); }
body.game-room-active .room-cap-btn[aria-disabled="true"] { border-color: var(--border); color: var(--text-dim); cursor: default; }
body.game-room-active .room-cap-btn svg,
body.game-room-active .room-strip-capture svg { flex: none; width: 20px; height: 20px; }
body.game-room-active .room-cap-status { margin: 10px 0 0; font-size: var(--room-fs-meta); line-height: 1.5; color: var(--text); }
body.game-room-active .room-cap-status:empty { display: none; }
body.game-room-active .room-cap-note { margin: 12px 0 0; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); font-size: var(--room-fs-meta); line-height: 1.5; color: var(--text-dim); }
body.game-room-active .room-cap-rec { display: inline-flex; align-items: center; gap: 6px; font-size: var(--room-fs-meta); font-weight: 600; color: var(--danger-ink); }
body.game-room-active .room-cap-rec-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); }
body.game-room-active .room-strip-capture { display: inline-grid; flex: none; place-items: center; width: 40px; height: 40px; min-width: var(--room-target); min-height: var(--room-target); padding: 0; border: 0; border-radius: var(--radius); background: none; cursor: pointer; }
body.game-room-active .room-strip-capture[data-room-quick="clip"] { color: var(--accent2-ink); }
body.game-room-active .room-strip-capture[data-room-quick="replay"] { color: var(--replay-ink); }
body.game-room-active .room-strip-capture[aria-disabled="true"] { color: var(--text-dim); cursor: default; }
@media (hover: hover) and (pointer: fine) {
  body.game-room-active .room-cap-btn:not([aria-disabled="true"]):hover,
  body.game-room-active .room-strip-capture:not([aria-disabled="true"]):hover { background: var(--surface); }
}

/* ── Controls tab (Task 25: CT1 to CT6, K8) ────────────────────────────── */

/* Task 16 leaves the Controls panel unpadded, so the tab pads itself. Text
   uses the type tokens (TH3) and the inks (TH1); the switch's on state is an
   indicator on the ring token (TH2, ruling D-6). Motion only under
   no-preference (TH5). */
body.game-room-active .room-ctl { display: grid; gap: 16px; padding: 16px; }
body.game-room-active .room-ctl-sec { padding-bottom: 16px; border-bottom: 1px solid var(--border); }
body.game-room-active .room-ctl-h { margin: 0 0 8px; font-size: var(--room-fs-body); font-weight: 600; color: var(--text); }
body.game-room-active .room-ctl-callout { display: flex; gap: 8px; align-items: flex-start; margin: 0; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface2); font-size: var(--room-fs-meta); line-height: 1.5; color: var(--text); }
body.game-room-active .room-ctl-list { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 12px; align-items: center; margin: 0; }
body.game-room-active .room-ctl-list dt { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0; font-size: var(--room-fs-meta); color: var(--text-dim); }
body.game-room-active .room-ctl-list dd { margin: 0; font-size: var(--room-fs-meta); color: var(--text); }
body.game-room-active .room-ctl kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; min-height: 24px; padding: 0 6px; border: 1px solid var(--border); border-bottom-width: 2px; border-radius: 4px; background: var(--surface2); color: var(--text); font-family: inherit; font-size: var(--room-fs-meta); font-weight: 600; }
body.game-room-active .room-ctl-pad { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; font-size: var(--room-fs-meta); color: var(--text); }
body.game-room-active .room-ctl-pad li { display: flex; flex-wrap: wrap; gap: 4px 12px; }
body.game-room-active .room-ctl-live { margin-bottom: 12px; padding: 10px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface2); }
body.game-room-active .room-ctl-live-name { margin: 0 0 4px; overflow-wrap: anywhere; font-size: var(--room-fs-meta); font-weight: 600; color: var(--text); }
body.game-room-active .room-ctl-live-name:empty { display: none; }
body.game-room-active .room-ctl-live-status,
body.game-room-active .room-ctl-live-readings { margin: 0; font-size: var(--room-fs-meta); line-height: 1.5; color: var(--text-dim); }
body.game-room-active .room-ctl-live-readings { margin-top: 6px; font-variant-numeric: tabular-nums; }
body.game-room-active .room-ctl-live .controllers-test-gamepad-figure { position: static; width: min(100%, 280px); margin: 0 auto; }
body.game-room-active .room-ctl-live .controllers-test-gamepad-diagram { display: block; width: 100%; height: auto; }
body.game-room-active .room-ctl-live .controllers-test-gamepad-caption { text-align: center; font-family: var(--font-mono); font-size: var(--room-fs-meta); font-weight: 400; letter-spacing: normal; text-transform: none; color: var(--text-dim); }
body.game-room-active .room-ctl-live .controllers-gamepad-body-shadow { fill: color-mix(in srgb, var(--focus-ring) 12%, transparent); }
body.game-room-active .room-ctl-live .controllers-gamepad-body { fill: var(--surface); stroke: var(--text-dim); stroke-width: 4; }
body.game-room-active .room-ctl-live .controllers-gamepad-seam { fill: none; stroke: var(--border); stroke-width: 3; stroke-linecap: round; }
body.game-room-active .room-ctl-live .controllers-gamepad-control-surface,
body.game-room-active .room-ctl-live .controllers-gamepad-stick-well,
body.game-room-active .room-ctl-live .controllers-gamepad-dpad-center { fill: var(--surface2); stroke: var(--text-dim); stroke-width: 3; }
body.game-room-active .room-ctl-live .controllers-gamepad-stick-well { stroke: var(--border); }
body.game-room-active .room-ctl-live .controllers-gamepad-stick-cap { fill: none; stroke: var(--text-dim); stroke-width: 2; }
body.game-room-active .room-ctl-live .controllers-gamepad-control-label { fill: var(--text); font-family: var(--font-mono); font-size: var(--room-fs-body); font-weight: 600; }
body.game-room-active .room-ctl-live .controllers-gamepad-control[data-pressed="true"] .controllers-gamepad-control-surface { fill: var(--focus-ring); stroke: var(--focus-ring); }
body.game-room-active .room-ctl-live .controllers-gamepad-control[data-pressed="true"] .controllers-gamepad-control-label { fill: var(--on-accent); }
body.game-room-active .room-ctl-live .controllers-gamepad-control[data-value]:not([data-value="0.00"]) .controllers-gamepad-control-surface { stroke: var(--focus-ring); }
body.game-room-active .room-ctl-live .controllers-gamepad-stick { transform-box: view-box; transform-origin: center; transition-duration: 0s; }
body.game-room-active .room-ctl-live-raw { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
body.game-room-active .room-ctl-live-button { padding: 4px 6px; border: 1px solid var(--border); border-radius: 4px; font-size: var(--room-fs-meta); color: var(--text); }
body.game-room-active .room-ctl-live-button[data-pressed="true"] { border-color: var(--focus-ring); background: var(--focus-ring); color: var(--on-accent); font-weight: 600; }
body.game-room-active .room-ctl-guide-btn,
body.game-room-active .room-ctl-switch { width: 100%; min-height: 44px; border-radius: var(--radius); color: var(--text); font: inherit; cursor: pointer; }
body.game-room-active .room-ctl-guide-btn { display: flex; align-items: center; justify-content: center; padding: 0 12px; border: 1px solid var(--border); background: var(--surface2); font-size: var(--room-fs-body); font-weight: 600; }
body.game-room-active .room-ctl-switch { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 8px 0; border: 0; background: none; text-align: left; }
body.game-room-active .room-ctl-switch + .room-ctl-switch { border-top: 1px solid var(--border); border-radius: 0; }
body.game-room-active .room-ctl-switch-label { display: block; font-size: var(--room-fs-body); font-weight: 600; }
body.game-room-active .room-ctl-switch-desc { display: block; font-size: var(--room-fs-meta); color: var(--text-dim); }
body.game-room-active .room-ctl-switch-track { position: relative; width: 42px; height: 24px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface2); }
body.game-room-active .room-ctl-switch-track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--text-dim); }
body.game-room-active .room-ctl-switch[aria-checked="true"] .room-ctl-switch-track { border-color: var(--focus-ring); background: color-mix(in srgb, var(--focus-ring) 28%, var(--surface2)); }
body.game-room-active .room-ctl-switch[aria-checked="true"] .room-ctl-switch-track::after { left: 21px; background: var(--focus-ring); }
body.game-room-active .room-ctl-hint,
body.game-room-active .room-ctl-note { margin: 8px 0 0; font-size: var(--room-fs-meta); color: var(--text-dim); }
body.game-room-active .room-ctl-link { display: inline-flex; align-items: center; min-height: var(--room-target); font-size: var(--room-fs-body); font-weight: 600; color: var(--accent-ink); }
@media (hover: hover) and (pointer: fine) {
  body.game-room-active .room-ctl-guide-btn:hover { border-color: var(--focus-ring); }
}
@media (prefers-reduced-motion: no-preference) {
  body.game-room-active .room-ctl-switch-track::after { transition: left 0.15s ease, background-color 0.15s ease; }
}
#screen-game.game-room .room-multitap-status { display: block; font-size: var(--room-fs-meta); color: var(--text-dim); text-align: center; }
#screen-game.game-room .room-multitap-status[hidden] { display: none; }
#screen-game.game-room .room-multitap-recovery { display: flex; gap: .5rem; flex-wrap: wrap; }

/* Give the C64 drive stack its own gutter beside the picture on desktop. */
@media (min-width: 1024px) {
  #screen-game.game-room[data-room-layout="desktop"] .room-well > .game-main[data-c64-workbench] {
    padding-left: 162px;
  }
  #screen-game.game-room[data-room-layout="desktop"] .game-main[data-c64-workbench] > #canvas-container:not(:fullscreen) {
    width: min(calc(100cqw - 162px), calc(100cqh * var(--game-ar-w) / var(--game-ar-h))) !important;
  }
}

/* Both drives occupy one gutter; the picture never sits behind their controls. */
#screen-game.game-room .room-well > .game-main:has(> .c64-drive-control-wrap:not(.hidden)) {
  padding-left: 174px;
  min-height: min(366px, calc(100dvh - 60px));
}
#screen-game.game-room #room-stage .game-main > .c64-drive-control-wrap {
  max-height: calc(100% - 52px);
  overflow-y: auto;
  scrollbar-width: thin;
}
#screen-game.game-room .game-main:has(> .c64-drive-control-wrap:not(.hidden)) > #canvas-container:not(:fullscreen) {
  width: min(calc(100cqw - 174px), calc(100cqh * var(--game-ar-w) / var(--game-ar-h))) !important;
}

/* The same Guide section adapts its rows to the narrower Controls rail. */
body.game-room-active .room-ctl .c64-vkey-row-1 {
  grid-template-columns: repeat(6, minmax(0, 1fr));
}
body.game-room-active .room-ctl .c64-vkey-row-1 > :nth-child(-n+2) { grid-column: span 3; }
body.game-room-active .room-ctl .c64-vkey-row-1 > :nth-child(n+3) { grid-column: span 2; }
body.game-room-active .room-ctl .c64-vkey-row-2,
body.game-room-active .room-ctl .c64-vkey-row-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
body.game-room-active .room-ctl .c64-vkey-row-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
body.game-room-active .room-ctl .c64-host-key-grid { grid-template-columns: 1fr; }
body.game-room-active .room-ctl .c64-vkey { min-height: 32px; padding: 4px 3px; font-size: var(--room-fs-meta); }
body.game-room-active .room-ctl .c64-vkey:disabled { opacity: .5; cursor: default; }
