/* ==========================================================================
   Hotbox University — the game shell (app/index.html, body.game)
   --------------------------------------------------------------------------
   The campus is the page. One world behind everything (the operator's own
   clip), the top bar with the four tabs over it, the dock of eight doors
   along the bottom, and the lobby HUD or a glass panel in between. Built
   from the Castle Lobby blueprint: left rail (profile, welcome, CTA, four
   cards), centre scene, right preview card, bottom dock. Loaded after
   app.css; everything here overrides the older sidebar layout.
   ========================================================================== */

body.game { background: #061027; color: #fff; overflow: hidden; }
body.game .shell { display: contents; }

/* ---- Tokens from the blueprint ---- */
body.game {
  --hu-navy-950: #061027; --hu-navy-900: #0a1936;
  --hu-blue-600: #1467ef; --hu-blue-400: #38a5ff;
  --hu-ice: #eaf5ff; --hu-gold: #e6bb66; --hu-amber: #f5c67c;
  --hu-panel: rgba(5, 15, 37, 0.78); --hu-panel-border: rgba(144, 195, 255, 0.4);
  --hu-glow: 0 0 20px rgba(34, 132, 255, 0.45);
  --top-h: 64px; --dock-h: 118px;
}

/* ---- The world ---- */
.world { position: fixed; inset: 0; z-index: 0; background: #061027; }
/* Still, loop and operator share one ground so the idle drift moves them as one picture. */
.world__ground { position: absolute; inset: 0; overflow: hidden; container-type: size; }
/* Off the lobby the art box is simply the whole ground and the still covers it. */
.world__art { position: absolute; inset: 0; }
.world__still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
.world__scene { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; opacity: 0; transition: opacity 500ms var(--ease); }
.world__scene.is-live { opacity: 1; }
.world__veil { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(6, 16, 39, 0.55), transparent 18%, transparent 70%, rgba(6, 16, 39, 0.75) 100%); pointer-events: none; transition: background 400ms var(--ease), backdrop-filter 400ms; }
/* On every screen but the lobby the world steps back: darker and softer, so the panel reads. */
body.game.is-panel .world__veil { background: rgba(6, 16, 39, 0.62); backdrop-filter: blur(6px) saturate(1.1); -webkit-backdrop-filter: blur(6px) saturate(1.1); }
/* In a room (Vault, Arsenal, Shop, Studio) the place is the point: a lighter veil, no blur, so the room reads around the panel. */
body.game.is-panel.is-room .world__veil { background: linear-gradient(180deg, rgba(6, 16, 39, 0.5), rgba(6, 16, 39, 0.28) 30%, rgba(6, 16, 39, 0.55) 100%); backdrop-filter: none; -webkit-backdrop-filter: none; }

/* ---- Top bar ---- */
.top { position: fixed; left: 0; right: 0; top: 0; z-index: 40; height: calc(var(--top-h) + env(safe-area-inset-top, 0px)); padding: calc(env(safe-area-inset-top, 0px) + 8px) 22px 8px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 16px; background: linear-gradient(180deg, rgba(6, 16, 39, 0.72), rgba(6, 16, 39, 0)); }
.top__crest { display: block; width: 52px; height: 52px; filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.7)); transition: transform 180ms var(--ease-out); }
.top__crest img { width: 100%; height: 100%; object-fit: contain; }
.top__crest:hover { transform: scale(1.06); }
.tabs { justify-self: center; display: flex; gap: 6px; padding: 4px; border-radius: 14px; background: rgba(5, 15, 37, 0.62); border: 1px solid rgba(144, 195, 255, 0.22); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.tabs a { display: block; padding: 10px 18px; border-radius: 10px; color: rgba(234, 245, 255, 0.82); font-weight: 800; font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none; transition: background 160ms, color 160ms, transform 160ms var(--ease-out); }
.tabs a:hover { color: #fff; background: rgba(255, 255, 255, 0.08); transform: translateY(-1px); }
.tabs a.is-active { color: #fff; background: linear-gradient(180deg, var(--hu-blue-400), var(--hu-blue-600)); box-shadow: var(--hu-glow), inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.top__right { display: flex; align-items: center; gap: 8px; }
.chip { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 6px 12px; border-radius: 12px; background: rgba(5, 15, 37, 0.62); border: 1px solid rgba(144, 195, 255, 0.22); color: #fff; text-decoration: none; font: inherit; cursor: pointer; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: border-color 160ms, transform 160ms var(--ease-out); }
.chip:hover { border-color: rgba(144, 195, 255, 0.6); transform: translateY(-1px); }
.chip--credits b { font-size: 1rem; color: var(--hu-amber); }
.chip--icon { width: 44px; justify-content: center; padding: 6px; position: relative; font-size: 1.2rem; }
.chip--icon img { width: 28px; height: 28px; object-fit: contain; }
.chip--icon .side__badge { position: absolute; top: -6px; right: -6px; }
body.game .streak { margin: 0; background: rgba(5, 15, 37, 0.62); }
body.game .sound { margin: 0; }

/* ---- The drawer (course menu) ---- */
body.game .side { position: fixed; top: calc(var(--top-h) + env(safe-area-inset-top, 0px) + 8px); right: 22px; bottom: calc(var(--dock-h) + 12px); left: auto; width: min(360px, 90vw); z-index: 45; transform: none; border: 1px solid var(--hu-panel-border); border-radius: 18px; background: var(--hu-panel); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); overflow-y: auto; padding: var(--s-4); display: grid; gap: var(--s-5); align-content: start; box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.9); animation: lpanel-in 220ms var(--ease-out) both; }
body.game .side[hidden] { display: none; }

/* ---- The stage: the lobby HUD or a glass panel ---- */
.stage { position: fixed; inset: calc(var(--top-h) + env(safe-area-inset-top, 0px)) 0 calc(var(--dock-h) + env(safe-area-inset-bottom, 0px)) 0; z-index: 10; overflow: hidden; }
.stage__view { position: absolute; inset: 0; }
body.game.is-panel .stage__view { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 10px 22px 24px; }
/* Every non-lobby view sits in one glass panel. The view's own content (cards, forms) keeps its styles. */
/* Grid children default to min-width:auto, so one unbreakable row would widen every sibling past a phone; never. */
body.game.is-panel .stage__view > .panel > * { min-width: 0; }
body.game .read-bar { margin: 0; }
body.game.is-panel .stage__view { overflow-x: hidden; }
body.game.is-panel .stage__view > .panel { max-width: 1180px; margin: 0 auto; padding: var(--s-6) var(--s-6) var(--s-7); border-radius: 22px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); box-shadow: 0 40px 100px -40px rgba(0, 0, 0, 0.9); display: grid; gap: var(--s-5); animation: lpanel-in 260ms var(--ease-out) both; }
body.game .read-bar { position: absolute; top: 0; left: 0; right: 0; z-index: 12; }
/* Full-bleed sections from the older layout become ordinary blocks inside the panel. */
body.game .lob, body.game .hub, body.game .hall { margin: 0; border-radius: 18px; min-height: 0; }
body.game .hall { min-height: 70vh; }
body.game .hub { min-height: 60vh; }

/* ---- The lobby HUD (views/lobby.js) ---- */
/* app.css still carries an older `.hud` card style; the lobby HUD is a transparent layer over the world. */
body.game:not(.is-panel) .hud { position: absolute; inset: 0; pointer-events: none; display: block; overflow: visible; padding: 0; border: 0; background: none; box-shadow: none; border-radius: 0; }
body.game:not(.is-panel) .hud > * { pointer-events: auto; }
.hud__left { position: absolute; left: 22px; top: 6px; bottom: 0; width: clamp(320px, 27vw, 400px); display: grid; gap: 14px; align-content: start; }
.hud__right { position: absolute; right: 22px; top: 6px; width: clamp(260px, 21vw, 320px); display: grid; gap: 14px; }
/* The badge spans the rail like the front page's operator badge: face, then name and rank, then one meta line. */
.badge { display: grid; grid-template-columns: 48px minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 12px; row-gap: 2px; align-items: center; padding: 8px 12px; border-radius: 14px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.badge > div:not(.badge__meta) { display: grid; }
.badge__face { grid-row: 1 / 3; width: 48px; height: 48px; border-radius: 50%; object-fit: cover; object-position: 50% 12%; background: var(--hu-navy-900); box-shadow: 0 0 0 2px rgba(56, 165, 255, 0.8); }
.badge__name { font-weight: 900; font-size: 1.1rem; letter-spacing: 0.02em; text-transform: uppercase; line-height: 1; color: #fff; cursor: pointer; background: none; border: 0; padding: 0; font-family: inherit; text-align: left; }
.badge__name.is-unnamed { color: var(--hu-blue-400); }
.badge__rank { display: inline-flex; align-items: center; gap: 8px; margin-top: 4px; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(234, 245, 255, 0.75); }
.hud__welcome { display: grid; gap: 8px; }
.hud__over { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(234, 245, 255, 0.85); text-shadow: 0 1px 8px rgba(0, 0, 0, 0.8); }
body.game:not(.is-panel) .hud__title { margin: 0; font-size: clamp(2.2rem, 3.6vw, 3.4rem); line-height: 0.98; font-weight: 800; letter-spacing: -0.02em; color: #fff; text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6), 0 12px 40px rgba(0, 0, 0, 0.8); text-wrap: balance; }
.hud__cta { display: inline-flex; align-items: center; justify-content: center; min-height: 56px; padding: 0 34px; border-radius: 999px; background: linear-gradient(180deg, #4db2ff, #1467ef 60%, #0f55d6); color: #fff; font-weight: 800; font-size: 1.15rem; text-decoration: none; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25), 0 0 40px rgba(34, 132, 255, 0.7), 0 12px 30px -10px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.45); transition: filter 150ms, transform 100ms; justify-self: start; }
.hud__cta:hover { filter: brightness(1.12); }
.hud__cta:active { transform: scale(0.98); }
.hud__obj { display: grid; gap: 2px; padding: 10px 12px; border-radius: 14px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.hud__obj-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; }
.hud__obj a { display: grid; grid-template-columns: 18px 1fr; gap: 10px; align-items: center; padding: 5px 4px; color: #fff; text-decoration: none; font-size: 0.86rem; border-radius: 8px; }
.hud__obj a:hover { background: rgba(255, 255, 255, 0.07); }
.hud__obj i { width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, 0.35); display: grid; place-items: center; font-style: normal; font-size: 10px; font-weight: 800; }
.hud__obj .is-done a { color: rgba(234, 245, 255, 0.55); text-decoration: line-through; }
.hud__obj .is-done i { border-color: var(--money); background: rgba(61, 220, 132, 0.2); color: var(--money); }
.cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cards a, .cards div { display: grid; grid-template-columns: 44px 1fr; grid-template-rows: auto auto; column-gap: 10px; align-items: center; padding: 10px 12px; border-radius: 14px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); color: #fff; text-decoration: none; transition: transform 160ms var(--ease-out), border-color 160ms; }
.cards a:hover { transform: translateY(-3px); border-color: rgba(56, 165, 255, 0.9); }
.cards img { grid-row: 1 / 3; width: 44px; height: 44px; object-fit: contain; }
.cards b { font-size: 1.5rem; line-height: 1; font-weight: 800; }
.cards span { font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(234, 245, 255, 0.72); }
.explore { display: block; position: relative; border-radius: 16px; overflow: hidden; border: 1px solid var(--hu-panel-border); box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.9); text-decoration: none; color: #fff; aspect-ratio: 16 / 10; transition: transform 200ms var(--ease-out); }
.explore:hover { transform: translateY(-3px) scale(1.01); }
.explore img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease-out); }
.explore:hover img { transform: scale(1.05); }
.explore__bar { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: linear-gradient(180deg, transparent, rgba(6, 16, 39, 0.9)); font-weight: 800; font-size: 0.85rem; letter-spacing: 0.06em; text-transform: uppercase; }
.explore__bar i { width: 22px; height: 22px; border-radius: 6px; background: var(--hu-blue-600); display: grid; place-items: center; font-style: normal; font-size: 12px; }
.next-class { padding: 12px 14px; border-radius: 14px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); display: grid; gap: 4px; color: #fff; text-decoration: none; }
.next-class b { font-size: 1rem; }
.next-class span { font-size: 0.8rem; color: rgba(234, 245, 255, 0.75); }
.hud__sex { position: absolute; right: 22px; bottom: 14px; display: inline-flex; padding: 3px; border-radius: 999px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); }
.hud__sex button { font: inherit; font-size: 0.75rem; font-weight: 800; color: rgba(255, 255, 255, 0.7); background: none; border: 0; padding: 6px 14px; border-radius: 999px; cursor: pointer; }
.hud__sex button { min-height: 32px; }
/* #2563eb under white text is 5.2:1 (the lighter blue was 3.6:1, WCAG 1.4.3). */
.hud__sex button[aria-pressed="true"] { background: #2563eb; color: #fff; box-shadow: var(--hu-glow); }
.hud__equipped { position: absolute; left: 50%; bottom: 14px; transform: translateX(calc(-50% + 180px)); display: flex; gap: 6px; }
.hud__equipped img { width: 44px; height: 44px; padding: 4px; border-radius: 10px; background: var(--hu-panel); border: 1px solid rgba(56, 165, 255, 0.7); box-shadow: var(--hu-glow); }

/* ---- The dock ---- */
.dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; height: calc(var(--dock-h) + env(safe-area-inset-bottom, 0px)); padding: 10px 22px calc(12px + env(safe-area-inset-bottom, 0px)); display: flex; gap: 10px; justify-content: flex-start; align-items: stretch; background: linear-gradient(180deg, rgba(6, 16, 39, 0), rgba(6, 16, 39, 0.8)); overflow-x: auto; scrollbar-width: none; }
.dock::-webkit-scrollbar { display: none; }
.dock a { flex: 0 0 auto; width: 124px; display: grid; justify-items: center; align-content: center; gap: 4px; border-radius: 16px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); color: #fff; text-decoration: none; font-weight: 800; font-size: 0.78rem; letter-spacing: 0.04em; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: transform 160ms var(--ease-out), border-color 160ms, box-shadow 160ms; }
.dock a img { width: 60px; height: 60px; object-fit: contain; transition: transform 200ms var(--ease-out), filter 200ms; }
.dock a:hover, .dock a:focus-visible { transform: translateY(-4px); border-color: rgba(56, 165, 255, 0.95); box-shadow: var(--hu-glow); outline: none; }
.dock a:hover img { transform: scale(1.1); filter: drop-shadow(0 0 10px rgba(56, 165, 255, 0.9)); }
.dock a.is-active { border-color: rgba(56, 165, 255, 0.95); box-shadow: var(--hu-glow), inset 0 0 0 1px rgba(56, 165, 255, 0.5); }

/* Craig's button is the last tile of the dock (round 39b; main.js moves it in), pushed to the right end, so nothing floats
   over the page: before, the pill sat above the dock and covered the bottom cards of the Classroom at 900px tall (WCAG
   2.4.11). It hides with the dock (phones have Ask Craig in the phone bar; the Hall has it in its own bar). */
body.game .dock .guide__toggle { position: relative; right: auto; bottom: auto; flex: 0 0 auto; margin-left: auto; width: 124px; height: auto; padding: 6px; display: grid; justify-items: center; align-content: center; gap: 4px; border-radius: 16px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); box-shadow: none; font-size: 0.78rem; font-weight: 800; letter-spacing: 0.04em; }
body.game .dock .guide__toggle img { width: 52px; height: 52px; }
body.game .dock .guide__toggle:hover, body.game .dock .guide__toggle:focus-visible { transform: translateY(-4px); border-color: rgba(56, 165, 255, 0.95); box-shadow: var(--hu-glow); }
body.game .dock .guide__toggle:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
body.game .dock .guide__toggle[aria-expanded="true"] { border-color: rgba(56, 165, 255, 0.95); box-shadow: var(--hu-glow), inset 0 0 0 1px rgba(56, 165, 255, 0.5); }
body.game:not(.is-panel):not(.is-hall):not(.is-room) .dock .guide__toggle { background: rgba(6, 16, 39, 0.52); border-color: rgba(190, 220, 255, 0.45); }
body.game .guide { bottom: calc(var(--dock-h) + 8px); right: 22px; }
@media (max-width: 1280px) and (min-width: 761px) {
  .dock a, body.game .dock .guide__toggle { width: 100px; }
  .dock a img { width: 50px; height: 50px; }
  body.game .dock .guide__toggle img { width: 44px; height: 44px; }
  .dock { gap: 8px; }
}
@media (max-width: 1000px) and (min-width: 761px) { .dock a, body.game .dock .guide__toggle { width: 86px; font-size: 0.7rem; } .dock { padding-inline: 12px; } }
@media (max-height: 760px) and (min-width: 761px) { body.game .dock .guide__toggle img { width: 40px; height: 40px; } }

/* ---- Responsive ---- */
@media (max-width: 1100px) { .tabs a { padding: 9px 12px; font-size: 0.74rem; } .hud__right { display: none; } .hud__left { width: min(360px, 44vw); } }
@media (max-width: 760px) {
  body.game { --top-h: 60px; --dock-h: 96px; }
  .top { grid-template-columns: auto minmax(0, 1fr) auto; padding-inline: 12px; }
  .tabs { display: none; }
  .top__right { justify-self: end; }
  .hud__left { left: 12px; right: 12px; width: auto; top: auto; bottom: 10px; gap: 8px; }
  .hud__title { font-size: 1.8rem; }
  .cards { grid-template-columns: repeat(4, 1fr); gap: 6px; }
  .cards a, .cards div { grid-template-columns: 1fr; justify-items: center; text-align: center; padding: 8px 4px; }
  .cards img { grid-row: auto; width: 32px; height: 32px; }
  .cards b { font-size: 1.1rem; }
  .hud__obj { display: none; }
  .hud__sex { right: 12px; top: 6px; bottom: auto; }
  .hud__equipped { display: none; }
  .dock { padding-inline: 10px; }
  .dock a { width: 86px; font-size: 0.68rem; }
  .dock a img { width: 44px; height: 44px; }
  body.game.is-panel .stage__view { padding: 8px 10px 16px; }
  body.game.is-panel .stage__view > .panel { padding: var(--s-4); border-radius: 16px; }
  body.game .side { right: 10px; left: 10px; width: auto; }
}
@media (prefers-reduced-motion: reduce) { .world__scene { display: none; } .world__op img, .world__blimp { animation: none; } }

/* =====================================================================
   The lecture hall (views/hall.js). The plate is the world; these are the
   working parts laid on it. Positions come from the script, in the
   photograph's own coordinates.
   ===================================================================== */
body.game.is-hall .dock { display: none; }
body.game.is-hall .stage { bottom: 0; }
body.game.is-hall .guide__toggle { display: none; } /* the bar has Ask Craig */
body.game.is-hall .guide { bottom: 132px; }
/* Immersive: just the room, the screen, the seats and the bar. */
body.is-immersive .top, body.is-immersive .hall__chat, body.is-immersive .guide__toggle { display: none; }
body.is-immersive .stage { top: 0; }

.hall { position: absolute; inset: 0; pointer-events: none; }
.hall > * { pointer-events: auto; }

/* The screen on the stage: laid out flat at 1000×562, then carried onto the photograph's screen by matrix3d. */
.hall__screen { position: fixed; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.screen { position: absolute; inset: 0; display: grid; grid-template-columns: minmax(0, 1fr) 280px; background: #05070d; color: #fff; overflow: hidden; }
.screen__video { width: 100%; height: 100%; object-fit: cover; display: block; background: #000; }
.screen__face { position: relative; overflow: hidden; }
.screen__art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.9; }
.screen__copy { position: absolute; inset: 0; display: grid; align-content: end; gap: 10px; padding: 36px 40px; background: linear-gradient(90deg, rgba(5, 7, 13, 0.92) 0%, rgba(5, 7, 13, 0.55) 45%, transparent 80%), linear-gradient(0deg, rgba(5, 7, 13, 0.9), transparent 60%); }
.screen__module { font-size: 13px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--hu-blue-400); font-weight: 800; }
.screen__copy h2 { margin: 0; font-size: 52px; line-height: 1; font-weight: 900; letter-spacing: -0.02em; max-width: 12ch; text-wrap: balance; }
.screen__play { display: grid; place-items: center; width: 74px; height: 74px; border-radius: 50%; background: linear-gradient(180deg, var(--hu-blue-400), var(--hu-blue-600)); color: #fff; text-decoration: none; font-size: 26px; box-shadow: 0 0 0 6px rgba(56, 165, 255, 0.25), 0 20px 40px -12px rgba(20, 103, 239, 0.9); transition: transform 180ms var(--ease-out); }
.screen__play i { font-style: normal; margin-left: 4px; }
.screen__play:hover { transform: scale(1.08); text-decoration: none; color: #fff; }
.screen__count { font-size: 14px; color: rgba(255, 255, 255, 0.8); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700; }
.screen__side { display: grid; grid-template-rows: auto 1fr; gap: 10px; padding: 22px 20px; background: rgba(10, 16, 32, 0.96); border-left: 1px solid rgba(144, 195, 255, 0.25); min-width: 0; }
.screen__label { font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255, 255, 255, 0.7); font-weight: 800; }
.screen__plan { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; align-content: start; overflow: hidden; }
.screen__plan a { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 10px; color: #fff; text-decoration: none; font-size: 13.5px; font-weight: 700; background: rgba(255, 255, 255, 0.04); }
.screen__plan a span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.screen__plan a:hover { background: rgba(56, 165, 255, 0.18); text-decoration: none; color: #fff; }
.screen__plan i { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: rgba(255, 255, 255, 0.12); font-style: normal; font-size: 11px; }
.screen__plan small { font-size: 12px; color: rgba(255, 255, 255, 0.6); }
.screen__plan .is-done i { background: var(--hu-blue-600); }
.screen__plan .is-next a { background: rgba(56, 165, 255, 0.22); box-shadow: inset 0 0 0 1px rgba(56, 165, 255, 0.6); }
.screen__plan .is-next i { background: #fff; color: var(--hu-blue-600); }

/* The Dean at the lectern: a foreground cut of the plate, above the screen. */
.hall__dean { position: fixed; pointer-events: none; z-index: 2; object-fit: fill; }

/* Seats on the front row. */
.hall__seats { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.pew { position: fixed; aspect-ratio: auto; width: auto; height: auto; line-height: 1.2; transform: translate(-50%, -100%); pointer-events: auto; display: grid; justify-items: center; gap: 2px; min-width: 64px; padding: 6px 8px 8px; border: 1px solid var(--hu-panel-border); border-radius: 12px; background: var(--hu-panel); color: #fff; font: inherit; cursor: pointer; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); transition: border-color 160ms, box-shadow 240ms, transform 160ms; }
.pew::after { content: ""; position: absolute; left: 50%; bottom: -18px; width: 54px; height: 14px; transform: translateX(-50%); border-radius: 50%; border: 2px solid rgba(56, 165, 255, 0.0); transition: border-color 240ms, box-shadow 240ms; }
.pew:hover { border-color: var(--hu-blue-400); transform: translate(-50%, -100%) translateY(-3px); }
.pew__open { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255, 255, 255, 0.7); padding: 6px 2px; }
.pew.is-mine { border-color: var(--hu-blue-400); box-shadow: 0 0 0 1px rgba(56, 165, 255, 0.5), 0 0 34px -4px rgba(56, 165, 255, 0.9); cursor: default; }
.pew.is-mine::after { border-color: rgba(56, 165, 255, 0.9); box-shadow: 0 0 24px rgba(56, 165, 255, 0.9), inset 0 0 12px rgba(56, 165, 255, 0.6); animation: seat-pulse 2.4s ease-in-out infinite; }
@keyframes seat-pulse { 50% { box-shadow: 0 0 10px rgba(56, 165, 255, 0.5), inset 0 0 4px rgba(56, 165, 255, 0.3); } }
.pew.is-mine img { width: 44px !important; height: 44px !important; border-radius: 50%; object-fit: cover; object-position: 50% 6%; border: 2px solid var(--hu-blue-400); background: #0b1a3d; }
.pew.is-mine b { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; }
.pew__hand { position: absolute; right: -8px; top: -16px; font-size: 1.5rem; opacity: 0; transform: translateY(8px); transition: opacity 200ms, transform 200ms; }
.pew.is-hand .pew__hand { opacity: 1; transform: none; animation: wave 1.2s ease-in-out infinite; }
.pew.is-hand { border-color: #fff; }
.pew__react { position: absolute; left: 50%; top: -6px; transform: translateX(-50%); font-size: 1.8rem; animation: react-up 1.5s var(--ease-out) forwards; pointer-events: none; }
@keyframes react-up { to { transform: translate(-50%, -90px) scale(1.3); opacity: 0; } }

/* The class chat, docked right. */
.hall__chat { position: absolute; right: 16px; top: 10px; bottom: 74px; width: min(240px, 22vw); display: grid; grid-template-rows: auto 1fr auto; border-radius: 16px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); overflow: hidden; z-index: 4; animation: lpanel-in 240ms var(--ease-out) both; }
.hall__chat .chat__head { display: flex; justify-content: space-between; align-items: center; padding: 12px 14px; border-bottom: 1px solid rgba(144, 195, 255, 0.2); }
.chat__online { display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: rgba(255, 255, 255, 0.8); }
.chat__online i { width: 7px; height: 7px; border-radius: 50%; background: var(--money); box-shadow: 0 0 8px var(--money); }
.hall__chat .chat__feed { overflow-y: auto; padding: 12px 14px; display: grid; gap: 10px; align-content: start; }
.hall__chat .chat__msg { display: grid; gap: 2px; font-size: 0.86rem; }
.hall__chat .chat__msg b { color: var(--hu-blue-400); font-size: 0.78rem; }
.hall__chat .chat__msg--sys { color: rgba(255, 255, 255, 0.65); font-style: italic; }
.hall__chat .chat__sys { font-size: 0.78rem; color: rgba(255, 255, 255, 0.65); line-height: 1.4; }
.hall__chat .chat__row { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 10px; border-top: 1px solid rgba(144, 195, 255, 0.2); }

/* The action bar across the bottom. */
.hall__bar { position: absolute; left: 22px; right: 22px; bottom: 12px; display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 14px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); z-index: 5; overflow-x: auto; scrollbar-width: none; }
.bar__you { display: grid; line-height: 1.15; padding: 0 10px 0 4px; white-space: nowrap; }
.bar__you b { font-size: 0.86rem; text-transform: uppercase; letter-spacing: 0.08em; }
.bar__you span { font-size: 0.7rem; color: rgba(255, 255, 255, 0.7); }
.bar__react { display: inline-flex; gap: 2px; padding: 2px; border-radius: 999px; background: rgba(255, 255, 255, 0.07); }
.bar__react button { font: inherit; font-size: 1.1rem; background: none; border: 0; width: 38px; height: 34px; border-radius: 999px; cursor: pointer; transition: transform 140ms var(--ease-out), background 140ms; }
.bar__react button:hover { transform: scale(1.2); background: rgba(56, 165, 255, 0.25); }
.bar__btn { font: inherit; font-size: 0.8rem; font-weight: 800; color: #fff; background: rgba(255, 255, 255, 0.07); border: 1px solid transparent; border-radius: 10px; padding: 8px 12px; cursor: pointer; text-decoration: none; white-space: nowrap; transition: background 140ms, border-color 140ms; }
.bar__btn:hover { background: rgba(56, 165, 255, 0.22); border-color: var(--hu-blue-400); color: #fff; text-decoration: none; }
.bar__btn--hand[aria-pressed="true"] { background: #fff; color: var(--hu-blue-600); }
.bar__btn--leave { margin-left: auto; border-color: rgba(255, 122, 131, 0.5); }
.bar__btn--leave:hover { background: rgba(255, 77, 90, 0.25); border-color: var(--red-hot); }

/* Narrow screens: the picture stays behind; the screen and the chat stack as blocks. */
.hall.is-stacked { position: static; display: grid; grid-template-rows: max-content minmax(240px, 1fr) max-content; grid-auto-rows: max-content; gap: 12px; padding: 10px 12px 0; overflow-y: auto; height: 100%; align-content: start; }
.hall.is-stacked .hall__screen { position: relative; width: 100% !important; height: auto !important; aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden; }
.hall.is-stacked .screen { grid-template-columns: 1fr; }
.hall.is-stacked .screen__side { display: none; }
.hall.is-stacked .screen__copy { padding: 14px; gap: 8px; }
.hall.is-stacked .screen__copy h2 { font-size: 22px; }
.hall.is-stacked .screen__module { font-size: 10px; }
.hall.is-stacked .screen__count { font-size: 10px; }
.hall.is-stacked .screen__play { width: 52px; height: 52px; font-size: 18px; }
.hall.is-stacked .hall__dean, .hall.is-stacked .hall__seats { display: none; }
.hall.is-stacked .hall__chat { position: relative; right: auto; top: auto; bottom: auto; width: auto; height: auto; min-height: 0; }
/* The bar is the last block, held at the bottom of the scroll: two rows that wrap, never a strip that runs off the screen. */
.hall.is-stacked .hall__bar { position: sticky; left: auto; right: auto; bottom: 0; margin: 0 -12px; border-radius: 14px 14px 0 0; flex-wrap: wrap; justify-content: center; overflow: visible; padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px)); }
.hall.is-stacked .bar__you, .hall.is-stacked .bar__btn--immersive { display: none; }
.hall.is-stacked .bar__react { flex: 1 1 100%; justify-content: space-between; }
.hall.is-stacked .bar__react button { flex: 1; height: 44px; }
.hall.is-stacked .bar__btn { flex: 1 1 0; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; text-align: center; }
.hall.is-stacked .bar__btn--leave { margin-left: 0; }
body.game.is-hall .stage__view { overflow: hidden; }

/* =====================================================================
   Loading Screen guide additions: badge meta, the six-card cluster, the
   rotating feature panel, presence, recent wins, the profile chip.
   ===================================================================== */
.tabs a.tabs__play { padding-inline: 22px; }
.chip--profile { width: 44px; padding: 3px; justify-content: center; }
.chip--profile img { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; object-position: 50% 10%; background: #0b1a3d; box-shadow: 0 0 0 2px rgba(56, 165, 255, 0.8); }

.badge__meta { grid-column: 2; display: flex; gap: 10px; align-items: center; flex-wrap: nowrap; white-space: nowrap; overflow: hidden; margin-top: 2px; font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(234, 245, 255, 0.72); }
.badge__streak { display: inline-flex; align-items: center; gap: 4px; }
.badge__streak i { font-style: normal; filter: grayscale(1) opacity(0.6); }
.badge__streak.is-lit i { filter: none; }
.badge__streak b { color: #fff; font-size: 0.8rem; }
.badge__chapter { color: var(--hu-blue-400); }

/* White → blue gradient hero text (guide §4). */
body.game:not(.is-panel) .hud__title { background: linear-gradient(180deg, #fff 45%, #9fd2ff 100%); -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent; filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.7)); text-shadow: none; }
.hud__sub { font-size: 0.86rem; color: rgba(234, 245, 255, 0.85); text-shadow: 0 1px 8px rgba(0, 0, 0, 0.8); }
.hud__cta > span { position: relative; z-index: 1; }

.cards--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.cards--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.hud__more { justify-self: start; display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 14px; border-radius: 999px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); color: #fff; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.02em; text-decoration: none; transition: border-color 160ms, background 160ms; }
.hud__more:hover { text-decoration: none; color: #fff; border-color: var(--hu-blue-400); background: rgba(56, 165, 255, 0.16); }
.cards--6 a { grid-template-columns: 36px 1fr; padding: 8px 10px; column-gap: 8px; min-width: 0; }
.cards--6 img { width: 36px; height: 36px; }
.cards--6 b { font-size: 1.2rem; white-space: nowrap; }
.cards--6 span { font-size: 0.58rem; letter-spacing: 0.12em; }

@media (max-height: 820px) { .hud__left { gap: 10px; } .hud__obj a { padding: 3px 4px; font-size: 0.8rem; } .cards--6 a { padding: 6px 8px; } }
@media (max-width: 760px) { .cards--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* =====================================================================
   Main Lobby Master additions: the next-step card, the class-wait card,
   the airship layer, the phone navigation and the stacked phone lobby.
   ===================================================================== */
.chip__word { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(234, 245, 255, 0.75); }
.nextcard { padding: 16px 18px; border-radius: 16px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); display: grid; gap: 10px; }
.nextcard .hud__title { font-size: clamp(1.8rem, 2.6vw, 2.4rem); }
.nextcard__line { margin: 0; font-size: 0.92rem; color: rgba(234, 245, 255, 0.85); }
.nextcard__foot { font-size: 0.72rem; color: rgba(234, 245, 255, 0.6); }
.nextcard .hud__cta { justify-self: start; }

.feature--class .feature__row { display: flex; gap: 10px; align-items: center; margin-top: 4px; }
.feature__btn { display: inline-flex; align-items: center; min-height: 36px; padding: 0 14px; border-radius: 10px; background: linear-gradient(180deg, var(--hu-blue-400), var(--hu-blue-600)); color: #fff; font-weight: 800; font-size: 0.8rem; text-decoration: none; }
.feature__btn.is-off { background: rgba(255, 255, 255, 0.1); color: rgba(234, 245, 255, 0.6); cursor: not-allowed; }
.feature__link { color: #fff; font-size: 0.8rem; text-decoration: underline; text-underline-offset: 3px; }

/* The airship (Main Lobby Master §06): Class of 2027 on the hull, the crest on the tail. It sits inside the lobby's 16:9 art
   box, so its spot in the sky of the photograph is the same at every window size (same spot as the front page). */
.world__blimp { --blimp-clear: calc(var(--top-h) + 16px); position: absolute; left: 66%; top: max(calc(0.14 * max(75cqw, 100cqh)), calc(max(75cqw, 100cqh) - 100cqh + var(--blimp-clear))); width: 10%; height: auto; filter: drop-shadow(0 18px 24px rgba(6, 16, 39, 0.35)); animation: blimp-drift 110s ease-in-out infinite alternate; pointer-events: none; }
@keyframes blimp-drift { from { transform: translate(0, 0) rotate(0.2deg); } to { transform: translate(-6%, 1%) rotate(-0.4deg); } }
body.is-hall .world__blimp, body.is-panel .world__blimp, body.is-room .world__blimp { display: none; }
@media (max-width: 1279px) and (min-width: 761px) { .world__blimp { display: none; } }

/* The operator: the member's own character as a foreground layer, like the dean in the hall. Rendered at 2K on its own so the
   face carries real pixels at any viewport (plate 10: a close-up asset must carry real detail, not an enlarged face). */
.world__op { position: absolute; left: 50%; bottom: calc(var(--dock-h) - 10px); height: min(66vh, 900px); transform: translateX(26%); pointer-events: none; transform-origin: 50% 100%; }
.world__op img { display: block; height: 100%; width: auto; filter: drop-shadow(0 14px 10px rgba(6, 16, 39, 0.35)); animation: op-breathe 7s ease-in-out infinite; transform-origin: 50% 100%; }
.world__op::after { content: ""; position: absolute; left: 50%; bottom: -1.2%; width: 70%; height: 4%; transform: translateX(-50%); border-radius: 50%; background: radial-gradient(ellipse at center, rgba(6, 16, 39, 0.55), rgba(6, 16, 39, 0) 70%); z-index: -1; }
@keyframes op-breathe { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(1.006); } }
body.is-hall .world__op { display: none; }
body.is-panel .world__op { opacity: 0.55; }

/* Phone navigation: short, plus More. Hidden on wide screens where the dock lives. */
.phonenav { display: none; }
@media (max-width: 760px) {
  body.game { --dock-h: 72px; }
  .dock { display: none; }
  .phonenav { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; display: grid; grid-template-columns: repeat(5, 1fr); height: calc(72px + env(safe-area-inset-bottom, 0px)); padding: 6px 8px env(safe-area-inset-bottom, 0px); background: rgba(5, 15, 37, 0.9); border-top: 1px solid var(--hu-panel-border); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
  .phonenav a, .phonenav button { display: grid; justify-items: center; gap: 2px; min-height: 44px; color: #fff; text-decoration: none; font: inherit; font-size: 0.68rem; font-weight: 800; background: none; border: 0; padding: 4px 0; border-radius: 10px; }
  .phonenav img { width: 32px; height: 32px; object-fit: contain; }
  .phonenav a.is-active { color: var(--hu-blue-400); }
  .phonenav .phonenav__face { border-radius: 50%; object-fit: cover; object-position: 50% 12%; background: #0b1a3d; box-shadow: 0 0 0 2px rgba(56, 165, 255, 0.8); }
  body.game .guide__toggle { display: none; }
  /* The lobby stacks: a compact scene on top, the lesson action and class state in normal flow (plate 19). */
  body.game:not(.is-panel):not(.is-hall) .stage__view { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  body.game:not(.is-panel):not(.is-hall) .hud { position: static; display: grid; gap: 12px; padding: 40vh 12px 16px; pointer-events: auto; }
  .hud__left, .hud__right { position: static; width: auto; }
  .hud__sex { position: static; justify-self: start; }
  .hud__equipped { position: static; }
  .cards--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .world__blimp { left: 65%; top: 13%; width: 15%; }
  .world__op { left: 58%; bottom: auto; top: 13vh; height: 44vh; transform: translateX(-50%); }
  body.game:not(.is-panel) .world__veil { background: linear-gradient(180deg, rgba(6, 16, 39, 0.35), transparent 14%, transparent 34%, rgba(6, 16, 39, 0.85) 48%, var(--hu-navy-950) 100%); }
}
@media (max-width: 760px) {
  .top__right { gap: 6px; }
  .top__right .hide-phone, .chip__word, .top__right .streak { display: none !important; }
  .chip--credits { padding-inline: 8px; }
  body.game .guide { bottom: calc(72px + env(safe-area-inset-bottom, 0px) + 76px); }
  /* The hall keeps the phone bar, so its view stops above it; Craig is in the phone bar, not the hall's. */
  body.game.is-hall .stage { bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
  .hall.is-stacked .bar__btn--craig { display: none; }
}

/* =====================================================================
   Craig 2.0 (guide/index.js): the docked panel, its states, the context
   banner, push-to-talk and the phone sheet. Its height never reaches past
   the top bar (on short windows 100vh - 110px did, by up to 44px).
   ===================================================================== */
body.game .guide { grid-template-rows: auto auto 1fr auto auto; width: min(420px, calc(100vw - 32px)); height: min(600px, calc(100vh - 110px)); max-height: calc(100vh - var(--top-h) - var(--dock-h) - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 24px); border-radius: 18px; background: var(--hu-panel); border: 1px solid var(--hu-panel-border); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); overflow: hidden; }
.guide__right { display: inline-flex; align-items: center; gap: 8px; }
.guide__status { font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(234, 245, 255, 0.7); }
.guide[data-state="listening"] .guide__status { color: var(--money); }
.guide[data-state="thinking"] .guide__status { color: var(--hu-blue-400); }
.guide[data-state="speaking"] .guide__status { color: #fff; }
.guide[data-state="error"] .guide__status { color: var(--red-hot); }
.guide__avatar { position: relative; display: inline-grid; place-items: center; }
.guide__halo { position: absolute; inset: -5px; border-radius: 50%; border: 2px solid rgba(56, 165, 255, 0); pointer-events: none; transition: border-color 200ms; }
.guide[data-state="listening"] .guide__halo { border-color: var(--money); animation: halo-breathe 1.2s ease-in-out infinite; }
.guide[data-state="thinking"] .guide__halo { border-color: var(--hu-blue-400); border-top-color: transparent; animation: halo-orbit 1s linear infinite; }
.guide[data-state="speaking"] .guide__halo { border-color: var(--hu-blue-400); animation: halo-breathe 0.6s ease-in-out infinite; }
@keyframes halo-breathe { 50% { transform: scale(1.12); opacity: 0.6; } }
@keyframes halo-orbit { to { transform: rotate(360deg); } }
.guide__context { display: grid; gap: 2px; padding: 8px 14px; background: rgba(20, 103, 239, 0.16); border-bottom: 1px solid rgba(144, 195, 255, 0.2); font-size: 0.8rem; font-weight: 700; }
.guide__context small { font-weight: 500; color: rgba(234, 245, 255, 0.65); font-size: 0.7rem; }
.guide__tools { display: flex; gap: 6px; padding: 6px 12px 0; }
.guide__tool { font: inherit; font-size: 0.72rem; font-weight: 700; color: #fff; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(144, 195, 255, 0.25); border-radius: 8px; padding: 5px 10px; min-height: 30px; cursor: pointer; }
.guide__tool[aria-pressed="true"] { background: rgba(56, 165, 255, 0.25); border-color: var(--hu-blue-400); }
.guide__tool[hidden] { display: none; }
.guide__talk { display: inline-flex; align-items: center; gap: 6px; min-width: 44px; min-height: 44px; padding: 0 12px; border-radius: 12px; border: 1px solid var(--hu-panel-border); background: rgba(255, 255, 255, 0.08); color: #fff; font: inherit; font-size: 0.8rem; font-weight: 800; cursor: pointer; }
.guide__talk i { width: 10px; height: 10px; border-radius: 50%; background: rgba(255, 255, 255, 0.5); }
.guide__talk[aria-pressed="true"] { background: rgba(61, 220, 132, 0.2); border-color: var(--money); }
.guide__talk[aria-pressed="true"] i { background: var(--money); box-shadow: 0 0 10px var(--money); animation: halo-breathe 1s ease-in-out infinite; }
.guide__cites { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.guide__cites a { font-size: 0.7rem; color: var(--hu-blue-400); text-decoration: underline; text-underline-offset: 2px; }
.guide__toggle[data-state="speaking"] img, .guide__toggle[data-state="listening"] img { box-shadow: 0 0 0 3px var(--hu-blue-400); }
@media (max-width: 760px) {
  body.game .guide { left: 0; right: 0; bottom: 0; width: auto; height: min(78vh, 640px); max-height: none; border-radius: 18px 18px 0 0; padding-bottom: env(safe-area-inset-bottom, 0px); z-index: 70; }
}

/* The Avatar Studio: the panel keeps to the left, the operator stands on the studio backdrop at the right. */
body.game.is-studio .stage__view > .panel { max-width: 640px; margin: 0 0 0 0; }
body.game.is-studio .world__op { display: block; opacity: 1; left: 72%; bottom: 13%; height: min(64vh, 900px); transform: translateX(-50%); }
body.game.is-studio .world__op::after { bottom: -0.8%; }
@media (max-width: 1100px) { body.game.is-studio .stage__view > .panel { max-width: none; } body.game.is-studio .world__op { display: none; } }

/* Keyboard focus on the dock and phone nav is a visible ring, not only a glow (WCAG 2.4.7). */
.dock a:focus-visible, .phonenav a:focus-visible, .tabs a:focus-visible, .chip:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.dock a:active { transform: translateY(-1px) scale(0.97); }

/* =====================================================================
   The frame: what keeps every piece in its place at every window size.
   ---------------------------------------------------------------------
   1. The lobby photograph is a 4:3 box (.world__art) that covers the screen
      and is anchored to its bottom edge with container units; the plaza runs
      under the dock, the operator's feet stay above it, and the airship keeps
      its spot in the sky.
   2. The top bar is one row at every width: words go first, then the streak,
      then the tabs (all of them are also in the menu).
   3. The lobby rail never reaches the dock: on short windows the dock gets
      smaller and the less important blocks step out, in a fixed order.
   ===================================================================== */
/* Very wide windows: the box slides down just enough to keep the operator's head below the top bar (head line at 35%). */
body.game:not(.is-panel):not(.is-hall):not(.is-room) .world__art { inset: auto; left: 50%; bottom: calc(-1 * max(0px, 0.65 * max(75cqw, 100cqh) - 100cqh + var(--top-h) + 16px)); width: max(100cqw, 133.33cqh); aspect-ratio: 4 / 3; transform: translateX(-50%); }
/* The dock stands on the plaza: no tray, glass doors, a soft shade low on the stones so they read. */
body.game:not(.is-panel):not(.is-hall):not(.is-room) .dock { background: none; }
body.game:not(.is-panel):not(.is-hall):not(.is-room) .dock a { background: rgba(6, 16, 39, 0.52); border-color: rgba(190, 220, 255, 0.45); box-shadow: 0 14px 22px -12px rgba(0, 0, 0, 0.65); }
body.game:not(.is-panel):not(.is-hall):not(.is-room) .world__veil { background: linear-gradient(180deg, rgba(6, 16, 39, 0.55), transparent 18%, transparent 78%, rgba(6, 16, 39, 0.4) 100%); }

/* 2. Top bar. */
@media (max-width: 1440px) { .chip__word { display: none; } }
@media (max-width: 1280px) { .top__right .streak { display: none; } }
@media (max-width: 1180px) { .top__right a[href="#/friends"] { display: none; } }
@media (max-width: 1000px) { .tabs { display: none; } .top__right { grid-column: 3; justify-self: end; } }

/* 3. Short windows. */
@media (max-height: 860px) and (min-width: 761px) { body.game:not(.is-panel) .hud .cards, body.game:not(.is-panel) .hud__more { display: none; } }
@media (max-height: 760px) and (min-width: 761px) {
  body.game { --dock-h: 92px; }
  .dock { padding-block: 8px calc(8px + env(safe-area-inset-bottom, 0px)); }
  .dock a img { width: 44px; height: 44px; }
}
@media (max-height: 640px) and (min-width: 761px) {
  .badge__meta, .nextcard__foot, .nextcard__line { display: none; }
  .nextcard { gap: 8px; padding: 12px 14px; }
  .nextcard .hud__title { font-size: 1.6rem; }
  .hud__cta { min-height: 46px; font-size: 1rem; }
}

@media (max-width: 760px) {
  /* Phones have no dock: the picture fills the top of the screen and the lesson panel follows in flow (plate 19). */
  body.game:not(.is-panel):not(.is-hall):not(.is-room) .world__ground { bottom: auto; height: 52vh; }
  body.game:not(.is-panel):not(.is-hall):not(.is-room) .world__art { left: 38%; }
  /* The cards start where the picture ends, so they never cover the operator. */
  body.game:not(.is-panel):not(.is-hall):not(.is-room) .hud { padding-top: calc(52vh - var(--top-h) - 8px); }
}

/* =====================================================================
   Round 39b — UX and flow: one name per place, the menu, focus, empty states.
   ===================================================================== */

/* Skip link: a button, first in the Tab order, shown only when focused (base.css .skip positions it). */
button.skip { border: 0; font: inherit; font-weight: 700; cursor: pointer; z-index: 120; }

/* The view scrolls, so it can take focus; its ring sits inside the panel edge instead of around the whole window. */
body.game .stage__view:focus { outline: none; }
body.game .stage__view:focus-visible { box-shadow: inset 0 0 0 2px rgba(56, 165, 255, 0.7); border-radius: 12px; }
/* A page heading that receives focus on arrival (main.js announce) shows no ring: it is not a control. */
h1[tabindex="-1"]:focus { outline: none; }
/* Focused content is never hidden under the dock or the top bar (WCAG 2.4.11): the scroller keeps a margin at both ends. */
body.game .stage__view { scroll-padding-block: 24px 32px; }

/* The streak chip is a door to the next lesson. Before the first day it says "start a streak" instead of 0. */
a.streak { color: #fff; text-decoration: none; }
a.streak:hover { text-decoration: none; color: #fff; }
.streak.is-empty .streak__n { display: none; }
.streak.is-empty .streak__l { color: var(--hu-blue-400); }

/* Points before the first point: the coin alone on phones, "Earn points" beside it on wider screens. Never a lone 0. */
.chip--credits.is-empty b { display: none; }
@media (min-width: 761px) { .chip--credits.is-empty .chip__word { display: inline; color: var(--hu-amber); } }

/* Phones: More in the phone bar is the menu, so the top bar's ☰ (the same drawer) steps out: one door, not two. */
@media (max-width: 760px) { #side-toggle { display: none; } }

/* Phone bar: "More" is a menu glyph in the icons' tile, not the Settings gear (Settings is a place with its own icon). */
.phonenav__more { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 9px; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(144, 195, 255, 0.35); color: #fff; }
.phonenav button[aria-expanded="true"] { color: var(--hu-blue-400); }
.phonenav button[aria-expanded="true"] .phonenav__more { border-color: var(--hu-blue-400); background: rgba(56, 165, 255, 0.2); }
.phonenav a:focus-visible, .phonenav button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* ---- The menu (main.js buildSide): grouped places with the dock's icons, the levels, a clean footer ---- */
body.game .side { gap: var(--s-4); padding: var(--s-3) var(--s-3) 0; overscroll-behavior: contain; }
body.game .side__group { gap: 2px; }
body.game .side__group > .label { padding: var(--s-2) var(--s-3) var(--s-1); color: rgba(234, 245, 255, 0.6); }
body.game .side a { grid-template-columns: 28px minmax(0, 1fr) auto; min-height: 44px; padding: 6px var(--s-3); color: rgba(234, 245, 255, 0.86); font-size: 0.92rem; border-radius: 12px; }
body.game .side a:hover { background: rgba(56, 165, 255, 0.12); color: #fff; }
body.game .side a.is-active { background: rgba(56, 165, 255, 0.18); color: #fff; box-shadow: inset 3px 0 0 var(--hu-blue-400); }
body.game .side a:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.side__icon { width: 28px; height: 28px; object-fit: contain; }
.side__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.game .side .side__n { justify-self: center; color: rgba(234, 245, 255, 0.55); }
body.game .side a.is-active .side__n { color: var(--hu-blue-400); }
/* The footer sticks to the bottom of the drawer: status on the left, the one action on the right, on one quiet bar. */
body.game .side__foot { position: sticky; bottom: 0; display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); flex-wrap: wrap; margin: 0 calc(-1 * var(--s-3)); padding: var(--s-3); border-top: 1px solid rgba(144, 195, 255, 0.22); background: linear-gradient(180deg, rgba(5, 15, 37, 0.92), rgba(5, 15, 37, 0.98)); color: rgba(234, 245, 255, 0.75); font-size: 0.78rem; line-height: 1.2; }
.sync-chip { display: inline-flex; align-items: center; gap: 8px; min-height: 32px; padding: 0 12px; border-radius: 999px; background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(144, 195, 255, 0.22); font-weight: 600; white-space: nowrap; }
.sync-chip__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--hu-amber); box-shadow: 0 0 8px rgba(245, 198, 124, 0.7); }
.sync-chip.is-account .sync-chip__dot { background: var(--money, #3ddc84); box-shadow: 0 0 8px rgba(61, 220, 132, 0.7); }
.side__replay { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 14px; border-radius: 10px; border: 1px solid rgba(144, 195, 255, 0.4); background: rgba(56, 165, 255, 0.12); color: #fff; font: inherit; font-size: 0.8rem; font-weight: 700; cursor: pointer; white-space: nowrap; transition: background 140ms, border-color 140ms; }
.side__replay:hover { background: rgba(56, 165, 255, 0.24); border-color: var(--hu-blue-400); }
.side__replay:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.side__replay-icon { font-size: 1rem; line-height: 1; }

/* The profile menu items meet the 44px touch target. */
.pmenu [role="menuitem"] { min-height: 40px; display: flex; align-items: center; }
.pmenu [role="menuitem"]:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

/* The tour's Skip is a real target (WCAG 2.5.8), not a 12px line of text. */
.tour__skip { min-height: 32px; padding: 0 10px; border-radius: 8px; }
.tour__skip:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.tour__title { font-size: var(--t-lg); line-height: 1.2; letter-spacing: -0.01em; }

/* Small text controls still get a 24px target (WCAG 2.5.8): the operator name in the badge and "Solo study". */
.badge__name { min-height: 24px; display: inline-flex; align-items: center; }
.feature__link { min-height: 24px; display: inline-flex; align-items: center; }
.badge__name:focus-visible, .feature__link:focus-visible, .hud__more:focus-visible, .hud__cta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* A top-bar chip that is a place lights like a tab when you are there (Points, Messages, Friends). */
.top__right .chip.is-active { border-color: rgba(56, 165, 255, 0.95); box-shadow: var(--hu-glow); }

/* ---- Toasts stand above the dock (R40 world overlays) ----
   components.css pins a toast 20px off the bottom of the window, which in the
   course app is on top of the dock (desktop) or the phone nav: it hid two room
   buttons, and on a phone its shrink-to-fit width broke a short line in two.
   It now floats a gap above whichever bar is there and takes the width its
   words need, never more than the window minus the gutters. */
body.game .toast { bottom: calc(var(--dock-h) + env(safe-area-inset-bottom, 0px) + 12px); width: max-content; max-width: calc(100vw - 32px); }

/* =====================================================================
   Round 40, the shell pass (defects-r40.md B2, H2, H10, H11, M24, L15).
   ===================================================================== */

/* B2. The dock never runs off the screen. Its nine tiles (eight rooms and Ask Craig) keep their full width while there is
   room and share what is left when there is not, so at 761-1000px every tile, Craig's included, stays inside the window:
   before, nine fixed 86px tiles overflowed an 820px iPad and the last label read "Ask Cr". */
@media (min-width: 761px) {
  .dock { overflow: hidden; }
  .dock a, body.game .dock .guide__toggle { flex: 0 1 auto; min-width: 0; }
  .dock a span, body.game .dock .guide__toggle span { max-width: 100%; white-space: nowrap; }
}
@media (max-width: 900px) and (min-width: 761px) {
  .dock { gap: 6px; padding-inline: 10px; }
  .dock a, body.game .dock .guide__toggle { letter-spacing: 0; }
  .dock a img { width: 40px; height: 40px; }
  body.game .dock .guide__toggle img { width: 38px; height: 38px; }
}

/* H2. A menu over the lobby: the right-hand column steps out while the profile menu or the drawer is open, so no clipped
   words of the cards behind show beside it ("Ori", "Uni"), and the page dims a little so the menu reads as on top. */
body.game.has-pmenu .hud__right, body.game.has-drawer .hud__right { opacity: 0; visibility: hidden; transition: opacity 120ms, visibility 0s 120ms; }
.pmenu { background: #061027; box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.9), 0 0 0 100vmax rgba(6, 16, 39, 0.38); }
.pmenu__who--plain { grid-template-columns: minmax(0, 1fr); }
.pmenu a.pmenu__cta { margin: 2px 0 6px; justify-content: center; text-align: center; font-weight: 800; color: #fff; background: linear-gradient(180deg, var(--hu-blue-400), var(--hu-blue-600)); box-shadow: var(--hu-glow), inset 0 1px 0 rgba(255, 255, 255, 0.3); }
.pmenu a.pmenu__cta:hover, .pmenu a.pmenu__cta:focus-visible { background: linear-gradient(180deg, #5cb6ff, var(--hu-blue-400)); }

/* H11. Visitor chrome (main.js paintTier). A preview visitor sees a neutral avatar and one "Unlock the course" chip; the
   member counters and member-only doors (points, streak, Messages, Friends) are not theirs yet. */
.top__visitor { display: none; }
.chip--unlock { font-weight: 800; font-size: 0.8rem; letter-spacing: 0.04em; white-space: nowrap; background: linear-gradient(180deg, var(--hu-blue-400), var(--hu-blue-600)); border-color: rgba(190, 225, 255, 0.6); box-shadow: var(--hu-glow), inset 0 1px 0 rgba(255, 255, 255, 0.3); }
.chip--unlock:hover { border-color: #fff; color: #fff; text-decoration: none; }
.chip--unlock[hidden] { display: none; }
body.is-preview .top__right .chip--credits, body.is-preview .top__right .streak,
body.is-preview .top__right a[href="#/messages"], body.is-preview .top__right a[href="#/friends"] { display: none !important; }
body.is-preview #top-face { display: none; }
body.is-preview .top__visitor { display: block; color: rgba(234, 245, 255, 0.9); }
body.is-preview .chip--profile { width: 44px; justify-content: center; padding: 6px; }

/* M24. The tabs hold still from route to route: the streak chip keeps one width whether it says "start a streak" or
   "12 day streak", so the centred tab pill no longer shifts ~11px. */
.top__right .streak { min-width: 12rem; justify-content: center; box-sizing: border-box; }   /* fits "start a streak" and a 3-digit "day streak" */

/* L15. The four sound bars are the "on" signal; with sound off they are not drawn (four grey ticks read as a loader). */
.sound:not(.is-on) i { display: none; }

/* H10. Large screens. From 1920px the whole shell grows with the window (root type, bars, dock, rails, panels) so a
   1440p monitor shows the same composition as a laptop, not a miniature of it. Below 1920px nothing changes. */
@media (min-width: 1920px) {
  /* 16px at 1920, 20px at 2560. lib/prefs.js writes the member's text size inline on <html> (100 / 112.5 / 125%), so the
     step is applied per choice and keeps it: a member who asked for larger text still gets larger text. */
  html { --hu-root: clamp(16px, 0.625vw + 4px, 22px); font-size: var(--hu-root); }
  html[style*="font-size: 100%"] { font-size: var(--hu-root) !important; }
  html[style*="font-size: 112.5%"] { font-size: calc(1.125 * var(--hu-root)) !important; }
  html[style*="font-size: 125%"] { font-size: calc(1.25 * var(--hu-root)) !important; }
  body.game { --top-h: clamp(64px, 3.3vw, 88px); --dock-h: clamp(118px, 6.15vw, 160px); }
  .top { padding-inline: 1.4rem; gap: 1rem; }
  .top__crest { width: 3.25rem; height: 3.25rem; }
  .chip { min-height: 2.75rem; padding: 0.4rem 0.75rem; border-radius: 0.75rem; }
  .chip--icon, .chip--profile { width: 2.75rem; }
  .chip--icon img, .chip--credits img { width: 1.75rem; height: 1.75rem; }
  .chip--profile img { width: 2.25rem; height: 2.25rem; }
  .top__right { gap: 0.5rem; }
  .dock { gap: 0.65rem; padding-inline: 1.4rem; }
  .dock a, body.game .dock .guide__toggle { width: 7.75rem; border-radius: 1rem; }
  .dock a img { width: 3.75rem; height: 3.75rem; }
  body.game .dock .guide__toggle img { width: 3.25rem; height: 3.25rem; }
  .hud__left { left: 1.4rem; width: clamp(320px, 20vw, 520px); gap: 0.9rem; }
  .hud__right { right: 1.4rem; width: clamp(260px, 16vw, 420px); gap: 0.9rem; }
  body.game.is-panel .stage__view { padding: 0.6rem 1.4rem 1.5rem; }
  body.game.is-panel .stage__view > .panel { max-width: 74rem; }
  body.game .side { right: 1.4rem; width: min(22.5rem, 90vw); }
  .pmenu { right: 1.4rem; width: 16.25rem; }
  body.game .guide { right: 1.4rem; width: min(26rem, calc(100vw - 32px)); height: min(37.5rem, calc(100vh - var(--top-h) - var(--dock-h) - 24px)); }
}

/* L5. The palette's keyboard hint is for keyboards: on touch screens it is not drawn. */
@media (hover: none) { .palette__foot { display: none; } }
