/* PHREAKNYST — phosphor-on-black, built for a hotel lobby at 2am
   and a phone with 40% battery. */

:root {
  --bg: #050706;
  --bg-2: #0a0e0c;
  --panel: #0d1311;
  --edge: #1d2a25;
  --ink: #7fe0b0;
  --ink-dim: #4e8f74;
  --text: #d6e6df;
  --muted: #7d918a;
  --warn: #f0b429;
  --bad: #f2685c;
  --good: #6ee7a8;
  --act1: #4ade80;
  --act2: #38bdf8;
  --act3: #fbbf24;
  --act4: #f87171;
  --topbar-h: 53px;
  --tap: 44px;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.55;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

body::after {
  /* CRT scanlines. Cheap, and it sells the whole thing. */
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(255,255,255,0.017) 0 1px, transparent 1px 3px);
  z-index: 9000;
}

a { color: var(--ink); }
button { font: inherit; }

#app { min-height: 100%; display: flex; flex-direction: column; }
#app:has(> .scene-wrap) { height: 100dvh; min-height: 0; }

/* ------------------------------------------------------------ gate screen */

.gate {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px 16px;
}
.gate-inner { width: min(560px, 100%); }
.gate h1 {
  font-size: clamp(28px, 8vw, 46px);
  letter-spacing: 0.16em;
  margin: 0 0 2px;
  color: var(--ink);
  text-shadow: 0 0 24px rgba(127,224,176,0.28);
}
.gate .sub { color: var(--muted); letter-spacing: 0.22em; font-size: 12px; margin-bottom: 26px; }
.gate .lede { color: var(--muted); margin: 0 0 22px; font-size: 14px; }
.gate .lede p { margin: 0 0 8px; }

.tabs { display: flex; gap: 0; margin-bottom: 18px; border-bottom: 1px solid var(--edge); }
.tabs button {
  flex: 1; background: none; border: 0; color: var(--muted);
  padding: 10px 6px; cursor: pointer; letter-spacing: 0.1em; font-size: 12px;
  border-bottom: 2px solid transparent;
}
.tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--ink); }

label { display: block; font-size: 11px; letter-spacing: 0.14em; color: var(--muted); margin: 14px 0 5px; }

input[type="text"], input[type="password"], textarea, select {
  width: 100%; padding: 11px 12px;
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--edge); border-radius: 3px;
  font-family: var(--mono);
  /* 16px is not a style choice: iOS Safari zooms the whole page when you focus
     a control smaller than this, and the player has to pinch back every time
     they answer a puzzle. */
  font-size: 16px;
  outline: none;
  min-height: var(--tap);
}
input:focus, textarea:focus { border-color: var(--ink-dim); box-shadow: 0 0 0 1px rgba(127,224,176,0.16); }
input[inputmode="numeric"] { letter-spacing: 0.4em; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 18px; background: var(--ink); color: #04140d;
  border: 0; border-radius: 3px; cursor: pointer;
  font-weight: 700; letter-spacing: 0.08em; font-size: 13px;
}
.btn:disabled { opacity: 0.45; cursor: default; }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--ink-dim); font-weight: 400; }
.btn.wide { width: 100%; margin-top: 20px; }
.btn.small { padding: 6px 11px; font-size: 12px; }

.err { color: var(--bad); font-size: 13px; margin-top: 12px; min-height: 19px; }
.ok { color: var(--good); }

/* ------------------------------------------------------------------- chrome */

.topbar {
  flex: none;
  position: sticky; top: 0; z-index: 60; min-height: 53px;
  display: flex; align-items: center; gap: 12px;
  padding: 8px 12px;
  background: rgba(5,7,6,0.94);
  border-bottom: 1px solid var(--edge);
  backdrop-filter: blur(6px);
}
.brand { color: var(--ink); letter-spacing: 0.16em; font-size: 12px; white-space: nowrap; }
.brand b { font-weight: 700; }
.spacer { flex: 1; }
.stat { font-size: 12px; color: var(--muted); white-space: nowrap; }
.stat b { color: var(--text); }
.iconbtn {
  background: none; border: 1px solid var(--edge); color: var(--muted);
  min-width: 36px; height: 34px; border-radius: 3px; cursor: pointer;
  font-size: 16px; line-height: 1; flex: 0 0 auto;
}
.iconbtn.on, .iconbtn:hover { color: var(--ink); border-color: var(--ink-dim); }
/* The walk-through is loud on purpose: every gate in the game is open while it
   is lit, and that must never be mistaken for having actually solved anything. */
.iconbtn.skeleton { color: var(--warn); border-color: var(--warn); background: rgba(240,180,41,.14); }
.iconbtn .dot {
  position: absolute; width: 7px; height: 7px; border-radius: 50%;
  background: var(--warn); transform: translate(11px, -14px);
}

/* --------------------------------------------------------------- the scene */

.scene-wrap { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.scene-main { display: flex; flex: 1; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
.scene-viewport, .inspection-viewport { flex: 1; min-height: 0; container-type: size; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.scene {
  position: relative;
  aspect-ratio: 3 / 2;
  /* Keep the full wall and its percent-based targets together at every size. */
  width: min(100cqw, 150cqh);
  min-width: 0;
  flex: none;
  margin-inline: auto;
  background: #000;
  overflow: hidden; user-select: none;
  touch-action: manipulation;   /* kill the 300ms double-tap-zoom delay */
}
.scene img { width: 100%; height: 100%; object-fit: cover; display: block; }
.scene-art-frame { position: absolute; box-sizing: border-box; pointer-events: none; background: #151310; border: clamp(2px, .5cqw, 8px) ridge #594432; box-shadow: 2px 4px 5px #0007; }
.scene-art-frame img { object-fit: cover; }
.scene-art-frame[data-frame^="triangle-"] img, .scene-art-frame[data-frame^="bitwize-"] img { object-fit: contain; }
.scene-art-frame[data-frame^="bitwize-"], .scene-art-frame[data-frame^="triangle-"] { border: 0; outline: clamp(2px, .5cqw, 8px) ridge #594432; }
.scene-art-frame[data-frame="not-spock-8"] img { object-position: center top; }
.inspection-photo.framed-art { box-sizing: border-box; object-fit: contain; border: clamp(4px, 1cqw, 14px) ridge #594432; background: #151310; }

.view-label, .inspection-title { position: absolute; z-index: 4; top: 10px; margin: 0; padding: 6px 9px; max-width: 46%; background: #080d0bc9; color: var(--ink); font: 11px/1.4 var(--mono, monospace); letter-spacing: .08em; pointer-events: none; }
.view-label { right: 10px; text-align: right; }
.scene > .arttag, .inspection-frame > .arttag { top: 48px; right: 10px; }
.inspection-title { left: 10px; }
.inspection { width: 100%; min-width: 0; min-height: 0; flex: 1; display: flex; flex-direction: column; }
.inspection-viewport { cursor: zoom-out; }
.inspection-frame { position: relative; width: min(100cqw, calc(100cqh * var(--image-ratio, 1.5))); max-height: 100%; margin-inline: auto; background: #000; cursor: auto; }
.inspection-photo { display: block; width: 100%; height: auto; }
.inspection-transcript { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: pre-wrap; border: 0; }
.inspection-image-tools { display: flex; justify-content: center; gap: 8px; padding: 6px; flex: none; }
.image-only-inspection.magnified .inspection-viewport { display: block; overflow: auto; cursor: default; }
.image-only-inspection.magnified .inspection-frame { width: max(100%, 1536px); max-width: none; height: auto; max-height: none; }
.image-only-inspection.magnified .inspection-exit { display: none; }
.inspection-frame > :not(.inspection-exit):not(.inspection-title):not(.view-label):not(.arttag):not(.inspection-body):not(.info-box-outline):not(.personal-info-outline) { position: relative; z-index: 1; }
.inspection-exit { position: absolute; z-index: 0; border: 0; padding: 0; background: transparent; cursor: zoom-out; }
.inspection-frame.return-hover { cursor: zoom-out; }
.inspection-exit-left, .inspection-exit-right { top: 0; bottom: 0; width: clamp(44px, 10%, 120px); }
.inspection-exit-left { left: 0; }
.inspection-exit-right { right: 0; }
.inspection-exit-top, .inspection-exit-bottom { left: 0; right: 0; height: clamp(44px, 10%, 120px); }
.inspection-exit-top { top: 0; }
.inspection-exit-bottom { bottom: 0; }
.inspection-exit:focus-visible { z-index: 3; pointer-events: none; background: #7fe0b016; outline: 1px solid var(--ink-dim); outline-offset: -1px; }
.inspection-image-stage { overflow: auto; }
.inspection-image { position: relative; }
.inspection-frame:has(.is-expanded) { width: 100%; height: 100%; }
.inspection-frame .patch-stage.is-expanded { height: 100%; max-height: 100%; }
.inspection-image-link { position: absolute; display: block; cursor: pointer; border-radius: 2px; }
.inspection-image-link:hover, .inspection-image-link:focus-visible { outline: 2px solid #63bcec; outline-offset: -2px; background: #63bcec0a; }
.inspection-body:empty { display: none; }
.inspection-body { overflow-wrap: anywhere; }
.side.inspection-details { padding: 0; }
.inspection-details .answer-row, .inspection-details .artifact { flex-wrap: wrap; }
.inspection-details .answer-row input { min-width: 0; flex-basis: 180px; }
.inspection-details .as-id { flex-basis: 100%; }
.scene-main > .zonepanel { flex: 0 1 auto; max-height: 40%; overflow: auto; }
.inspection-body .prose { max-width: 100%; }
.inspection-frame.has-phone { width: auto; height: 100%; max-width: 100%; }
.inspection-frame .phone-face { height: 100%; max-width: 100%; }
.inspection-frame .patch-stage { border: 0; }
.inspection-frame:has(.terminal-stage.is-expanded) { padding-top: 44px; }
.inspection-frame .terminal-stage.is-expanded { height: 100%; min-height: 0; }

.hotspot {
  position: absolute; border: 0; border-radius: 2px;
  cursor: pointer; background: transparent; padding: 0;
  -webkit-tap-highlight-color: transparent;
  transition: background 120ms;
}
/* Deliberately invisible: the room is searched, not read. The only feedback is
   a brief flash on press so a tap feels like it landed. */
.hotspot:active { background: rgba(127,224,176,0.16); }
/* Doors win over floor zones. Distant doors keep their photographed bounds
   instead of mobile minimums expanding across neighboring doors. */
.hotspot[data-id^="approach-room-"] { z-index: 1; min-width: 0; min-height: 0; }
/* These adjacent objects need separate targets even when mobile minimums would merge them. */
.scene[data-node="lobby"] .hotspot:is([data-id="ledger"], [data-id="guest-services"], [data-id="lobby-directory"], [data-id="reception-notice"], [data-id="attendee-sign"], [data-id="business-info"], [data-id="business-access"]) { min-width: 0; min-height: 0; }
.hotspot:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.hotspot.locked { cursor: not-allowed; }
/* Floor-plan zoom bar. The Level 1 sheet is twice as wide as it is tall, so a
   phone needs to magnify it rather than squint at a fitted strip.

   This block used to be glued to an orphaned `.hotspot.tag-right` selector left
   over from the first commit. Comments are stripped before parsing, so the two
   became `.hotspot.tag-right .plan-zoom` — a descendant selector that matches
   nothing, and the zoom buttons have been unstyled ever since. */
.plan-zoom { display: flex; gap: 6px; margin-bottom: 8px; }
.plan-zoom button { flex: 0 0 auto; padding: 5px 12px; font-size: 12px; letter-spacing: 1px; }
.plan-zoom button.on { border-color: var(--ink); color: var(--ink); }

.caption {
  padding: 10px 14px; border-bottom: 1px solid var(--edge);
  background: var(--bg-2); color: var(--muted); font-size: 13px;
}
.caption .where { color: var(--ink); letter-spacing: 0.14em; font-size: 11px; display: block; margin-bottom: 3px; }

.exits { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 14px 14px; }
.exit {
  background: var(--panel); border: 1px solid var(--edge); color: var(--text);
  padding: 7px 12px; border-radius: 3px; cursor: pointer; font-size: 12px;
}
.exit:hover { border-color: var(--ink-dim); color: var(--ink); }
.exit::before { content: "→ "; color: var(--ink-dim); }

/* ---------------------------------------------------------------- terminal */

.terminal { margin-top: 16px; padding: 12px; background: #050a07; border: 1px solid var(--edge); }
.terminal-output { max-height: 45vh; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; color: var(--ink); }
.terminal-entry { display: flex; align-items: center; gap: 8px; }
.terminal-entry input { flex: 1; min-width: 0; width: 0; font: inherit; }
.terminal-prompt { white-space: pre-wrap; overflow-wrap: anywhere; max-width: 35%; }
.terminal-device { margin-top: 16px; }
.terminal-stage { position: relative; aspect-ratio: 3 / 2; container-type: inline-size; }
.terminal-photo { display: block; width: 100%; height: 100%; object-fit: contain; }
.terminal-on-screen { position: absolute; box-sizing: border-box; display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 10px; border: 0; background: #020302; color: #ffcd69; font: 13px/1.35 var(--mono, monospace); font-size: clamp(12px, 1.7cqw, 16px); overflow: hidden; }
.terminal-on-screen .terminal-output { flex: 1; min-height: 0; max-height: none; margin: 0; color: inherit; scrollbar-width: thin; }
.terminal-on-screen .terminal-entry { flex: none; gap: 4px; }
.terminal-on-screen input { background: #050805; color: inherit; border: 1px solid #5e552e; padding: 6px; }
.terminal-on-screen button { color: inherit; background: #13170f; border-color: #5e552e; padding: 6px; }
.terminal-on-screen .solved-banner, .terminal-on-screen .err { margin: 0; padding: 4px; font-size: 12px; }
.terminal-on-screen :focus-visible { outline: 2px solid #ffcd69; outline-offset: 1px; }
.terminal-stage.is-expanded { height: min(65dvh, 540px); min-height: 280px; aspect-ratio: auto; }
.terminal-stage.is-expanded .terminal-photo { display: none; }
.terminal-stage.is-expanded .terminal-on-screen { inset: 0 !important; width: 100% !important; height: 100% !important; font-size: 16px; }
.terminal-toolbar { display: flex; justify-content: flex-end; flex: none; }
.terminal-toolbar .terminal-expand-toggle { min-height: 32px; margin: 0; font-size: 11px; }

.patch-stage { overflow: auto; max-width: 100%; border: 1px solid var(--edge); }
.patch-surface { position: relative; width: 100%; aspect-ratio: 3 / 2; }
.patch-stage.is-expanded .patch-surface { min-width: 760px; }
.patch-photo { display: block; width: 100%; height: 100%; }
.patch-button { position: absolute; margin: 0; padding: 0; background: transparent; border: 1px solid transparent; border-radius: 6px; cursor: pointer; color: #f7f1db; }
.patch-button:hover { background: #ffffff0a; border-color: #e5dba877; }
.patch-button:focus-visible { outline: 3px solid var(--warn); outline-offset: 3px; }
.patch-button:disabled { cursor: wait; }
.patch-led { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 44%; aspect-ratio: 1; border-radius: 50%; background: radial-gradient(circle at 40% 35%, #fff9, var(--led-color) 45%, #0007); box-shadow: 0 0 8px 2px var(--led-color), inset 0 0 4px #fff8; pointer-events: none; }
.patch-button[data-off="true"] .patch-led { opacity: 0; }
.patch-port-name { display: none; }
.patch-device > button { margin-top: 8px; }
.patch-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 12px; font-size: 11px; }
.patch-legend span { display: inline-flex; gap: 6px; align-items: center; }
.patch-legend i { width: 10px; height: 10px; border: 1px solid #ffffff66; border-radius: 50%; }
.patch-status { min-height: 1.5em; color: var(--muted); font-size: 12px; }
.patch-stage.image-unavailable .patch-surface { min-width: 0; aspect-ratio: auto; display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; padding: 12px; }
.patch-stage.image-unavailable .patch-photo { display: none; }
.patch-stage.image-unavailable .patch-button { position: relative; inset: auto !important; width: 100% !important; height: 90px !important; background: #151a19; border-color: var(--edge); }
.patch-stage.image-unavailable .patch-port-name { display: block; position: absolute; top: 4px; width: 100%; }
.patch-stage.image-unavailable .patch-led { width: 25px; }
.patch-stage.image-unavailable .patch-button[data-off="true"] .patch-led { opacity: 1; box-shadow: none; background: #242728; }

/* Claiming a real-world code lives in the REAL WORLD tab, not in a bar pinned
   to every screen. Six of the eleven stations are typed in; the rest arrive by
   scan. That is not enough traffic to justify permanent furniture under the
   picture, which is the one thing the game is actually made of. */
.claimbox { margin-bottom: 16px; display: grid; gap: 5px; }
.claimbox label { font-size: 10px; letter-spacing: 0.14em; color: var(--muted); }
.claimbox input { flex: 1; }

/* ------------------------------------------------------------------ modals */

.modal-bg {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0,0,0,0.82);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 4vh 12px; overflow-y: auto;
}
.modal {
  width: min(760px, 100%); background: var(--panel);
  border: 1px solid var(--edge); border-radius: 4px;
  box-shadow: 0 30px 90px rgba(0,0,0,0.7);
}
.modal-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--edge);
}
.modal-head h2 { margin: 0; font-size: 15px; letter-spacing: 0.1em; color: var(--ink); flex: 1; }
.modal-head .pts { font-size: 12px; color: var(--warn); }
.modal-body { padding: 16px; }
.modal-body pre, .prose {
  white-space: pre-wrap; word-break: break-word;
  font-family: var(--mono); font-size: 13.5px; line-height: 1.6; margin: 0;
}

/* Aligned blocks: column position carries meaning, so never wrap them.
   fitArt() shrinks each one to fit; below its floor this scrolls instead. */
pre.art {
  white-space: pre;
  word-break: normal;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  max-width: 100%;
  padding-bottom: 2px;
}
pre.art::-webkit-scrollbar { height: 5px; }
pre.art::-webkit-scrollbar-thumb { background: var(--edge); border-radius: 3px; }
/* Only the ones too wide even at the minimum size advertise that they scroll. */
pre.art.scrolls {
  border-right: 1px solid var(--edge);
  background: linear-gradient(to left, rgba(127,224,176,0.07), transparent 24px);
}
.flavor { color: var(--muted); font-style: italic; margin-bottom: 14px; font-size: 13px; }
.prompt-box {
  background: #06090800; border-left: 2px solid var(--edge);
  padding: 2px 0 2px 14px; margin-bottom: 18px; color: var(--text);
}
.close { background: none; border: 0; color: var(--muted); font-size: 22px; cursor: pointer; line-height: 1; padding: 0 4px; }
.close:hover { color: var(--bad); }

.solved-banner {
  border: 1px solid rgba(110,231,168,0.4); background: rgba(110,231,168,0.06);
  color: var(--good); padding: 10px 12px; border-radius: 3px; margin-bottom: 16px; font-size: 13px;
}
.gate-banner {
  border: 1px solid rgba(240,180,41,0.4); background: rgba(240,180,41,0.06);
  color: var(--warn); padding: 10px 12px; border-radius: 3px; margin-bottom: 16px; font-size: 13px;
}

/* -------------------------------------------------------- puzzle controls */

.answer-row { display: flex; gap: 8px; margin-top: 6px; }
.answer-row input { flex: 1; }
.mission-sign { color: var(--ink); font-weight: 700; }
.mission-camera-open { min-height: 48px; width: 100%; }
.mission-camera-options { display: flex; flex-direction: column; gap: 8px; }
.mission-camera-options .btn { min-height: 48px; width: 100%; }
@media (hover: hover) and (pointer: fine) {
  .mission-camera-options .phone-camera-open { order: -1; color: #04140d; background: var(--ink); font-weight: 700; border: 1px solid var(--ink); }
  .mission-camera-options .mission-camera-open { color: var(--ink); background: transparent; border: 1px solid var(--ink-dim); }
}
.camera-handoff-dialog { width: min(480px, calc(100% - 24px)); max-height: calc(100dvh - 32px); margin: auto; overflow-y: auto; padding: 24px; color: var(--text); background: var(--panel); border: 1px solid var(--ink-dim); border-radius: 10px; }
.camera-handoff-dialog::backdrop { background: #000b; }
.camera-handoff-dialog h2 { margin: 0 0 12px; color: var(--ink); font-size: 21px; }
.camera-handoff-dialog p { overflow-wrap: anywhere; }
.camera-handoff-qr { display: block; width: 288px; max-width: 100%; height: auto; margin: 16px auto; background: white; }
.camera-handoff-qr[hidden], .camera-handoff-actions [hidden] { display: none; }
.camera-handoff-countdown { color: var(--muted); font-size: 13px; }
.camera-handoff-status { min-height: 24px; }
.camera-handoff-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.camera-handoff-actions .btn { min-height: 48px; flex: 1 1 auto; }

.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; max-width: 260px; margin: 14px 0; }
.keypad button {
  padding: 15px 0; background: var(--bg-2); border: 1px solid var(--edge);
  color: var(--text); border-radius: 3px; cursor: pointer; font-size: 19px;
}
.keypad button:active { background: var(--ink); color: #04140d; }
.keydisp {
  font-size: 30px; letter-spacing: 0.42em; color: var(--ink);
  min-height: 42px; padding: 4px 0 0 6px; border-bottom: 1px solid var(--edge); max-width: 260px;
}

.seq-options { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.seq-options button {
  background: var(--bg-2); border: 1px solid var(--edge); color: var(--text);
  padding: 9px 13px; border-radius: 3px; cursor: pointer; font-size: 13px; text-align: left;
}
.seq-options button:hover { border-color: var(--ink-dim); }
.seq-options button:disabled { opacity: 0.3; cursor: default; }
.seq-picked {
  min-height: 44px; border: 1px dashed var(--edge); border-radius: 3px;
  padding: 8px 10px; margin: 10px 0; color: var(--ink); font-size: 13px;
}
.seq-picked span { display: inline-block; margin-right: 10px; }
.seq-picked .n { color: var(--muted); }

.wires { display: grid; gap: 10px; margin: 14px 0; }
.wire-row {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px; align-items: center;
  border: 1px solid var(--edge); border-radius: 3px; padding: 9px 11px; background: var(--bg-2);
}
@media (max-width: 560px) {
  .wire-row { grid-template-columns: 1fr; gap: 6px; }
  .wire-row .arrow { display: none; }
  .wire-row .det { margin-bottom: 4px; }
}
.wire-row .lbl { font-size: 13px; color: var(--ink); }
.wire-row .det { font-size: 11.5px; color: var(--muted); }
.wire-row select {
  background: var(--bg); color: var(--text); border: 1px solid var(--edge);
  border-radius: 3px; padding: 10px; font-family: var(--mono); font-size: 16px; width: 100%;
}
.wire-row .arrow { color: var(--ink-dim); }

.fields { display: grid; gap: 12px; margin: 14px 0; }

.term {
  background: #04070500; border: 1px solid var(--edge); border-radius: 3px;
  height: min(46vh, 380px); overflow: auto; padding: 12px;
  font-size: 13px; white-space: pre; word-break: normal;
  -webkit-overflow-scrolling: touch;
  background-color: #030605;
}
.term > div { min-width: max-content; }
@media (max-width: 560px) { .term { font-size: 11.5px; } }
.term .cmd { color: var(--ink); }
.term .out { color: var(--text); opacity: 0.92; }
.term-input { display: flex; gap: 8px; margin-top: 8px; align-items: center; }
.term-input .ps { color: var(--ink); font-size: 13px; }
.term-input input { flex: 1; }

/* --------------------------------------------------------------- payphone */

.phone { display: grid; gap: 14px; margin-top: 14px; }

/* The phone is the picture. Keys are percentage rects over a close-up of the
   real plate, exactly like a room hotspot, so they stay on their buttons at
   any rendered size. */
.phone-face {
  position: relative; margin: 0 auto;
  /* Sized by HEIGHT, not width. The plate is twice as tall as it is wide, so
     filling the width of a phone would run it off the bottom of the screen;
     filling the height instead gets the keys as big as they can be and still
     be seen all at once. Keys land at ~70px, well over the 44px tap floor. */
  height: min(68dvh, 660px);
  width: auto; max-width: 100%;
  background-repeat: no-repeat; border-radius: 3px;
  box-shadow: 0 0 0 1px var(--edge), 0 10px 34px #000a;
}
@supports not (height: 1dvh) { .phone-face { height: min(68vh, 660px); } }
.phone-key {
  position: absolute; appearance: none; padding: 0; cursor: pointer;
  background: transparent; border: 1px solid transparent; border-radius: 3px;
  transition: background 90ms, box-shadow 90ms;
}
/* Unlit until you go looking, so the plate reads as a photograph first. */
.phone-face:hover .phone-key, .phone-face:focus-within .phone-key { border-color: #7fe0b026; }
/* Touch has no hover to go looking with, and a photograph of a keypad gives a
   thumb nothing to aim at. On a phone the keys are always faintly outlined. */
@media (hover: none) {
  .phone-key { border-color: #7fe0b038; }
}
.phone-key:hover { background: #7fe0b01f; border-color: var(--ink-dim); }
.phone-key:active, .phone-key.lit {
  background: #7fe0b059; border-color: var(--ink);
  box-shadow: 0 0 12px #7fe0b073, inset 0 0 8px #7fe0b04d;
}
.phone-key:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.phone-answer {
  position: absolute; z-index: 4; left: 10.7%; top: 5.6%; width: 69.6%; height: 14.6%;
  background: #071e15; color: #a8ffd5; border: 2px solid #81e8b5;
  font: bold clamp(12px, 4cqw, 22px) monospace; cursor: pointer;
}
.phone-answer[hidden] { display: none; }
.phone-answer.handset-answer { background: #75e9b31a; border-color: #a8ffd566; color: transparent; }
.phone-answer.handset-answer:hover, .phone-answer.handset-answer:focus-visible { color: white; background: #061c12b8; }
.image-device-stage, .lighting-stage { width: 100%; height: 100%; overflow: auto; }
.image-device-surface, .lighting-surface { position: relative; width: 100%; container-type: inline-size; }
.image-device-photo, .lighting-photo { display: block; width: 100%; height: auto; }
.lighting-display { position: absolute; display: flex; flex-direction: column; gap: .5cqw; padding: .7cqw; background: #091e19; color: #a5efc0; font: 1.15cqw var(--mono); overflow: auto; }
.lighting-display textarea { min-height: 2.2em; flex: 1; resize: none; font: inherit; }
.lighting-display input, .lighting-display button { font: inherit; }
.lighting-fader { position: absolute; writing-mode: vertical-lr; direction: rtl; appearance: auto; padding: 0; margin: 0; accent-color: #a9deb5; cursor: ns-resize; box-shadow: 0 0 calc(var(--level) * 16px) #b9ff86; }
.lighting-control { position: absolute; font: bold .65cqw var(--mono); border-radius: 45%; padding: 0; background: #14170ddd; border: 1px solid #c9ba74; color: #f1e8bb; cursor: pointer; }
.lighting-flash { background: transparent; }
.lighting-control:active { background: #d3d68c; color: black; }
.lighting-control:focus-visible, .lighting-fader:focus-visible { outline: 3px solid white; }
.lighting-download { position: absolute; display: flex; align-items: center; justify-content: center; background: #e4c79f; color: #17221b; font: bold 1.2cqw var(--mono); text-decoration: underline; border: 1px solid #786345; border-radius: 3px; }
.lighting-download:focus-visible { outline: 3px solid white; outline-offset: 2px; }
.receiver-stage { width: 100%; overflow: hidden; }
.receiver-surface { position: relative; width: 100%; container-type: inline-size; }
.receiver-photo { display: block; width: 100%; }
.receiver-dial { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.receiver-knob { position: absolute; left: 70.6%; top: 50.5%; width: 13.1%; height: 20%; border-radius: 50%; background: transparent; border: 0; touch-action: none; cursor: grab; }
.receiver-knob:active { cursor: grabbing; }
.receiver-position { position: absolute; background: transparent; border: 0; border-radius: 50%; cursor: pointer; }
.receiver-position:hover { background: #c6e2a342; }
.receiver-position:focus-visible, .receiver-knob:focus-visible { outline: 3px solid white; }
.receiver-controls { display: grid; gap: 12px; font: 13px var(--mono); }
.receiver-controls output { color: var(--muted); }
.receiver-controls pre { white-space: pre-wrap; font: inherit; }
.image-device-screen { position: absolute; box-sizing: border-box; display: flex; flex-direction: column; gap: .5cqw; padding: 1cqw; background: #061719; color: #a6f5e4; border: 1px solid #487578; font: 1.35cqw var(--mono); overflow: auto; }
.image-device-screen button { font: inherit; color: inherit; background: #123436; border: 1px solid #458781; padding: .6cqw; cursor: pointer; min-height: 30px; }
.image-device-screen button:focus-visible, .device-photo-key:focus-visible { outline: 3px solid white; }
.device-title { text-transform: uppercase; font-weight: bold; }
.device-readout { white-space: normal; overflow-wrap: anywhere; min-height: 1em; }
.device-photo-key { position: absolute; border: 1px solid #a1ffd855; background: transparent; border-radius: 30%; cursor: pointer; }
.device-photo-key:hover, .device-photo-key:active { background: #a1ffd84a; }
.image-device-stage.image-unavailable .image-device-surface { min-height: 600px; background: #101c20; }
.image-device-stage.image-unavailable .device-photo-key::after { content: attr(aria-label); color: white; }
@media (max-width: 700px) {
  .image-device-surface, .lighting-surface { width: 850px; }
}
.phone-answer:focus-visible { outline: 3px solid white; outline-offset: 2px; }
.incoming-call-notice { margin: 10px 0; }

.phone-glass {
  position: absolute; display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-weight: 600;
  font-size: clamp(9px, 7.5cqw, 17px);
  letter-spacing: 0.08em; white-space: nowrap; overflow: hidden;
  color: #ffb545; text-shadow: 0 0 6px #ffb54599, 0 0 14px #ff8a0059;
  background: #140b02cc;
}
.phone-face { container-type: inline-size; }
.phone-glass.bare {
  position: static; height: 40px; margin-bottom: 12px; font-size: 15px;
  border: 1px solid var(--edge); border-radius: 3px;
}

.phone-line {
  border: 1px solid var(--edge); border-radius: 3px; background-color: #030605;
  max-height: min(42vh, 340px); overflow: auto; padding: 12px; font-size: 13px;
  -webkit-overflow-scrolling: touch;
}
.phone-line:empty { display: none; }
.phone-line .said { margin-bottom: 12px; }
.phone-line .said:last-child { margin-bottom: 0; }
.phone-line .dialled {
  color: var(--ink); letter-spacing: 0.2em; border-bottom: 1px solid var(--edge);
  padding-bottom: 7px; margin-bottom: 10px;
}
.phone-line .dialtone { color: var(--muted); }
.phone-line .got { color: var(--good); }
.phone-line .note { color: var(--warn); }
.phone-line .err { color: var(--bad); }
.phone-line .solved {
  color: #04140d; background: var(--good); font-weight: 600;
  letter-spacing: 0.1em; padding: 6px 10px; border-radius: 3px; margin: 4px 0 12px;
}
@media (max-width: 560px) { .phone-line { font-size: 12px; } }

/* The grid fallback, for a phone with no close-up art of its own. */
.dialpad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; max-width: 280px; margin: 0 auto; }
.dialpad.dtmf { grid-template-columns: repeat(4, 1fr); max-width: 340px; }
.dialpad .dkey {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: var(--tap); padding: 8px 0 6px;
  background: var(--bg-2); border: 1px solid var(--edge); color: var(--text);
  border-radius: 3px; cursor: pointer; font-family: var(--mono); line-height: 1.1;
}
.dialpad .dkey .d { font-size: 19px; }
.dialpad .dkey .l { font-size: 8.5px; letter-spacing: 0.1em; color: var(--muted); min-height: 11px; }
.dialpad .dkey:active { background: var(--ink); color: #04140d; }
.dialpad .dkey:active .l { color: #04140d; }
.dialpad .dkey.col4 { border-color: var(--ink-dim); }
.dialpad .dkey.col4 .d { color: var(--ink-dim); }


/* -------------------------------------------------------------- panels */

.panel-list { display: grid; gap: 10px; }
.card {
  border: 1px solid var(--edge); border-radius: 3px; padding: 11px 13px; background: var(--bg-2);
}
.card h4 { margin: 0 0 4px; font-size: 13px; color: var(--text); }
.card .meta { font-size: 11.5px; color: var(--muted); }
.card.done { border-color: rgba(110,231,168,0.3); }
.card.done h4 { color: var(--good); }
.card.locked { opacity: 0.62; }

.tag {
  display: inline-block; font-size: 10px; letter-spacing: 0.1em;
  padding: 2px 6px; border: 1px solid currentColor; border-radius: 2px; margin-right: 6px;
}
.tag.qr { color: #7dd3fc; } .tag.nfc { color: #c4b5fd; } .tag.code { color: #fcd34d; }
.tag.ssid { color: #6ee7a8; } .tag.rolling { color: #fda4af; } .tag.staff { color: #fdba74; }

.map-grid { display: grid; gap: 8px; }
.map-act h3 {
  font-size: 11px; letter-spacing: 0.18em; color: var(--muted);
  margin: 16px 0 8px; border-bottom: 1px solid var(--edge); padding-bottom: 5px;
}
.map-node {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: var(--bg-2); border: 1px solid var(--edge); border-radius: 3px;
  padding: 9px 11px; cursor: pointer; color: var(--text);
}
.map-node:hover { border-color: var(--ink-dim); }
.map-node:disabled { opacity: 0.4; cursor: not-allowed; }
.map-node .nm { flex: 1; font-size: 13px; }
.map-node .pz { font-size: 11px; color: var(--muted); }
.map-node .bar { width: 42px; height: 4px; background: var(--edge); border-radius: 2px; overflow: hidden; }
.map-node .bar i { display: block; height: 100%; background: var(--good); }
.map-node .caret { color: var(--ink-dim); font-size: 10px; width: 9px; }
.map-node[aria-expanded="true"] .caret { color: var(--ink); }

/* The row opens the room; the arrow on the end still walks there. */
.map-row { display: flex; gap: 6px; align-items: stretch; }
.map-row .map-node { flex: 1; border-radius: 3px 0 0 3px; }
.map-row.open .map-node { border-color: var(--ink-dim); border-bottom-color: transparent; border-radius: 3px 0 0 0; }
.map-go {
  flex: none; width: 34px; background: var(--bg-2); border: 1px solid var(--edge);
  border-left: 0; border-radius: 0 3px 3px 0; color: var(--ink-dim);
  cursor: pointer; font-size: 15px; line-height: 1;
}
.map-go:hover { border-color: var(--ink-dim); color: var(--ink); background: #7fe0b014; }
.map-go:disabled { opacity: 0.4; cursor: not-allowed; }
.map-row.open .map-go { border-color: var(--ink-dim); }

.map-detail {
  border: 1px solid var(--ink-dim); border-top: 0; border-radius: 0 0 3px 3px;
  background: var(--panel); padding: 7px; margin: -1px 0 8px; display: grid; gap: 5px;
}
.md-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: transparent; border: 1px solid transparent; border-radius: 3px;
  padding: 6px 7px; cursor: pointer; color: var(--text); font-size: 12.5px;
}
.md-item:hover { border-color: var(--edge); background: var(--bg-2); }
.md-mark { color: var(--ink-dim); width: 11px; }
.md-item.done .md-mark { color: var(--good); }
.md-item.locked .md-mark { color: var(--warn); }
.md-title { flex: 1; }
.md-item.done .md-title { color: var(--muted); text-decoration: line-through; }
.md-pts { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.md-empty { font-size: 11.5px; color: var(--muted); padding: 4px 7px; line-height: 1.45; }

table.board { width: 100%; border-collapse: collapse; font-size: 13px; }
table.board th, table.board td { padding: 7px 8px; border-bottom: 1px solid var(--edge); text-align: left; }
table.board th { color: var(--muted); font-size: 10.5px; letter-spacing: 0.14em; font-weight: 400; }
table.board td.n { text-align: right; font-variant-numeric: tabular-nums; }
table.board tr.me { background: rgba(127,224,176,0.07); }
table.board tr.me td { color: var(--ink); }

.feed-item { font-size: 12.5px; padding: 6px 0; border-bottom: 1px solid var(--edge); color: var(--muted); }
.feed-item b { color: var(--ink); font-weight: 400; }

.toast-wrap { position: fixed; left: 50%; bottom: 74px; transform: translateX(-50%); z-index: 500; width: min(520px, 92vw); }
.toast {
  background: var(--panel); border: 1px solid var(--ink-dim); border-left-width: 3px;
  border-radius: 3px; padding: 10px 13px; margin-top: 8px; font-size: 13px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.6); animation: rise 180ms ease-out;
}
.toast.bad { border-color: var(--bad); color: var(--bad); }
/* Sensor advice runs to several lines of settings navigation. Without this the
   long ones clipped, which is the same as not showing them. */
.toast { line-height: 1.45; white-space: pre-line; overflow-wrap: anywhere; }
.toast.warn { border-color: var(--warn); color: var(--warn); }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }

.announce {
  border: 1px solid var(--warn); border-left-width: 3px; background: rgba(240,180,41,0.07);
  color: var(--warn); padding: 9px 12px; font-size: 12.5px; margin: 10px 14px 0;
}

.empty { color: var(--muted); font-size: 13px; padding: 20px 0; text-align: center; }

/* ------------------------------------------------------------- responsive */

@media (min-width: 900px) {
  .scene-wrap { flex-direction: row; align-items: flex-start; gap: 0; }
  .scene-main { flex: 1 1 auto; min-width: 0; height: 100%; }
  .side {
    width: 340px; flex: 0 0 340px; border-left: 1px solid var(--edge);
    height: 100%; overflow-y: auto; padding: 14px;
  }
}
/* Very narrow phones (320px, iPhone SE 1st gen): shed the least useful chrome
   rather than letting the topbar push the page sideways. */
@media (max-width: 374px) {
  .topbar { gap: 7px; padding: 8px 8px; }
  .brand { overflow: hidden; text-overflow: ellipsis; max-width: 38vw; }
  .stat.rank { display: none; }
}

@media (orientation: landscape) and (max-height: 560px) and (hover: none) {
  /* The turn buttons keep their edges but shrink out of the way. */
  .turnedge { transform: scale(0.85); }
}

@media (max-width: 560px) {
  .topbar { flex-wrap: wrap; }
  .tag { font-size: 11px; }
  .card .meta, .feed-item { font-size: 12.5px; }
  table.board th { font-size: 11px; }
  .caption { font-size: 13.5px; }
  .stat { font-size: 12.5px; }
  .brand { font-size: 12.5px; }
  .modal-bg { padding: 2vh 6px 12px; }
  .modal-body { padding: 12px 10px; }
  .modal-head { padding: 10px 12px; }
  .exits { padding-bottom: 18px; }
}

@media (max-width: 899px) {
  .side { display: none; }
  .side.inspection-details { display: block; flex: none; max-height: 40%; overflow: auto; border-top: 1px solid var(--edge); }
  .side.open {
    display: block; position: fixed; inset: 49px 0 0 0; z-index: 120;
    background: var(--bg); overflow-y: auto; padding: 14px 14px 90px;
  }
}

.side h3 { font-size: 11px; letter-spacing: 0.18em; color: var(--muted); margin: 0 0 10px; }
.side section { margin-bottom: 26px; }

.sidebar-tabs { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.sidebar-tabs button {
  background: none; border: 1px solid var(--edge); color: var(--muted);
  padding: 5px 9px; border-radius: 3px; font-size: 11px; cursor: pointer; letter-spacing: 0.08em;
}
.sidebar-tabs button[aria-selected="true"] { color: var(--ink); border-color: var(--ink-dim); }

.progress-line { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); margin-bottom: 5px; }
.progress-bar { height: 5px; background: var(--edge); border-radius: 3px; overflow: hidden; margin-bottom: 14px; }
.progress-bar i { display: block; height: 100%; background: var(--ink); }

/* ------------------------------------------------------------ art labels

   Organizer-only badge naming the art file, top-right of every picture. Sits
   above the hotspots so it stays readable, but ignores the mouse so it can
   never eat a click meant for the scene. */

.arttag {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 6;
  pointer-events: none;
  padding: 3px 7px;
  border: 1px solid rgba(127, 224, 176, .38);
  border-radius: 2px;
  background: rgba(7, 11, 10, .74);
  color: #7fe0b0;
  font: 400 11px/1.35 var(--mono, ui-monospace, monospace);
  letter-spacing: .5px;
  white-space: nowrap;
  text-shadow: 0 1px 2px #000;
}

.shotwrap { position: relative; display: block; }
.shotwrap .zoomshot { display: block; }

/* ---------------------------------------------------- clickable regions (H)

   Outlines every hit target on the scene and names it from data-id. Colour
   carries the state, because "this box is in the wrong place" and "this box
   has already been found" are different notes to take:
     green  = not yet found      amber = found      blue = solved
     violet = edge-of-screen turn strip                                    */

.scene.boxes .hotspot {
  border: 1px dashed rgba(127, 224, 176, .85);
  background: rgba(127, 224, 176, .09);
}
.scene.boxes .hotspot.found { border-color: rgba(232, 196, 112, .9); background: rgba(232, 196, 112, .09); }
.scene.boxes .hotspot.solved { border-color: rgba(120, 196, 255, .9); background: rgba(120, 196, 255, .09); }
.scene.boxes .hotspot::after {
  content: attr(data-id);
  position: absolute;
  left: 0;
  top: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 1px 4px;
  background: rgba(7, 11, 10, .82);
  color: #d6f5e6;
  font: 400 10px/1.4 var(--mono, ui-monospace, monospace);
  letter-spacing: .3px;
  pointer-events: none;
}
.scene.boxes .hotspot.found::after { color: #f0dcae; }
.scene.boxes .hotspot.solved::after { color: #c2e2ff; }

/* --------------------------------------------------- floor plan editor */

.planner-body { overflow: hidden; }
.planner-body #app { display: flex; flex-direction: column; height: 100dvh; }

.pl-bar, .pl-status {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px; border-bottom: 1px solid var(--edge); background: var(--panel);
}
.pl-bar .spacer { flex: 1; }
.pl-tabs { display: flex; gap: 6px; }
.pl-status {
  border-bottom: 0; border-top: 1px solid var(--edge);
  font: 400 11px/1.4 var(--mono, ui-monospace, monospace); letter-spacing: .5px; color: var(--dim);
}
.pl-status .warn { color: #f0b429; }
.pl-status .ok { color: var(--accent); }

.pl-main { flex: 1; display: flex; min-height: 0; }
.pl-canvaswrap { flex: 1; min-width: 0; background: #070b0a; position: relative; }
.pl-canvas { width: 100%; height: 100%; display: block; touch-action: none; cursor: grab; }

.pl-g1 { stroke: rgba(127, 224, 176, .07); fill: none; }
.pl-g10 { stroke: rgba(127, 224, 176, .16); fill: none; }
.pl-axis { stroke: rgba(240, 180, 41, .34); fill: none; }

.pl-room rect { fill: rgba(7, 11, 10, .3); stroke: #7fe0b0; cursor: move; }
.pl-room.sel rect { stroke: #f0b429; fill: rgba(240, 180, 41, .10); }
.pl-room.bad rect { stroke: #ff6b6b; }
.pl-room.k-service rect { stroke: #9fc4b4; }
.pl-room.k-hall rect { stroke: #7fe0b0; fill: rgba(127, 224, 176, .10); stroke-dasharray: 5 4; }
.pl-room.k-hall.sel rect { stroke-dasharray: none; }
.pl-room.k-venue rect, .pl-room.k-subroom rect { stroke: #8ad6a8; }
.pl-room.k-atrium rect, .pl-room.k-void rect { stroke: #38bdf8; }
.pl-room.k-exterior rect { stroke: #f0b429; }
.pl-room.k-overlay rect { stroke: #6c7f78; stroke-dasharray: 6 5; }
.pl-room.k-mystery rect { stroke: #c58af0; stroke-dasharray: 6 5; }

/* Doors. The fat transparent hit line is what you actually grab — a 3 ft door
   is a few pixels wide on a 340 ft sheet and would be unhittable otherwise. */
.pl-doorhit { stroke: transparent; cursor: move; }
.pl-doorjamb { stroke: #7fe0b0; stroke-linecap: round; pointer-events: none; }
.pl-doorleaf { stroke: #f0b429; stroke-linecap: round; pointer-events: none; }
.pl-doorarc { stroke: #f0b429; fill: none; stroke-dasharray: 3 3; opacity: .8; pointer-events: none; }
.pl-door.sel .pl-doorjamb { stroke: #fff2cc; }
.pl-door.sel .pl-doorleaf, .pl-door.sel .pl-doorarc { stroke: #ffd97a; opacity: 1; }
.pl-listitem.door b { color: #f0b429; }
.pl-selhead {
  font-size: 11px; letter-spacing: 1.5px; color: #f0b429;
  margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--edge);
}

.pl-label {
  fill: #d6e6df; text-anchor: middle; dominant-baseline: middle;
  font-family: var(--mono, ui-monospace, monospace); pointer-events: none; user-select: none;
}
.pl-label.dim { fill: #7d938b; }
.pl-dim {
  fill: #f0b429; text-anchor: middle; font-family: var(--mono, ui-monospace, monospace);
  pointer-events: none; user-select: none;
}
.pl-handle { fill: #f0b429; stroke: #070b0a; }

.pl-side {
  width: 320px; flex: 0 0 320px; overflow-y: auto; padding: 12px;
  border-left: 1px solid var(--edge); background: var(--panel);
}
.pl-list { margin-bottom: 14px; }
.pl-listhead { font-size: 11px; letter-spacing: 1px; color: var(--dim); margin-bottom: 6px; }
.pl-listbody { max-height: 30vh; overflow-y: auto; border: 1px solid var(--edge); border-radius: 3px; }
.pl-listitem {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  padding: 5px 8px; border: 0; border-bottom: 1px solid rgba(127, 224, 176, .08);
  background: transparent; color: var(--ink); text-align: left; cursor: pointer;
  font: 400 12px/1.35 var(--mono, ui-monospace, monospace);
}
.pl-listitem:last-child { border-bottom: 0; }
.pl-listitem:hover { background: rgba(127, 224, 176, .07); }
.pl-listitem.on { background: rgba(240, 180, 41, .14); color: #f0b429; }
.pl-listitem.bad b::after { content: ' ⚠'; color: #ff6b6b; }
.pl-listitem b { flex: 1; font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-listitem i { font-style: normal; color: var(--dim); font-size: 11px; }

.pl-empty { color: var(--dim); font-size: 12px; line-height: 1.5; margin: 0 0 10px; }
.pl-field { display: block; margin-bottom: 10px; }
.pl-field > span { display: block; font-size: 11px; letter-spacing: 1px; color: var(--dim); margin-bottom: 4px; }
.pl-field > i { display: block; font-size: 11px; font-style: normal; color: #6c7f78; margin-top: 3px; }
.pl-field input, .pl-field select, .pl-field textarea { width: 100%; }
.pl-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 10px; }
.pl-rowbtns { display: flex; gap: 8px; margin-top: 12px; }
.pl-rowbtns .btn { flex: 1; }
.btn.danger { border-color: #ff6b6b; color: #ff6b6b; }
.pl-preview { margin-top: 16px; }
.pl-preview summary { cursor: pointer; font-size: 11px; letter-spacing: 1px; color: var(--dim); }
.pl-preview img { width: 100%; margin-top: 8px; border: 1px solid var(--edge); background: #070b0a; }

/* On a phone the inspector goes underneath, because the canvas needs the width
   and this gets used standing in a hotel corridor. */
@media (max-width: 760px) {
  .pl-main { flex-direction: column; }
  .pl-canvaswrap { flex: 1 1 55%; }
  .pl-side { width: auto; flex: 1 1 45%; border-left: 0; border-top: 1px solid var(--edge); }
}

/* ------------------------------------------------------ touch targets

   Last in the file on purpose: these are minimums that must beat the base
   rules above, and they are all equal-specificity single-class selectors.
   Scoped to coarse pointers so desktop keeps its compact chrome. */

@media (pointer: coarse) {
  .btn, .btn.small, .exit, .iconbtn, .close,
  .map-node, .seq-options button, .sidebar-tabs button, .tabs button,
  .keypad button, .card .btn {
    min-height: var(--tap);
  }
  .iconbtn, .close { min-width: var(--tap); width: auto; }
  .close { font-size: 26px; }
  .btn.small { padding: 8px 14px; }
  .exit { padding: 11px 14px; }
  .sidebar-tabs button { padding: 9px 12px; min-width: var(--tap); }
  .seq-options button { padding: 11px 14px; }
  /* Percentage rects land a few px short of 44 on the narrowest phones because
     the frame height varies with viewport width. The content rects are authored
     close enough that this last nudge cannot make neighbours overlap. */
  .hotspot { min-width: 44px; min-height: 44px; }

  /* No hover on touch, so never leave a control in a hover-only state. */
  .hotspot:hover { background: transparent; }
  }

/* ------------------------------------------------------------- found list

   The only place a thing gets named, and only once the player has clicked it. */

.found { padding: 12px 14px calc(16px + env(safe-area-inset-bottom, 0px)); }
.found-head {
  display: flex; align-items: baseline; gap: 10px;
  border-bottom: 1px solid var(--edge); padding-bottom: 7px; margin-bottom: 10px;
}
.found-title { font-size: 11px; letter-spacing: 0.2em; color: var(--muted); }
.found-count { font-size: 11px; color: var(--ink-dim); margin-left: auto; font-variant-numeric: tabular-nums; }
.found-empty { color: var(--muted); font-size: 13px; line-height: 1.6; font-style: italic; }
.found-list { display: grid; gap: 7px; }

.found-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: var(--panel); border: 1px solid var(--edge); border-radius: 3px;
  color: var(--text); padding: 10px 12px; cursor: pointer; font-size: 13.5px;
  min-height: var(--tap);
}
.found-item:hover { border-color: var(--ink-dim); }
.found-item .fi-mark { color: var(--ink-dim); width: 14px; flex: 0 0 auto; text-align: center; }
.found-item .fi-label { flex: 1; }
.found-item .fi-pts { color: var(--warn); font-size: 12px; flex: 0 0 auto; }
.found-item.go .fi-mark { color: #7dd3fc; }
.found-item.go .fi-label { color: #cbe9fb; }
.found-item.puzzle .fi-mark { color: var(--ink); }
.found-item.done { border-color: rgba(110,231,168,0.32); }
.found-item.done .fi-mark, .found-item.done .fi-label { color: var(--good); }
.found-item.locked .fi-mark { color: var(--warn); }
.found-item.locked .fi-label { color: var(--muted); }

/* ---------------------------------------------------------- labyrinth map */

.automap-wrap {
  border: 1px solid var(--edge); border-radius: 3px; background: var(--bg-2);
  padding: 8px; overflow-x: auto;
}
.automap { width: 100%; max-width: 260px; height: auto; color: var(--ink-dim); display: block; margin: 0 auto; }
.automap-cell { cursor: pointer; }
.automap-cell:hover { fill: rgba(127,224,176,0.16) !important; }

/* ------------------------------------------------------- Myst-style cursors

   Two shapes, as in Myst: an open hand over anything you can take hold of, and
   a pointing finger at the screen edges for turning. Inline SVG data URIs so
   there are no asset requests and no external files to lose. The hotspot itself
   stays invisible — the cursor is the only tell, which is the whole point. */

:root {
  /* open hand — over something you can manipulate */
  --cur-grab: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><g fill="%23e8fff5" stroke="%2305100c" stroke-width="1.4" stroke-linejoin="round"><path d="M12 20V8.5a2 2 0 1 1 4 0V16"/><path d="M16 15.5V7a2 2 0 1 1 4 0v8.5"/><path d="M20 16V9.5a2 2 0 1 1 4 0V19"/><path d="M24 19v-4a2 2 0 1 1 4 0v9c0 4.5-3 7.5-7.5 7.5h-3C13 31.5 11 29 9.5 26L7 21.5a2 2 0 0 1 3.4-2.1L12 21.5"/></g></svg>') 17 17, grab;
  /* closed hand — the moment you press */
  --cur-grabbing: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><g fill="%23e8fff5" stroke="%2305100c" stroke-width="1.4" stroke-linejoin="round"><path d="M9 18c0-4 3-6 8-6h6c4.5 0 7 2.5 7 6.5v5c0 4.5-3 7.5-7.5 7.5h-3C14 31 11 28.5 9.5 25.5Z"/><path d="M12 13.5V10a2 2 0 1 1 4 0v3"/><path d="M16 12.5V9a2 2 0 1 1 4 0v3.5"/><path d="M20 13v-2.5a2 2 0 1 1 4 0V14"/></g></svg>') 17 17, grabbing;
  /* magnifier — something to inspect rather than handle */
  --cur-look: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><g fill="none" stroke="%23e8fff5" stroke-width="2.6"><circle cx="12.5" cy="12.5" r="7.5"/><path d="M18 18l8 8"/></g><g fill="none" stroke="%2305100c" stroke-width="1"><circle cx="12.5" cy="12.5" r="9"/></g></svg>') 12 12, zoom-in;
}

/* pointing finger, rotated per edge */

:root {
  --cur-point-l: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><g fill="%23e8fff5" stroke="%2305100c" stroke-width="1.4" stroke-linejoin="round"><path d="M14 17H4"/><path d="M14 12.5c-3 0-5 2-5 4.5s2 4.5 5 4.5h3v6.5c0 2 1.5 3.5 3.5 3.5h6c3 0 5.5-2.5 5.5-5.5v-9c0-2.5-2-4.5-4.5-4.5H17Z"/></g></svg>') 6 17, w-resize;
  --cur-point-r: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><g fill="%23e8fff5" stroke="%2305100c" stroke-width="1.4" stroke-linejoin="round"><path d="M20 17h10"/><path d="M20 12.5c3 0 5 2 5 4.5s-2 4.5-5 4.5h-3v6.5c0 2-1.5 3.5-3.5 3.5h-6C4.5 31.5 2 29 2 26v-9c0-2.5 2-4.5 4.5-4.5H17Z"/></g></svg>') 28 17, e-resize;
  --cur-point-u: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><g fill="%23e8fff5" stroke="%2305100c" stroke-width="1.4" stroke-linejoin="round"><path d="M17 14V4"/><path d="M12.5 14c0-3 2-5 4.5-5s4.5 2 4.5 5v3h6.5c2 0 3.5 1.5 3.5 3.5v6c0 3-2.5 5.5-5.5 5.5h-9c-2.5 0-4.5-2-4.5-4.5V17Z"/></g></svg>') 17 6, n-resize;
  --cur-point-d: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34"><g fill="%23e8fff5" stroke="%2305100c" stroke-width="1.4" stroke-linejoin="round"><path d="M17 20v10"/><path d="M21.5 20c0 3-2 5-4.5 5s-4.5-2-4.5-5v-3H6c-2 0-3.5-1.5-3.5-3.5v-6C2.5 4.5 5 2 8 2h9c2.5 0 4.5 2 4.5 4.5V17Z"/></g></svg>') 17 28, s-resize;
}

/* Hotspot cursor by what the thing is. */
.hotspot.cur-grab   { cursor: var(--cur-grab); }
.hotspot.cur-grab:active { cursor: var(--cur-grabbing); }
.hotspot.cur-look   { cursor: var(--cur-look); }
.hotspot.cur-go     { cursor: var(--cur-point-u); }

/* Turning. On the frame, at the middle of each edge, and VISIBLE — which is
   the whole difference from what was here before. The old controls were
   invisible strips 13% of the width down each side, so a door or a corridor
   near the edge of a shot sat underneath one and clicking the thing you could
   see turned you away from it. A small button you can actually see takes a
   fraction of the area and tells you what it is. */
.turnedge {
  position: absolute; z-index: 5;
  width: 44px; height: 78px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(127, 224, 176, .45); border-radius: 3px;
  background: rgba(5, 7, 6, .62);
  color: var(--ink); font-size: 30px; line-height: 1;
  cursor: pointer; padding: 0;
  -webkit-tap-highlight-color: transparent;
  backdrop-filter: blur(2px);
  transition: background 120ms, border-color 120ms;
}
.turnedge:hover { background: rgba(5, 7, 6, .85); border-color: var(--ink); }
.turnedge:active { background: rgba(127, 224, 176, .3); }
.turnedge:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.te-left  { left: 8px;  bottom: 8px; }
.te-right { right: 8px; bottom: 8px; }
.te-up    { left: 50%; top: 8px;    transform: translateX(-50%) rotate(90deg); }
.te-down  { left: 50%; bottom: 8px; transform: translateX(-50%) rotate(-90deg); }

@media (pointer: coarse) {
  .turnedge { width: var(--tap); height: 88px; }
}

/* A found thing that lives on another wall of this room. */
.found-item.elsewhere { opacity: 0.62; }
.found-item.elsewhere .fi-pts { color: var(--ink-dim); }

/* A close-up of the thing you just leaned in to look at. */
.zoomshot {
  width: 100%; height: auto; display: block; border-radius: 3px;
  border: 1px solid var(--edge); margin-bottom: 14px; background: #05100c;
}

/* ------------------------------------------------- challenge artifacts -- */
/* Files a puzzle hands the player: a capture, a dump, a photograph with
   something in it. Styled as a thing you are taking, not as a download list. */
.artifacts { margin: 14px 0 4px; border: 1px solid var(--edge); border-radius: 4px; }
.artifacts-head { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); padding: 7px 10px; border-bottom: 1px solid var(--edge); }
.artifact { display: flex; align-items: center; gap: 10px; padding: 9px 10px; }
.artifact + .artifact { border-top: 1px solid var(--edge); }
.a-meta { flex: 1 1 auto; min-width: 0; }
.a-label { font-size: 13.5px; color: var(--ink); }
.a-sub { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere; }
.a-note { font-size: 11.5px; color: var(--muted); margin-top: 3px; font-style: italic; }
.artifact-file-link { min-width: 0; overflow-wrap: anywhere; text-decoration: underline; }
.a-missing { flex: 0 0 auto; font-size: 10px; letter-spacing: 0.12em; color: var(--bad); }
@media (max-width: 560px) {
  .artifact { flex-wrap: wrap; }
}

/* ------------------------------------------------------------ zone editor */

/* Admin-only, and it deliberately looks like a tool rather than the game: the
   whole point is to see the boxes you are aiming, over the picture they sit on. */
/* While editing, a drag on the picture is aiming a box, never a page scroll.
   touch-action has to be none on the SCENE, not just on the zones: the browser
   intersects it up the ancestor chain, and a scrollable ancestor that still
   allows panning cancels the pointer mid-gesture — which reads as "drag does
   nothing at all" on a phone, and only on the first touch. */
.scene.zoning { cursor: default; touch-action: none; }
.scene.zoning img { opacity: 0.82; }

.zone {
  position: absolute; box-sizing: border-box;
  border: 1px solid var(--ink-dim); background: #7fe0b014;
  cursor: move; touch-action: none;
}
.zone.moved { border-color: var(--warn); background: #f0b4291f; }
.zone.sel { border-color: var(--ink); background: #7fe0b029; box-shadow: 0 0 0 1px var(--ink), 0 0 18px #7fe0b040; }
.zone-tag {
  position: absolute; left: 0; top: -17px; white-space: nowrap;
  font-size: 10px; letter-spacing: 0.1em; color: var(--ink);
  background: #050706d9; padding: 1px 5px; border-radius: 2px; pointer-events: none;
}
.zone.moved .zone-tag { color: var(--warn); }

/* Grips are invisible until the box is selected, so eight handles per zone do
   not turn the wall into a pincushion. Big hit areas, small marks. */
.zone .grip { position: absolute; width: 22px; height: 22px; touch-action: none; }
.zone.sel .grip::after {
  content: ''; position: absolute; inset: 7px;
  background: var(--ink); border-radius: 1px; box-shadow: 0 0 6px #7fe0b0a6;
}
.zone .g-nw { left: -11px; top: -11px; cursor: nwse-resize; }
.zone .g-n  { left: calc(50% - 11px); top: -11px; cursor: ns-resize; }
.zone .g-ne { right: -11px; top: -11px; cursor: nesw-resize; }
.zone .g-e  { right: -11px; top: calc(50% - 11px); cursor: ew-resize; }
.zone .g-se { right: -11px; bottom: -11px; cursor: nwse-resize; }
.zone .g-s  { left: calc(50% - 11px); bottom: -11px; cursor: ns-resize; }
.zone .g-sw { left: -11px; bottom: -11px; cursor: nesw-resize; }
.zone .g-w  { left: -11px; top: calc(50% - 11px); cursor: ew-resize; }

.zonepanel {
  border: 1px solid var(--ink-dim); border-radius: 3px; background: var(--panel);
  padding: 11px 12px; margin-top: 10px; display: grid; gap: 10px;
}
.zp-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.zp-title { font-size: 11px; letter-spacing: 0.14em; color: var(--ink); }
.zp-count { font-size: 11px; color: var(--muted); }
.zp-empty { font-size: 12px; color: var(--muted); line-height: 1.5; }
.zp-sel { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.zp-sel .btn.small { margin-left: auto; }
.zp-id { color: var(--ink); font-size: 13px; }
.zp-act { color: var(--muted); font-size: 11.5px; }
.zp-nums { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.zp-num { display: grid; gap: 3px; }
.zp-num span { font-size: 10px; letter-spacing: 0.12em; color: var(--muted); }
.zp-num input {
  background: var(--bg); color: var(--text); border: 1px solid var(--edge);
  border-radius: 3px; padding: 7px 8px; font-family: var(--mono); font-size: 14px; width: 100%;
}
.zp-warn { font-size: 11.5px; color: var(--warn); }
.zp-pick { display: flex; flex-wrap: wrap; gap: 6px; }
.zp-pick .moved { border-color: var(--warn); color: var(--warn); }
.zp-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.zp-hint { font-size: 11px; color: var(--muted); }

.zp-live { font-size: 11px; color: var(--muted); letter-spacing: 0.08em; }

/* ---------------------------------------------------- challenge editor */

.admin-strip {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 12px; border-top: 1px dashed var(--edge);
}
.as-tag { font-size: 10px; letter-spacing: 0.16em; color: var(--warn); }
.as-id { font-size: 11.5px; color: var(--muted); flex: 1; }
.challenge-review { flex-basis: 100%; margin: 10px 0; }
.challenge-review label, .editor .challenge-review label {
  display: flex; align-items: center; gap: 8px; min-height: 44px;
  color: var(--good); font-size: 13px; letter-spacing: normal; text-transform: none; cursor: pointer;
}
.challenge-review input { width: 20px; height: 20px; margin: 0; accent-color: var(--good); }
.review-status { color: var(--muted); font-size: 11px; overflow-wrap: anywhere; }

.ce { display: grid; gap: 14px; }
.ce-structure {
  display: grid; gap: 3px; font-size: 12px; color: var(--text);
  border: 1px solid var(--edge); border-radius: 3px; padding: 8px 10px; background: var(--bg-2);
}
.ce-structure b { color: var(--ink); font-weight: 400; }
.ce-ro { font-size: 11px; color: var(--muted); line-height: 1.45; }
.ce-field { display: grid; gap: 4px; }
.ce-field label { font-size: 10px; letter-spacing: 0.14em; color: var(--muted); }
.ce-hint { font-size: 11px; color: var(--muted); line-height: 1.4; }
.ce-field input, .ce-field textarea {
  background: var(--bg); color: var(--text); border: 1px solid var(--edge);
  border-radius: 3px; padding: 8px 9px; font-family: var(--mono); font-size: 13px; width: 100%;
}
.ce-field textarea { resize: vertical; line-height: 1.5; }
.ce-field input:focus, .ce-field textarea:focus { border-color: var(--ink-dim); outline: none; }

/* The room's caption and FOUND list when the menu is holding them (landscape). */
.side-here { margin-bottom: 18px; padding-bottom: 16px; border-bottom: 1px solid var(--edge); }
.side-here .caption { padding: 0 0 10px; }

/* Zone editor: adding, deleting, and re-pointing a zone ---------------------
   A zone that does not exist yet is drawn dashed, so it reads as pending
   rather than as something already in the game. */
.zone.fresh { border-style: dashed; border-color: var(--ink); }
.zone.fresh .zone-tag::before { content: '+ '; }

/* The kind/target selects. Full width because a node id plus its name is long,
   and stacked because on a phone they would otherwise be three across. */
.zp-pickrow {
  display: grid; grid-template-columns: 76px 1fr; align-items: center;
  gap: 8px; margin-top: 6px;
}
.zp-pickrow > span {
  font-size: 10px; letter-spacing: .14em; color: var(--muted); text-transform: uppercase;
}
.zp-pickrow select {
  width: 100%; min-width: 0; padding: 7px 9px;
  font: inherit; font-size: 12px;
  color: var(--text); background: var(--panel-2, #0f1613);
  border: 1px solid var(--edge); border-radius: 3px;
}
.zp-pickrow select:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }

.btn.danger { border-color: var(--bad, #f2685c); color: var(--bad, #f2685c); }
.btn.danger:hover { background: #f2685c1f; }
/* A pending deletion stays in the list, struck through, so it can be taken back
   before save. */
.btn.struck { text-decoration: line-through; opacity: .6; }

/* Lights that are still on ---------------------------------------------------
   A view can declare `glows`: soft lights positioned in percent of the frame,
   like hotspots, and drawn over the art. `screen` blending means they ADD
   light to the photograph instead of laying a grey patch on it, so a dark
   picture keeps its blacks and only the lit thing brightens.

   Two periods that do not divide into each other, so the pair never settles
   into an obvious loop, and irregular keyframe stops so neither one is a
   metronome. */
.glow {
  position: absolute;
  pointer-events: none;          /* never in the way of the hotspot underneath */
  border-radius: 50%;
  mix-blend-mode: screen;
  will-change: opacity;
}

/* A screen refreshing: cool, small, and never quite steady. */
.glow-screen {
  background: radial-gradient(ellipse at center,
    rgba(150, 200, 255, 0.50) 0%,
    rgba(95, 145, 215, 0.24) 38%,
    rgba(40, 70, 120, 0) 72%);
  animation: glow-crt 6.3s linear infinite;
}
@keyframes glow-crt {
  0%, 100% { opacity: .82 }
  7%       { opacity: .95 }
  9%       { opacity: .71 }
  23%      { opacity: .88 }
  25%      { opacity: .68 }
  47%      { opacity: .97 }
  52%      { opacity: .79 }
  69%      { opacity: .87 }
  71%      { opacity: .64 }
  88%      { opacity: .92 }
}

/* A work lamp on a car battery: warm, wide, and slowly breathing as the
   charge sags and recovers. */
.glow-lamp {
  background: radial-gradient(ellipse at center,
    rgba(255, 196, 120, 0.34) 0%,
    rgba(215, 150, 80, 0.16) 42%,
    rgba(120, 80, 40, 0) 74%);
  animation: glow-lamp 11.7s ease-in-out infinite;
}
@keyframes glow-lamp {
  0%, 100% { opacity: .58; transform: scale(1) }
  38%      { opacity: .74; transform: scale(1.035) }
  61%      { opacity: .63; transform: scale(1.01) }
}

/* Someone who has asked for stillness gets the light, not the flicker. */
@media (prefers-reduced-motion: reduce) {
  .glow { animation: none !important; }
  .glow-screen { opacity: .84 }
  .glow-lamp { opacity: .64 }
}

/* The zone id is editable in place: renaming a zone is a normal thing to want
   and used to mean hand-editing content/nodes.json. It looks like the label it
   replaced until you focus it. */
input.zp-id {
  font: inherit; font-size: 13px; color: var(--ink);
  background: transparent; border: 1px solid transparent; border-radius: 3px;
  padding: 2px 5px; min-width: 8ch; width: 18ch; max-width: 100%;
}
input.zp-id:hover { border-color: var(--edge); }
input.zp-id:focus { background: var(--panel-2, #0f1613); border-color: var(--ink); outline: none; }

.challenge-toolbar { padding: 12px 0; }
.challenge-toolbar select { width: 100%; padding: 10px; color: var(--text); background: var(--panel); border: 1px solid var(--edge); }
.md-title small { display: block; opacity: .65; font-size: .75em; margin-top: 4px; }
.sidebar-tabs { flex-wrap: wrap; }

.archive-request { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; margin: 16px 0; }
.acoustic-stage { height:100%; width:100%; display:grid; place-items:center; }
.acoustic-surface { position:relative; max-width:100%; max-height:100%; aspect-ratio:3/2; height:100%; }
.acoustic-surface > img { width:100%; height:100%; display:block; object-fit:contain; }
.acoustic-control { position:absolute; z-index:3; border:0; background:transparent; cursor:grab; touch-action:none; border-radius:50%; }
.acoustic-control:focus-visible { outline:3px solid #e6c484; }
.acoustic-control:active,.acoustic-control.listening { background:#e6c48430; box-shadow:inset 0 0 14px #e6c484; }
.acoustic-lamp { position:absolute; border-radius:50%; pointer-events:none; }
.acoustic-lamp.lit { background:#ffc873aa; box-shadow:0 0 10px #ffbe5a; }
.ambient-caption { color:var(--muted); font-size:12px; }
.archive-request pre { grid-column: 1 / -1; white-space: pre-wrap; overflow-wrap: anywhere; }
.evidence-sources { display: grid; gap: 8px; margin: 16px 0; }
.evidence-sources .btn { white-space: normal; text-align: left; justify-content: flex-start; }
@media (max-width: 560px) { .archive-request { grid-template-columns: minmax(0, 1fr); } }

/* Navigation is opened deliberately; inspecting never creates a second column. */
#side { display: none; }
#side.open { display: block; position: fixed; inset: var(--topbar-h, 53px) 0 0; z-index: 55; width: auto; height: auto; max-height: none; overflow-y: auto; padding: clamp(16px, 3vw, 40px); background: #080d0b; border: 0; }
#side[hidden], .inspection-body[hidden], #info-toggle[hidden] { display: none; }
.scene-wrap { flex-direction: column; align-items: stretch; }
.menu-toggle { flex: none; color: #06110c; background: var(--ink); font-weight: 800; min-height: 44px; }
.info-toggle { flex: none; min-height: 44px; color: #06110c; background: var(--ink); border: 1px solid var(--ink); box-shadow: 0 2px 8px #0008; }
.info-toggle:hover { background: #b4f6d4; }
.info-toggle:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.challenge-actions { display: inline-flex; align-items: center; gap: 8px; flex: none; white-space: nowrap; }
.challenge-actions > .info-toggle { position: static; margin: 0; }
.inspection-body > .info-toggle { display: block; position: sticky; bottom: 0; z-index: 5; margin: 12px 0 0 auto; }
.inspection-body:has(.mission-record) > .info-toggle { position: static; }
.inspection-frame > #info-toggle { position: absolute; right: 8px; bottom: 8px; z-index: 15; margin: 0; }
#side > .sidebar-tabs { position: sticky; top: -1px; padding: 12px 0; background: #080d0b; z-index: 2; }
#side .sidebar-tabs button { min-height: 44px; }
.inspection-frame > .inspection-body { position: absolute; z-index: 8; box-sizing: border-box; width: min(680px, 84%); max-height: 44%; overflow: auto; overscroll-behavior: contain; padding: 16px 20px; border: 1px solid #83b49d; border-radius: 8px; background: rgba(5, 12, 9, .96); box-shadow: 0 10px 36px #0009; font-size: 14px; line-height: 1.5; text-align: left; }
.inspection-body[data-position^="bottom"] { bottom: 14px; }
.inspection-body[data-position^="top"] { top: 48px; }
.inspection-body[data-position$="left"] { left: 14px; width: min(500px, 45%); }
.inspection-body[data-position$="right"] { right: 14px; width: min(500px, 45%); }
.inspection-body[data-position$="center"] { left: 50%; transform: translateX(-50%); }
.inspection-body[data-position^="center"] { top: 50%; transform: translateY(-50%); }
.info-heading h3 { margin: 0 0 10px; font-size: 16px; color: var(--ink); }
.inspection-body .answer-row, .inspection-body .artifact { flex-wrap: wrap; }
.inspection-body .answer-row input { min-width: 0; flex: 1 1 160px; }
.inspection-body .as-id { flex-basis: 100%; }
.source-record { border-top: 1px solid var(--edge); margin-top: 12px; padding-top: 8px; }
.source-record summary { cursor: pointer; color: var(--ink); padding-block: 5px; }
.info-position-editor { display: flex; flex-wrap: wrap; gap: 8px; padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--ink); }
.info-position-editor strong { width: 100%; }
@media (max-width: 700px) {
  .topbar { gap: 6px; }
  .topbar .brand { display: none; }
  .menu-toggle, .info-toggle { padding: 8px 10px; font-size: 12px; }
  .inspection-frame > .inspection-body { max-height: 70%; padding: 10px 12px; width: 94%; font-size: 13px; }
  .inspection-body[data-position$="left"] { left: 3%; }
  .inspection-body[data-position$="right"] { right: 3%; }
  .inspection-body[data-position^="bottom"] { bottom: 6px; }
  .inspection-body[data-position^="top"] { top: 32px; }
}
.map-toolbar { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; }
.map-toolbar select { max-width: 100%; margin: 8px 0; }
.hotel-plan-scroll { overflow: auto; background: #101b17; border: 1px solid var(--edge); margin: 16px 0 24px; max-height: 65vh; }
.hotel-plan { display: block; min-width: 800px; width: 100%; min-height: 340px; max-height: 1000px; }
.hotel-map-room rect { fill: #15231e; stroke: #607c6d; stroke-width: .45; }
.hotel-map-room text { fill: #899c92; pointer-events: none; }
.hotel-map-room.available { cursor: pointer; }
.hotel-map-room.available rect { fill: #233e31; stroke: #8fc4a6; }
.hotel-map-room.available text { fill: #eff9f3; }
.hotel-map-room.available:hover rect, .hotel-map-room.available:focus rect { fill: #38694e; stroke: white; stroke-width: 1; }
.hotel-map-room.current rect { fill: #405b35; stroke: #e5d492; stroke-width: 1; }
.map-destinations { display: flex; flex-wrap: wrap; gap: 8px; }
.map-destinations .btn { min-height: 44px; }
/* Portrait leaves useful space below the photograph; use it without covering evidence. */
@media (max-width: 700px) and (orientation: portrait) {
  .inspection-viewport { display: block; overflow-y: auto; overscroll-behavior: contain; }
  .inspection-frame, .inspection-frame.has-phone, .inspection-frame:has(.is-expanded) { width: 100%; height: auto; max-height: none; }
  .inspection-frame > .inspection-body { position: relative; inset: auto; transform: none; width: calc(100% - 16px); max-height: none; margin: 10px 8px 18px; }
  .inspection-frame .phone-face { height: min(58dvh, 580px); max-width: 100%; }
  .inspection-frame .terminal-stage.is-expanded { height: 48dvh; min-height: 240px; }
  .inspection-frame .image-device-stage, .inspection-frame .lighting-stage { height: auto; }
  .inspection-frame .patch-stage.is-expanded { max-height: 52dvh; }
  .inspection-body input, .inspection-body select, .terminal-entry input { font-size: 16px; }
}
@media (orientation: landscape) and (max-height: 560px) {
  .topbar { min-height: 44px; padding: 4px 8px; flex-wrap: nowrap; }
  .topbar .brand, .topbar .stat.progress, .topbar .stat.rank { display: none; }
  .inspection-frame > .inspection-body { max-height: 72%; font-size: 13px; padding: 10px 14px; }
  .inspection-body[data-position^="top"] { top: 32px; }
}
/* The handset and keypad end above this strip on the authored payphone face. */
.inspection-frame.has-phone > .inspection-body[data-position="bottom-center"] { max-height: 27%; bottom: 8px; }
@media (max-width: 700px) and (orientation: portrait) {
  .inspection-frame.has-phone > .inspection-body[data-position="bottom-center"] { max-height: none; bottom: auto; }
}
#room-return[hidden] { display: none; }
.room-return { min-height: 44px; flex: none; padding: 8px 10px; }
.menu-account-tools { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
.menu-account-tools .iconbtn { min-width: 44px; min-height: 44px; }
@media (max-width: 700px) { .room-return { font-size: 12px; } .topbar .stat.progress { display: none; } }
.menu-progress { color: var(--muted); margin-bottom: 12px; }
.menu-progress summary { cursor: pointer; padding: 8px 0; }
.menu-progress > div { padding: 12px 0; }
.menu-account-tools { margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--edge); }
@media (max-width: 700px) {
  #side > .sidebar-tabs { flex-wrap: nowrap; overflow-x: auto; }
  #side .sidebar-tabs button { flex: none; }
  #side .map-toolbar { margin-bottom: 4px; }
}

/* The directory has its own layout; sidebar-sized lists waste a desktop viewport. */
#side.open { padding: 28px clamp(20px, 3vw, 56px) 40px; background: radial-gradient(ellipse at 85% 0, #19352a65, transparent 60%), #080d0b; }
.menu-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid #31473c; border-radius: 10px; background: #10201980; margin-bottom: 28px; }
.menu-metric { padding: 18px 24px; border-right: 1px solid #31473c; }
.menu-metric:last-child { border: 0; }
.menu-metric strong { display: block; color: #e3eee8; font-size: clamp(20px, 2vw, 30px); font-weight: 500; font-variant-numeric: tabular-nums; line-height: 1.3; }
.menu-metric span { display: block; color: #9dafA5; font-size: 10px; letter-spacing: .1em; margin-top: 6px; }
#side button:focus-visible, #side select:focus-visible, #side a:focus-visible { outline: 2px solid #b9efd2; outline-offset: 3px; }
.menu-content { min-width: 0; }
.menu-section-heading { margin-bottom: 24px; }
.menu-section-heading h2 { font-size: 24px; font-weight: 500; letter-spacing: -.025em; color: #e3eee8; margin: 0 0 8px; }
.menu-section-heading p { color: #9dafA5; font-size: 13px; line-height: 1.65; margin: 0; }
.challenge-toolbar { display: flex; justify-content: flex-end; margin-bottom: 18px; }
.challenge-groups, .menu-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 310px), 1fr)); gap: 18px; align-items: start; }
#side .challenge-groups > section, #side .menu-card-grid > .card { margin: 0; border: 1px solid #30483b; border-radius: 8px; padding: 18px; background: linear-gradient(135deg, #14271d90, #0c1510); min-width: 0; }
#side .challenge-groups h3 { color: #adbeB4; line-height: 1.6; margin-bottom: 14px; }
#side .md-item { min-height: 60px; padding: 12px 8px; border-bottom: 1px solid #263d30; gap: 12px; }
#side .md-item:last-child { border-bottom: 0; }
#side .md-item:hover { background: #23433380; }
#side .md-title { line-height: 1.5; }
#side .md-title small { color: #9dafA5; margin-top: 4px; }
#side .field-challenge-group { grid-column: auto; }
.menu-card-grid > .flavor { grid-column: 1 / -1; }
.menu-card-grid .card p { line-height: 1.65; }
.hotel-map-drawing { min-width: 0; }
.map-legend { display: flex; flex-wrap: wrap; gap: 18px; color: #a4d3b8; padding: 14px 0; font-size: 11px; }
.map-legend .current { color: #e5d492; }
.map-legend .locked { color: #899c92; }
#side .board { background: #11201780; border: 1px solid #30483b; }
#side .board td, #side .board th { padding: 14px 18px; }
.menu-content[data-section="feed"] .feed-item { padding: 18px; border-left: 2px solid #40634e; background: #12221980; margin-bottom: 10px; line-height: 1.7; }
@media (max-width: 900px) {
  #side.open { padding: 20px; }
  .menu-content { width: 100%; }
  .menu-metrics { margin-bottom: 20px; }
  .menu-metric { padding: 14px; }
  .menu-section-heading { margin-bottom: 18px; }
}
@media (max-width: 520px) {
  #side.open { padding: 16px; }
  .menu-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .menu-metric:nth-child(2) { border-right: 0; }
  .menu-metric:nth-child(-n+2) { border-bottom: 1px solid #31473c; }
  .menu-metric span { font-size: 9px; }
  .challenge-toolbar select { width: 100%; }
  .challenge-toolbar { display: block; }
  .menu-section-heading h2 { font-size: 22px; }
  #side .board td, #side .board th { padding: 10px 7px; }
}
#side .hotel-map-drawing { border: 1px solid #30483b; border-radius: 8px; background: linear-gradient(#17302570 1px, transparent 1px), linear-gradient(90deg, #17302570 1px, transparent 1px), #0e1913; background-size: 24px 24px; }
#side .hotel-plan { width: 100%; min-width: 0; min-height: 0; max-height: none; height: auto; }
.location-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 12px; }
#side .location-group { margin-bottom: 28px; }
#side .location-group h3 { color: #adbeB4; margin-bottom: 14px; line-height: 1.6; }
.location-card { position: relative; display: flex; flex-direction: column; gap: 10px; text-align: left; padding: 20px 40px 20px 18px; border: 1px solid #30483b; border-radius: 8px; color: #d6e4dc; background: #12221980; cursor: pointer; font: inherit; min-width: 0; }
.location-card:hover { background: #234333; border-color: #8acba7; }
.location-card.current { border-color: #b6a66b; background: #353d2280; }
.location-card-title { font-size: 14px; line-height: 1.5; }
.location-card .meta { font-size: 10px; color: #9dafA5; line-height: 1.5; }
.location-arrow { position: absolute; right: 16px; top: 22px; color: #8acba7; }
.menu-content[data-section="collection"] .map-act { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 18px; margin-bottom: 24px; }
.menu-content[data-section="collection"] .map-act > h3 { grid-column: 1 / -1; }
.menu-content[data-section="collection"] .card { margin: 0; }

/* Page navigation stays first; progress belongs to the page it describes. */
#side.open { padding-top: 0; }
.menu-navigation { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: 24px; padding: 18px 0; margin-bottom: 28px; border-bottom: 1px solid #31473c; background: #0a120eee; backdrop-filter: blur(12px); }
#side .menu-navigation .sidebar-tabs { display: flex; flex-direction: row; flex-wrap: nowrap; overflow-x: auto; gap: 6px; margin: 0; padding: 3px; min-width: 0; flex: 1; }
#side .menu-navigation .sidebar-tabs button { flex: none; padding: 12px 16px; border: 1px solid transparent; border-radius: 6px; color: #a7bab0; font-size: 12px; }
#side .menu-navigation .sidebar-tabs button:hover { background: #14261c; color: #e1f3e9; }
#side .menu-navigation .sidebar-tabs button[aria-selected="true"] { background: #1c392b; color: #b4f6d4; border-color: #436d55; box-shadow: inset 0 -2px #89d8b0; }
.menu-close { flex: none; font-size: 11px; min-height: 44px; }
.menu-section-heading { display: flex; justify-content: space-between; align-items: center; gap: 24px; margin-bottom: 24px; }
.menu-section-heading h2 { font-size: clamp(24px, 2.5vw, 34px); }
.menu-section-heading .menu-metrics { display: flex; flex: none; margin: 0; border: 0; background: none; border-radius: 0; }
.menu-section-heading .menu-metric { padding: 4px 24px; min-width: 140px; }
.menu-section-heading .menu-metric:last-child { padding-right: 0; }
.menu-section-heading .menu-metric strong { font-size: 24px; }
.menu-footer { margin-top: 32px; }
.menu-footer .menu-account-tools { margin-bottom: 0; }
@media (max-width: 900px) {
  .menu-navigation { gap: 12px; margin-bottom: 20px; padding: 12px 0; }
  #side .menu-navigation .sidebar-tabs button { padding: 10px 12px; font-size: 11px; }
  .menu-section-heading { align-items: flex-start; }
  .menu-section-heading .menu-metric { min-width: 0; padding-inline: 16px; }
}
@media (max-width: 600px) {
  .menu-navigation { gap: 8px; }
  .menu-close { font-size: 10px; padding: 8px; max-width: 70px; white-space: normal; }
  .menu-section-heading { flex-direction: column; gap: 16px; }
  .menu-section-heading .menu-metrics { width: 100%; }
  .menu-section-heading .menu-metric { flex: 1; border-bottom: 0; padding: 4px 16px; }
  .menu-section-heading .menu-metric:first-child { padding-left: 0; }
}
body:has(#side.open) .topbar .stat { display: none; }
body:has(#side.open) .topbar #info-toggle, body:has(#side.open) .topbar #room-return { display: none; }
.inspection-frame > .inspection-body.custom-info-position {
  left: var(--info-x); top: var(--info-y); width: var(--info-w); height: var(--info-h);
  right: auto; bottom: auto; transform: none; max-height: none;
}
.inspection { position: relative; }
.inspection > .info-position-editor { position: relative; flex: none; z-index: 30; margin: 8px; padding: 12px; background: #101c15f5; border: 1px solid #a6ddbb; border-radius: 6px; max-height: 35%; overflow: auto; }
.info-position-editor label { display: flex; align-items: center; gap: 4px; }
.info-position-editor input { width: 72px; min-width: 0; padding: 6px; }
.info-position-editor [role="status"] { flex-basis: 100%; font-size: 12px; }
.inspection-frame > .info-box-outline { position: absolute; z-index: 20; pointer-events: none; border: 2px dashed #d5ef8e; box-sizing: border-box; }
.info-geometry-handle { position: absolute; pointer-events: auto; touch-action: none; background: #d5ef8e; border: 1px solid #182212; color: #182212; width: 20px; height: 20px; padding: 0; }
.info-geometry-handle.move { top: 0; left: 50%; transform: translateX(-50%); width: 80px; height: 28px; cursor: move; font-weight: bold; }
.info-geometry-handle.nw { top: 0; left: 0; cursor: nwse-resize; }
.info-geometry-handle.ne { top: 0; right: 0; cursor: nesw-resize; }
.info-geometry-handle.sw { bottom: 0; left: 0; cursor: nesw-resize; }
.info-geometry-handle.se { bottom: 0; right: 0; cursor: nwse-resize; }
.info-heading .edit-info-box { margin-bottom: 8px; }
@media (max-width: 700px) and (orientation: portrait) {
  .inspection-frame:not(.editing-info) > .inspection-body.custom-info-position { position: relative; inset: auto; width: calc(100% - 16px); height: auto; transform: none; }
  .inspection-frame.editing-info > .inspection-body { position: absolute; margin: 0; }
}
.menu-content .map-toolbar, .menu-content .challenge-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 24px; margin: 0 0 24px; }
.menu-content .map-toolbar > label { min-width: 0; flex: 1; max-width: 650px; }
.menu-content .challenge-toolbar > select { flex: 1; width: auto; min-width: 0; max-width: 650px; }
.menu-content .menu-metrics { display: flex; flex: none; border: 0; background: none; margin: 0; }
.menu-content .menu-metric { padding: 4px 20px; border-bottom: 0; }
.menu-content .menu-metric:last-child { padding-right: 0; }
.menu-content .menu-metric strong { font-size: 24px; }
.page-summary { display: flex; justify-content: flex-end; margin-bottom: 20px; }
@media (max-width: 600px) {
  .menu-content .map-toolbar, .menu-content .challenge-toolbar { gap: 12px; flex-wrap: wrap; }
  .menu-content .map-toolbar > label, .menu-content .challenge-toolbar > select { flex-basis: 100%; max-width: none; }
  .menu-content .menu-metric { padding-inline: 16px; }
  .menu-content .menu-metric:first-child { padding-left: 0; }
}
.toast-wrap { pointer-events: none; }

.inspection > .info-position-editor select { width: auto; max-width: 100%; }
/* One persistent navigation bar connects the scene and the directory pages. */
.topbar { flex-wrap: nowrap; gap: 12px; }
.hotel-tabs { display: flex; align-items: center; flex: 1 1 auto; min-width: 0; gap: 4px; overflow-x: auto; padding: 3px; scrollbar-width: thin; }
.hotel-tabs button { flex: none; min-height: 44px; padding: 10px 14px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: #a7bab0; font: inherit; font-size: 11px; letter-spacing: .06em; cursor: pointer; }
.hotel-tabs button:hover { background: #14261c; color: #e1f3e9; }
.hotel-tabs button[aria-current="page"] { background: #1c392b; color: #b4f6d4; border-color: #436d55; box-shadow: inset 0 -2px #89d8b0; }
.hotel-tabs button:focus-visible { outline: 2px solid #b9efd2; outline-offset: -2px; }
#side.open { padding-top: 24px; }
@media (max-width: 700px) {
  .topbar { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px; padding: 6px 8px; }
  .hotel-tabs { width: 100%; }
  .hotel-tabs button { padding: 10px; }
  .topbar .info-toggle, .topbar .room-return { justify-self: start; }
  #side.open { padding-top: 16px; }
}

/* Fit the complete plan into the remaining page space, preserving its geometry. */
#side.open:has(.hotel-map) { display: grid; grid-template-rows: minmax(0, 1fr) auto; overflow: hidden; padding-bottom: 12px; }
.menu-content[data-section="map"] { min-height: 0; display: flex; flex-direction: column; }
.hotel-map { flex: 1; min-height: 0; display: grid; grid-template-rows: auto minmax(0, 1fr); }
.hotel-map-content { min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto; }
#side .hotel-map-drawing { min-height: 0; }
#side .hotel-map .hotel-plan { width: 100%; height: 100%; }
#side .hotel-map .map-toolbar { margin-bottom: 12px; }
#side .hotel-map .map-legend { padding: 8px 0; gap: 12px; }
#side:has(.hotel-map) .menu-footer { margin-top: 4px; }
#side:has(.hotel-map) .menu-account-tools { margin: 0; padding-top: 8px; gap: 8px; }
@media (max-height: 560px) {
  #side.open:has(.hotel-map) { padding-top: 8px; padding-bottom: 8px; }
  #side .hotel-map .map-toolbar { margin-bottom: 6px; }
  #side .hotel-map .map-toolbar select { margin: 4px 0; }
  #side:has(.hotel-map) .menu-account-tools .ambient-caption { font-size: 11px; }
}
.staff-notice { margin: 14px 0; padding: 12px 16px; border-left: 3px solid #bfa46c; background: #bfa46c0c; }
.staff-notice h4 { margin: 0 0 8px; color: #d8c58e; font-size: 11px; letter-spacing: .12em; }
.staff-notice p:last-child { margin-bottom: 0; }
.camera-open { position: absolute; right: 12px; bottom: 12px; z-index: 5; }
.terminal-stage.showing-cameras > .terminal,
.terminal-stage.showing-cameras > .terminal-photo,
.terminal-stage.showing-cameras > .camera-open { visibility: hidden; }
.camera-bank { position: absolute; inset: 0; background: #090e10; color: #c9ded2; display: flex; flex-direction: column; padding: 44px 10px 10px; gap: 8px; }
.camera-bank[hidden] { display: none; }
.camera-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; font: 12px monospace; }
.camera-detail { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; gap: 8px; }
.inspection-frame:has(.showing-cameras) { display: flex; flex-direction: column; width: 100%; height: 100%; padding-top: 44px; box-sizing: border-box; }
.inspection-frame .terminal-stage.showing-cameras { flex: 1 1 0; min-height: 0; height: auto; aspect-ratio: auto; width: 100%; }
.terminal-stage.showing-cameras > .terminal-photo { display: none; }
.showing-cameras .camera-bank { padding-top: 8px; }
.inspection-frame:has(.showing-cameras) > .inspection-body { position: relative; inset: auto; transform: none; width: 100%; height: auto; max-height: 32%; min-height: 0; flex: 0 1 auto; margin: 8px 0 0; order: 2; }
.inspection-frame > .inspection-body[data-position="bottom-wide"] { left: 0; right: 0; top: auto; bottom: 0; transform: none; width: 100%; height: auto; max-height: 30%; margin: 0; padding: 10px 14px; border-radius: 0; }
.inspection-body[data-position="bottom-wide"] .info-heading h3 { margin: 0 0 6px; }
.inspection-body[data-position="bottom-wide"] .prose { margin: 6px 0; }
@media (max-width: 700px) and (orientation: portrait) {
  .inspection-frame > .inspection-body[data-position="bottom-wide"] { position: relative; max-height: none; }
}
.inspection-frame:has(.showing-cameras) > .inspection-body[data-position="bottom-wide"] { position: relative; max-height: 30%; }
.card-reader-stage { position: relative; aspect-ratio: 3 / 2; overflow: hidden; }
.card-reader-canvas { position: relative; width: 100%; aspect-ratio: 3 / 2; container-type: inline-size; }
.card-reader-canvas > img { display: block; width: 100%; height: 100%; object-fit: contain; }
.card-reader-screen { position: absolute; margin: 0; box-sizing: border-box; padding: 1cqw; overflow: auto; background: #101a13; color: #c5e6b0; font: max(10px, 1.1cqw)/1.3 monospace; white-space: pre-wrap; text-shadow: 0 0 2px #b5e8aa55; }
.card-reader-key { position: absolute; padding: 0; border: 1px solid transparent; border-radius: 7%; background: transparent; cursor: pointer; }
.card-reader-key:hover { background: #b4f6d41a; border-color: #b4f6d477; }
.card-reader-key:active { background: #b4f6d433; }
.card-reader-key:focus-visible { outline: 2px solid #b4f6d4; outline-offset: 2px; }
.camera-detail-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font: 12px monospace; }
.camera-feed-label { margin-right: auto; }
.camera-detail-toolbar button { min-width: 36px; min-height: 36px; }
.camera-viewport { flex: 1; min-height: 0; overflow: auto; background: #000; cursor: zoom-in; overscroll-behavior: contain; }
.camera-viewport.magnified { cursor: grab; }
.camera-viewport.magnified:active { cursor: grabbing; }
.camera-canvas { width: 100%; height: 100%; }
.camera-canvas img { display: block; width: 100%; height: 100%; max-width: none; object-fit: contain; user-select: none; }
@media (max-width: 600px) {
  .card-reader-stage { aspect-ratio: 15 / 22; }
  .card-reader-canvas { width: 220%; left: -60%; }
  .camera-feed-label { width: 100%; order: -1; }
}

/* Personal handles stay outside the scrolling text so they remain reachable. */
.inspection-frame > .personal-info-outline { position: absolute; z-index: 22; pointer-events: none; box-sizing: border-box; }
.personal-info-outline[hidden] { display: none; }
.personal-info-edge, .personal-info-handle { position: absolute; pointer-events: auto; touch-action: none; user-select: none; padding: 0; margin: 0; border: 0; border-radius: 0; background: transparent; }
.personal-info-edge { cursor: move; }
.personal-info-edge.n, .personal-info-edge.s { left: 0; width: 100%; height: 10px; }
.personal-info-edge.n { top: 0; }
.personal-info-edge.s { bottom: 0; }
.personal-info-edge.e, .personal-info-edge.w { top: 0; height: 100%; width: 10px; }
.personal-info-edge.e { right: 0; }
.personal-info-edge.w { left: 0; }
.personal-info-handle { width: 20px; height: 20px; z-index: 1; }
.personal-info-handle::after { content: ''; position: absolute; width: 8px; height: 8px; background: var(--ink); border: 1px solid #183d2c; box-shadow: 0 0 2px #000; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.personal-info-handle.nw { left: 0; top: 0; transform: translate(-50%, -50%); cursor: nwse-resize; }
.personal-info-handle.n { left: 50%; top: 0; transform: translate(-50%, -50%); cursor: ns-resize; }
.personal-info-handle.ne { right: 0; top: 0; transform: translate(50%, -50%); cursor: nesw-resize; }
.personal-info-handle.e { right: 0; top: 50%; transform: translate(50%, -50%); cursor: ew-resize; }
.personal-info-handle.se { right: 0; bottom: 0; transform: translate(50%, 50%); cursor: nwse-resize; }
.personal-info-handle.s { left: 50%; bottom: 0; transform: translate(-50%, 50%); cursor: ns-resize; }
.personal-info-handle.sw { left: 0; bottom: 0; transform: translate(-50%, 50%); cursor: nesw-resize; }
.personal-info-handle.w { left: 0; top: 50%; transform: translate(-50%, -50%); cursor: ew-resize; }
/* The border reveals every grip without covering or intercepting the text. */
.personal-info-handle::after { opacity: 0; }
.personal-info-outline:hover .personal-info-handle::after,
.personal-info-outline:has(:focus-visible) .personal-info-handle::after,
.moving-personal-info .personal-info-handle::after { opacity: 1; }
.personal-info-edge:focus-visible, .personal-info-handle:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.inspection-frame > .inspection-body.personal-info-position.custom-info-position {
  position: absolute; left: var(--info-x); top: var(--info-y); right: auto; bottom: auto;
  width: var(--info-w); height: var(--info-h); max-height: none; min-height: 0;
  margin: 0; transform: none; flex: none; overflow: auto;
}
.moving-personal-info { user-select: none; }
.inspection-frame:has(.pool-table-stage) { --image-ratio: 1.03; }
.inspection-frame:has(.pool-table-stage) > .inspection-title { display: none; }
.pool-table-stage { padding-bottom: 30%; background: #0e1717; }
.pool-table-canvas { position: relative; width: 100%; isolation: isolate; }
.pool-table-canvas > img { display: block; width: 100%; user-select: none; pointer-events: none; }
.pool-ball, .pool-pocket { position: absolute; transform: translate(-50%, -50%); touch-action: none; }
.pool-pocket { width: max(44px, 10%); aspect-ratio: 1; border: 2px solid transparent; border-radius: 50%; padding: 0; background: transparent; z-index: 2; }
.pool-pocket.available { z-index: 4; border-color: #ffe49b99; background: #ffe49b12; }
.pool-pocket:hover, .pool-pocket:focus-visible { outline: 3px solid #ffe49b; outline-offset: 2px; }
.pool-ball {
  width: clamp(24px, 3.75%, 36px); aspect-ratio: 1; padding: 0; appearance: none;
  border: 0; border-radius: 50%; background: var(--ball-color);
  box-shadow: inset -3px -4px 6px #0009, inset 1px 1px 3px #fff6, 1px 3px 3px #0009;
  z-index: 3; cursor: grab; display: grid; place-items: center; isolation: isolate;
}
/* Keep a forgiving grab target around the smaller photographed-scale ball. */
.pool-ball::before {
  content: ''; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: max(44px, 100%); aspect-ratio: 1; border-radius: 50%;
}
.pool-ball::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(ellipse at 29% 20%, #fff 0%, #ffffffb3 4%, #ffffff33 12%, transparent 26%),
    radial-gradient(circle at 35% 28%, transparent 40%, #0006 100%);
}
.pool-ball span {
  width: 44%; aspect-ratio: 1; border-radius: 50%; background: #fff8e8; color: #131313;
  display: grid; place-items: center; font: bold clamp(9px, 1vw, 12px)/1 Arial,sans-serif;
  box-shadow: inset -1px -2px 3px #82785a55; transform: translate(6%, 8%) rotate(-9deg);
  pointer-events: none;
}
.pool-ball.selected { outline: 3px solid #ffe49b; outline-offset: 3px; z-index: 5; cursor: grabbing; }
.pool-ball.pocketed { box-shadow: inset -3px -4px 6px #0009, inset 1px 1px 3px #fff6, 0 2px 3px 2px #000b; }
.pool-ball:focus-visible { outline: 3px solid white; outline-offset: 3px; }
.pool-table-status { margin: 6px 0; color: var(--muted); }
.inspection-frame:has(.pool-table-stage) > .view-label { display: none; }
.inspection-frame:has(.pool-table-stage) > .view-label.view-name-on { display: block; }
.view-label[hidden] { display: none; }
.inspection-frame:has(.pool-table-stage) > .arttag { top: 0; }
@media (max-width: 700px) and (orientation: portrait) {
  .pool-table-stage { padding-bottom: 0; }
}
@media (orientation: landscape) and (max-height: 560px) {
  .inspection-frame:has(.pool-table-stage) { --image-ratio: 2.5; }
  .pool-table-stage { padding-bottom: 0; }
  .pool-table-canvas { width: 60%; }
  .inspection-frame:has(.pool-table-stage) > .inspection-body:not(.custom-info-position) { left: 60%; right: 0; top: 0; bottom: 0; width: 40%; height: 100%; max-height: 100%; }
}

/* An incoming call remains visible with muted audio and reduced motion. */
.hotspot.phone-ringing { border: 2px solid #ffd978; border-radius: 12px; background: #ffd97818; box-shadow: 0 0 0 5px #ffd97833; animation: phone-ring-halo 1.8s ease-out infinite; }
@keyframes phone-ring-halo { 0%, 100% { box-shadow: 0 0 0 3px #ffd97866; } 65% { box-shadow: 0 0 0 16px #ffd97800; } }
@media (prefers-reduced-motion: reduce) { .hotspot.phone-ringing { animation: none; } }

.challenge-completion { color: var(--good); margin: 0 0 14px; font-weight: 600; }
.challenge-completion > :first-child { margin-top: 0; }
.device-travel-controls { position: absolute; z-index: 12; top: 12%; left: 8%; right: 8%; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.device-travel-controls .btn { min-height: 44px; background: #14211fee; color: #e9fff5; border-color: #8ac9b0; }

.btn.answer-wrong { color: #fff; background: #a32936; border-color: #ef6674; }

.locked-door-notice { position: absolute; z-index: 20; transform: translate(-50%, -50%); pointer-events: none; display: grid; place-items: center; width: 52px; height: 58px; border: 1px solid #ffda7880; border-radius: 14px; background: #211b12e8; color: #ffdb70; box-shadow: 0 3px 12px #0008; }
.locked-door-notice svg { width: 32px; height: 36px; overflow: visible; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; animation: door-lock-rattle .38s ease-in-out 2; }
.locked-door-notice circle { fill: currentColor; stroke: none; }
@keyframes door-lock-rattle { 0%, 100% { transform: rotate(0); } 20%, 60% { transform: translateX(-2px) rotate(-8deg); } 40%, 80% { transform: translateX(2px) rotate(8deg); } }
@media (prefers-reduced-motion: reduce) { .locked-door-notice svg { animation: none; } }

.mechanical-lock-stage { overflow: hidden; }
.mechanical-lock-surface { position: relative; width: 100%; }
.mechanical-pointer { position: absolute; pointer-events: none; filter: drop-shadow(2px 3px 2px #160c08a0); }
.mechanical-pointer svg, .mechanical-crank svg { display: block; width: 100%; height: 100%; overflow: visible; }
.mechanical-pointer-rotor { transform-origin: 200px 200px; transition: transform 180ms ease-out; }
.mechanical-crank-rotor { transform-origin: 150px 150px; transition: transform 180ms ease-out; }
.mechanical-crank, .mechanical-latch, .mechanical-reset { position: absolute; padding: 0; border: 0; background: transparent; cursor: grab; touch-action: none; }
.mechanical-crank { border-radius: 50%; filter: drop-shadow(3px 4px 3px #160c08a0); }
.mechanical-crank:active { cursor: grabbing; }
.mechanical-latch, .mechanical-reset { border-radius: 12%; cursor: pointer; }
.mechanical-reset { border-radius: 50%; }
.mechanical-lock-surface button:focus-visible { outline: 2px solid #ecc087; outline-offset: 3px; }
.mechanical-lock-surface button:disabled { opacity: 1; cursor: default; }
.mechanical-status { display: block; margin: .5em 0; color: var(--muted); }
.mechanical-checking .mechanical-latch { box-shadow: inset 0 0 12px #e7b77855; }
.mechanical-open .mechanical-latch { background: #e7b77812; box-shadow: inset 0 0 12px #e7b77844; }
@media (prefers-reduced-motion: reduce) { .mechanical-pointer-rotor, .mechanical-crank-rotor { transition: none; } }
.gear-rack-stage { width: min(100%, 900px); margin: auto; padding: 14px; box-sizing: border-box; background: linear-gradient(135deg,#272c2b,#101514); }
.gear-rack-console { padding: clamp(12px,2vw,24px); border: 4px ridge #77786b; border-radius: 12px; background: repeating-linear-gradient(0deg,#303736 0px,#303736 2px,#333a39 3px,#333a39 4px); box-shadow: inset 0 0 40px #0007,0 10px 30px #0008; }
.gear-plate-label { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; color: #f1d89e; letter-spacing: .08em; font-size: 13px; margin-bottom: 14px; }
.gear-plate-label span { color: #f1eadb; }
.gear-controls { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 12px 0; }
.gear-controls .btn { min-height: 44px; }
.gear-plane-label { display: block; color: #ebd4a7; text-align: center; font: bold 12px monospace; letter-spacing: .2em; }
.gear-board { position: relative; aspect-ratio: 420 / 180; margin: 8px 0; border-radius: 8px; background: radial-gradient(ellipse,#141b1a,#090e0d); border: 1px solid #67756d; box-shadow: inset 0 0 20px #000b; container-type: inline-size; }
.gear-board[data-plane="rear"] { background: radial-gradient(ellipse,#172532,#0a1018); }
.gear-mount { position: absolute; top: 48%; transform: translate(-50%,-50%); width: var(--gear-size); aspect-ratio: 1; min-width: 36px; min-height: 36px; display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: #f8e7bc; cursor: pointer; touch-action: manipulation; }
.gear-mount.fixed { pointer-events: none; }
.gear-mount svg { width: 100%; height: 100%; filter: drop-shadow(2px 3px 2px #000b); }
.gear-mount.selected { outline: 2px solid #b0f5cf; border-radius: 50%; }
.gear-mount:focus-visible, .gear-piece:focus-visible { outline: 3px solid #b0f5cf; outline-offset: 3px; }
.gear-brass { fill: #c5a55e; stroke: #f1d899; stroke-width: .8; }
.gear-steel { fill: #7b918d; stroke: #ccdcd4; stroke-width: .8; }
.gear-cutout { fill: #151b19; stroke: #806a3c; stroke-width: 1; }
.gear-hub { fill: #625337; stroke: #eddaaa; stroke-width: 1; }
.gear-timing-mark { stroke: #fff0be; stroke-width: 2; }
.gear-tooth-label { position: absolute; font: bold clamp(10px,1.5cqw,15px) monospace; color: #fff4d8; text-shadow: 0 1px 2px #000; pointer-events: none; }
.gear-empty { display: grid; place-items: center; width: 28px; height: 28px; border: 2px dashed #a3af9b; border-radius: 50%; color: #dce6db; font-size: 22px; }
.gear-shaft-label { position: absolute; bottom: 8%; transform: translateX(-50%); font: bold clamp(8px,2.4cqw,12px) monospace; color: #f2e5c7; }
.gear-dimension { position: absolute; top: 8%; transform: translateX(-50%); font: clamp(8px,2.4cqw,12px) monospace; color: #b5c7c1; white-space: nowrap; }
.gear-readout { display: block; text-align: center; color: #ffcc7b; background: #090f0d; border: 2px inset #535f58; padding: 10px; font: bold clamp(13px,2vw,20px) monospace; letter-spacing: .07em; }
.gear-readout.on-target { color: #a4f2bd; }
.gear-status { min-height: 3em; margin: 10px 0; font-size: 13px; color: #eee5cf; }
.gear-tray { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 10px; padding: 10px; border: 2px inset #6d7167; background: #171d1b; }
.gear-piece { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 6px 2px; background: #242c28; color: #f6e2ac; border: 1px solid #566351; border-radius: 5px; cursor: pointer; }
.gear-piece.selected { border-color: #b0f5cf; background: #33483a; box-shadow: 0 0 0 1px #b0f5cf; }
.gear-piece svg { width: 45px; height: 45px; }
.gear-piece small { font: 10px monospace; color: #d5dfd6; }
.gear-legend { color: #c4cfc5; font-size: 12px; margin-bottom: 0; }
.turning .gear-rotor { animation: gear-turn var(--gear-period) linear infinite; animation-direction: var(--gear-direction); }
@keyframes gear-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .turning .gear-rotor { animation: none; } }
.inspection-frame:has(.gear-rack-stage) { width: 100%; height: auto; max-height: none; padding-top: 40px; }
.inspection-frame:has(.gear-rack-stage) > .inspection-body:not(.custom-info-position) { position: relative; inset: auto; transform: none; width: min(900px,100%); max-height: none; margin: 10px auto 20px; }
.gear-mount svg { width: var(--gear-art-width); height: var(--gear-art-width); max-width: none; }
.gear-mount.fouled svg { filter: drop-shadow(0 0 4px #ff6a4d); }
.inspection-viewport:has(.gear-rack-stage) { display: block; overflow-y: auto; overscroll-behavior: contain; }

.tile-panel-surface { position: relative; width: 100%; }
.tile-panel-photo { display: block; width: 100%; }
.fireplace-tile, .tile-panel-control { position: absolute; padding: 0; margin: 0; border: 0; border-radius: 0; background-color: transparent; cursor: pointer; touch-action: manipulation; }
.fireplace-tile { background-repeat: no-repeat; background-blend-mode: normal; opacity: 0; transition: opacity .13s ease; }
.fireplace-tile.pressed { opacity: 1; }
.fireplace-tile:focus-visible, .tile-panel-control:focus-visible { opacity: 1; outline: 2px solid #e4d5a5; outline-offset: -3px; }
.fireplace-tile:focus-visible:not(.pressed) { background-image: none !important; }
.tile-panel-control { color: #fff; font: bold clamp(10px,1.7vw,22px) monospace; text-shadow: 0 1px 3px #000; }
.tile-panel-control:active { background: #0003; border-radius: 50%; }
.tile-panel-status { display: block; margin: 8px 0; }
.inspection-frame:has(.tile-panel-stage, .acoustic-stage, .receiver-stage) > .inspection-body:not(.custom-info-position) { position: relative; inset: auto; transform: none; width: 100%; max-height: none; margin: 0; }
.inspection-viewport:has(.tile-panel-stage, .acoustic-stage, .receiver-stage) { display: block; overflow-y: auto; overscroll-behavior: contain; }
.inspection-frame:has(.tile-panel-stage, .acoustic-stage, .receiver-stage) { width: min(100%,1100px); max-height: none; padding-top: 35px; }
.acoustic-rotor { position: absolute; inset: 0; border-radius: 50%; background-repeat: no-repeat; pointer-events: none; }

/* Keep the roster and its evidence side by side when there is room to read both. */
.team-page { display: grid; gap: 22px; }
.team-overview, .team-details { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: 22px; align-items: start; }
.team-overview { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.team-card { min-width: 0; padding: clamp(18px, 3vw, 30px); border: 1px solid #385444; border-radius: 12px; background: linear-gradient(135deg, #182c22, #102017); }
.team-card h2 { margin: 0 0 18px; font-size: 18px; color: #c8e4d2; overflow-wrap: anywhere; }
.team-card p { line-height: 1.6; }
.team-score { margin: 8px 0; color: #a7c8b4; }
.team-score strong { font-size: clamp(32px, 5vw, 52px); color: #d6f4df; font-variant-numeric: tabular-nums; }
.team-pin { display: block; font-size: 38px; letter-spacing: .3em; font-variant-numeric: tabular-nums; margin-bottom: 18px; color: #e3e5b4; }
.team-member, .team-solve { display: flex; justify-content: space-between; gap: 16px; padding: 16px 0; border-bottom: 1px solid #34473b; }
.team-member:last-child, .team-solve:last-child { border-bottom: 0; }
.team-member > div, .team-solve > div { min-width: 0; overflow-wrap: anywhere; }
.team-member > strong, .team-solve > strong { flex-shrink: 0; font-variant-numeric: tabular-nums; }
.team-member p, .team-solve p { margin: 5px 0; }
.team-card input, .team-card select { width: 100%; min-width: 0; margin-bottom: 14px; }
.team-join-note { max-width: 85ch; line-height: 1.7; color: #adc2b4; }
@media (max-width: 700px) {
  .team-overview, .team-details { grid-template-columns: minmax(0, 1fr); gap: 16px; }
}

.registration-page { width: min(1060px, 100%); margin: 0 auto; padding: clamp(20px, 5vw, 56px); box-sizing: border-box; }
.registration-page h1 { font-size: clamp(26px, 5vw, 40px); margin: 28px 0 12px; }
.registration-back { color: #b4dbc5; }
.registration-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; margin: 24px 0; }
.registration-page label { display: block; margin: 14px 0 8px; color: #bdd4c7; font-size: 13px; letter-spacing: .04em; }
.registration-choice { border: 1px solid #385444; padding: 12px 16px; border-radius: 8px; margin: 20px 0; }
.registration-choice label { display: flex; align-items: center; gap: 10px; min-height: 44px; margin: 0; cursor: pointer; }
.registration-choice input { width: auto; margin: 0; accent-color: #7fe0b0; }
.registration-submit { max-width: 680px; }
.registration-submit .btn { min-height: 48px; white-space: normal; }
.registration-page [hidden] { display: none !important; }
.registration-grid:has(#account-fields[hidden]) { grid-template-columns: minmax(0, 1fr); max-width: 680px; }
@media (max-width: 700px) { .registration-grid { grid-template-columns: minmax(0, 1fr); } }

.menu-toggle:disabled { opacity: 1; cursor: default; background: transparent; color: var(--ink); box-shadow: none; }

.challenge-tags { display: inline-flex; flex-wrap: wrap; gap: 5px; margin: 3px 0; vertical-align: middle; }
.challenge-tag { display: inline-block; padding: 2px 7px; border: 1px solid #82918b; border-radius: 999px; font-size: 11px; line-height: 1.4; letter-spacing: .02em; color: #e2eee8; background: #202a25; white-space: nowrap; }
.challenge-tag.difficulty-easy { border-color: #77b99a; }
.challenge-tag.difficulty-medium { border-color: #d5b76b; }
.challenge-tag.difficulty-hard { border-color: #d99090; }
.challenge-tag.mandatory-tag { color: #ffdf92; border-color: #caa358; background: #332d1d; }
.md-title > .challenge-tags { display: flex; }

/* The photograph supplies the physical control; the button supplies interaction. */
.patch-apply { position: absolute; top: 2%; left: 88%; width: 7.2%; height: 10%; z-index: 2; margin: 0; padding: 0; border: 0; border-radius: 8px; background: transparent; color: transparent; box-shadow: none; cursor: pointer; }
.patch-apply:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.patch-apply:disabled { cursor: default; }
.patch-stage.image-unavailable .patch-apply { position: static; width: auto; height: auto; min-height: 44px; grid-column: 1 / -1; padding: 10px; background: #151d17; border: 1px solid var(--edge); color: var(--ink); }

.challenge-heading-label { display: inline; }
.challenge-heading-label > .challenge-tags { margin: 0 0 0 8px; font-weight: normal; }

.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.challenge-record-links { margin: 10px 0; }
.challenge-record-links summary { cursor: pointer; color: var(--muted); }
.challenge-record-links[open] { display: grid; gap: 6px; }
.challenge-record-links button { text-align: left; }

