:root {
  --blue: #1B8FF2;
  --blue-l: #4DB6F7;
  --pink: #F11C6B;
  --ice: #cfe6ff;
  --line: rgba(77,182,247,.22);
  --void: #070b14;
  --f-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --f-type: 'Special Elite', 'Courier New', Courier, monospace;
  color-scheme: dark;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--void); color: var(--ice); font-family: var(--f-mono); font-size: 13px; }
button { font: inherit; color: inherit; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--blue-l); outline-offset: 2px; }

/* The view runs the full width of the window; the room name, the item bar and the panels below keep
   to a readable column. */
#game { padding: 18px 0 40px; }
#game > .bar, #game > .panels { max-width: 1240px; margin-inline: auto; padding-inline: 16px; box-sizing: border-box; }
/* The room name sits at the window's left edge, not the centered column's, so it lines up with the full-width stage. */
#game > .hud { padding-inline: 16px; }
.hud { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 8px 24px; padding-block: 4px 12px; }
.rname { font-family: var(--f-type); font-size: clamp(20px, 3.4vw, 28px); color: #eaf4ff; }
.stats { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; font-variant-numeric: tabular-nums; }
.stats b { color: #fff; font-weight: 600; }
.rcode { margin-left: 12px; font-size: 12px; color: var(--blue-l); opacity: .8; letter-spacing: .06em; }
.meter { display: inline-flex; align-items: center; gap: 8px; }
/* The HUD sits in the view's top right corner, inside the view, so it shows in fullscreen too, and
   above the black-out when you collapse (z-index over the collapse screen's 40). */
.hud-corner { position: absolute; top: 12px; right: 12px; z-index: 45; display: grid; justify-items: end; gap: 6px; padding: 10px 12px; background: rgba(7,11,20,.6); border: 1px solid rgba(77,182,247,.22); font-size: 12px; color: #dcebff; max-width: min(320px, calc(100% - 24px)); }
.hud-corner .meter i { width: 120px; height: 7px; }
.hud-corner .fx:empty { display: none; }
.hud-corner .copyright { font-size: 10px; opacity: .45; }
.keys-bar { position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 0; padding: 6px 58px; background: linear-gradient(to top, rgba(4,7,13,.85), rgba(4,7,13,0)); font-size: 11px; color: rgba(220,235,255,.75); z-index: 45; }
/* The bar spans the stage over the gear, so only its buttons take clicks and the gear under it still works. */
.keys-bar { pointer-events: none; }
.keys-bar button { pointer-events: auto; }
.keys-bar kbd, .inv-panel kbd { font: 600 10px "JetBrains Mono", monospace; padding: 1px 4px; border: 1px solid rgba(77,182,247,.4); margin-right: 3px; color: #eaf4ff; }
.keys-bar .linkish { font-size: 11px; }
/* Three groups of the keys that matter while walking, split by a thin rule; the rest are in Controls. */
.kgroup { display: flex; align-items: center; gap: 14px; padding: 0 14px; }
.kgroup + .kgroup { border-left: 1px solid rgba(77,182,247,.25); }
.keys-bar .linkish, .keys-bar .quest-key { color: inherit; text-decoration: none; }
.inv-panel { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(660px, calc(100% - 32px)); height: min(620px, calc(100% - 64px)); overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; padding: 18px 20px; background: rgba(7,11,20,.94); border: 1px solid rgba(77,182,247,.4); box-shadow: 0 18px 60px rgba(0,0,0,.6); color: #dcebff; font-size: 12px; z-index: 6; }
.inv-panel header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; }
.inv-panel h3 { margin: 0; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--blue-l); }
.inv-close { font-size: 12px; color: #eaf4ff; }
.inv-grid { list-style: none; margin: 0 0 12px; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.inv-grid li { position: relative; display: grid; justify-items: center; gap: 6px; padding: 12px 6px 8px; min-height: 92px; border: 1px solid rgba(77,182,247,.2); background: rgba(77,182,247,.04); text-align: center; }
.inv-grid li svg { width: 72px; height: 26px; }
.inv-grid li .key { position: absolute; top: 4px; left: 6px; font: 600 10px "JetBrains Mono", monospace; opacity: .6; }
.inv-grid li .name { font-size: 11px; line-height: 1.3; }
.inv-grid li.empty { opacity: .35; }
.inv-grid li.held { border-color: #4DB6F7; background: rgba(77,182,247,.16); }
.inv-grid li .inv-acts { display: flex; gap: 4px; }
.inv-grid li .inv-acts button { padding: 2px 8px; font-size: 10px; }
.inv-grid li .count { position: absolute; top: 4px; right: 6px; font: 600 10px "JetBrains Mono", monospace; color: #cfe6ff; }
.inv-pockets { list-style: none; margin: 0 0 12px; padding: 0; display: grid; gap: 4px; max-height: 30vh; overflow: auto; }
.inv-pockets li { display: grid; grid-template-columns: 52px 1fr repeat(3, auto); align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid rgba(77,182,247,.15); }
.inv-pockets li svg { width: 52px; height: 18px; }
.inv-pockets li .name { font-size: 11px; }
.inv-pockets li button { padding: 2px 8px; font-size: 10px; }
.inv-pockets li.none { display: block; opacity: .5; border: 0; }
.inv-grid li.held .key { opacity: 1; color: #4DB6F7; }
.inv-panel footer { display: flex; flex-wrap: wrap; gap: 6px 16px; justify-content: center; opacity: .8; font-size: 11px; }
@media (max-width: 420px) { .inv-grid { grid-template-columns: repeat(2, 1fr); } }
.meter i { display: block; width: 70px; height: 6px; border: 1px solid var(--line); }
.meter i b { display: block; height: 100%; background: var(--blue-l); transition: width .3s ease; }
.meter i b.health { background: #e5484d; }
.meter i b.health.low { animation: lowhp 1s steps(2) infinite; }
@keyframes lowhp { 50% { opacity: .35; } }
.meter i b.stamina { background: #4fd18b; transition: none; }
.fade.hurt { background: var(--pink); opacity: .35; transition: none; }
.stage.static > canvas:first-child { filter: blur(.6px) contrast(1.25) saturate(.35) sepia(.15); animation: vhsjitter .18s steps(2) infinite; }
@keyframes vhsjitter { 0% { transform: translateX(0); } 50% { transform: translateX(2px); } }
.vhs { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; image-rendering: pixelated; mix-blend-mode: screen; opacity: .55; }
.stage.static.heavy > canvas:first-child { filter: blur(1.1px) contrast(1.45) saturate(.15) sepia(.2); animation-duration: .1s; }
@keyframes vhsjitterheavy { 0% { transform: translateX(0); } 33% { transform: translateX(-4px); } 66% { transform: translateX(5px); } }
.stage.static.heavy > canvas:first-child { animation-name: vhsjitterheavy; animation-timing-function: steps(3); }
.stage.heavy .vhs { opacity: .85; }
.controls-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 4px 14px; margin-top: 10px; }
.controls-grid p { margin: 0; font-size: 11px; color: #dcebff; display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.controls-grid kbd { font: 600 10px "JetBrains Mono", monospace; padding: 1px 4px; border: 1px solid rgba(77,182,247,.4); color: #eaf4ff; }
/* A panel that opens on a click: its title is the whole closed panel, with a short summary beside it. */
/* The panels that open on a click share one full-width row, equal boxes side by side; opening one
   leaves the others closed and short. */
.folds { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; align-items: start; }
.panel.fold summary { display: flex; align-items: baseline; gap: 10px; cursor: pointer; list-style: none; }
.panel.fold summary::-webkit-details-marker { display: none; }
.panel.fold summary h2 { margin: 0; }
.panel.fold summary::after { content: "+"; margin-left: auto; color: var(--blue-l); font: 600 14px "JetBrains Mono", monospace; }
.panel.fold[open] summary::after { content: "-"; }
.fold-sum { font: 11px "JetBrains Mono", monospace; color: var(--blue-l); }
.panel.fold :is(#achMine, #online) { margin-top: 10px; }
.panel-note { margin: -4px 0 8px; font-size: 11px; opacity: .65; }
.period-tabs { margin: 0 0 10px; }
.period-tabs button { height: 26px; padding: 0 10px; font-size: 11px; color: inherit; }
.inv-tabs button { height: 26px; font-size: 11px; color: inherit; }
.shop .inv-tabs { margin-bottom: 10px; }
kbd { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px; border: 1px solid var(--line);
  border-bottom-width: 2px; background: rgba(27,143,242,.08); font: 600 11px var(--f-mono); color: #fff; }
.fx { display: inline-flex; gap: 8px; }
.fx span { padding: 2px 8px; border: 1px solid var(--line); }
.fx .runs { border-color: var(--pink); color: #ffb3cf; }
.fx .bad { border-color: var(--pink); color: #ffb3cf; }
/* The tester tag (app/marks.py): beside your name, and on testers in Online now. */
.tester-tag { font: 600 10px "JetBrains Mono", monospace; color: #ffcf5a; }
.online .tester { font-style: normal; font-size: 10px; color: #ffcf5a; margin-left: 6px; }
/* A deadline almost up: one soft pulse a second, a glow rather than motion when motion is reduced. */
.fx .urgent { animation: fx-urgent 1s ease-out; }
@keyframes fx-urgent { 0% { transform: scale(1.12); background: rgba(255,90,140,.45); } 100% { transform: scale(1); background: transparent; } }
@media (prefers-reduced-motion: reduce) { @keyframes fx-urgent { 0% { background: rgba(255,90,140,.45); } 100% { background: transparent; } } }
.hud-corner .fx { flex-wrap: wrap; justify-content: flex-end; font-size: 11px; }
.code-tag { background: rgba(77,182,247,.1); border: 1px solid rgba(77,182,247,.35); color: #cfe6ff; font: 500 11px "JetBrains Mono", monospace; letter-spacing: .06em; padding: 2px 6px; cursor: copy; }
.linkish { background: none; border: 0; padding: 0; cursor: pointer; color: var(--blue-l); text-decoration: underline dotted; text-underline-offset: 3px; }

.stage-wrap { position: relative; background: #000; }
.stage-wrap:fullscreen { display: grid; place-items: center; }
.stage-wrap:fullscreen .stage { width: 100vw; height: 100vh; }
/* As tall as the window allows under the room name, never a letterbox: the camera takes whatever shape
   the window has (game.js resizes on every change). */
.stage { position: relative; width: 100%; height: calc(100svh - 64px); min-height: 320px; overflow: hidden; outline: none;
  box-shadow: 0 0 0 1px var(--line), 0 30px 90px -30px rgba(27,143,242,.45); transition: transform .28s ease-in, filter .28s ease-in; }
.stage canvas { display: block; width: 100%; height: 100%; touch-action: none; }
/* The wall ad layer sits behind the canvas and shows only through the hole the room render leaves. */
.stage { isolation: isolate; }
.stage.nausea canvas { filter: brightness(.55) saturate(.6) blur(.6px) hue-rotate(-25deg); }
.stage.nausea2 canvas { filter: brightness(.45) saturate(.4) blur(1.6px) hue-rotate(-55deg) contrast(1.15); animation: queasy 4.6s ease-in-out infinite; }
@keyframes queasy { 0%, 100% { transform: scale(1.02) skewX(0deg); } 30% { transform: scale(1.05) skewX(1.6deg); } 70% { transform: scale(1.03) skewX(-1.2deg); } }
.stage.parched canvas { filter: saturate(.5) contrast(.9); }
.fade { position: absolute; inset: 0; background: #000; opacity: 0; pointer-events: none; transition: opacity .22s ease; }
.fade.on { opacity: 1; }
.cross { position: absolute; left: 50%; top: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: rgba(255,255,255,.85); box-shadow: 0 0 0 1px rgba(0,0,0,.6); pointer-events: none; }
.eat-cue { position: absolute; left: calc(50% + 14px); top: calc(50% + 6px); color: rgba(255,255,255,.8); pointer-events: none; filter: drop-shadow(0 0 1px rgba(0,0,0,.8)); }
.hint { position: absolute; left: 50%; top: calc(50% + 18px); transform: translateX(-50%); padding: 4px 10px; background: rgba(7,11,20,.8); border: 1px solid var(--line); font-size: 12px; pointer-events: none; white-space: nowrap; }
.look { position: absolute; left: 50%; top: calc(50% + 50px); transform: translateX(-50%); z-index: 7; padding: 6px 12px; background: rgba(7,11,20,.8); border: 1px solid var(--line); font-size: 12px; pointer-events: none; }
.tabs { display: flex; gap: 6px; }
.tabs button { height: 30px; padding: 0 12px; background: none; border: 1px solid var(--line); cursor: pointer; }
.tabs button[aria-selected="true"] { background: rgba(27,143,242,.2); border-color: var(--blue-l); color: #fff; }
#pad { display: block; width: 100%; aspect-ratio: 2 / 1; background: #e9eef4; cursor: crosshair; touch-action: none; }
#drawPane { display: grid; gap: 6px; }
.writer-actions { display: flex; justify-content: flex-end; gap: 8px; }
.stage.walk { transform: scale(1.22); filter: brightness(0); }
.stage.arrive { animation: arrive .6s steps(1); }
@keyframes arrive { 0% {filter:brightness(.15)} 25% {filter:brightness(1)} 35% {filter:brightness(.4)} 50% {filter:brightness(1)} }
.stage.shake { animation: shake .45s; }
@keyframes shake { 0%,100% {transform:translate(0,0)} 20% {transform:translate(-8px,3px) rotate(-1deg)} 50% {transform:translate(7px,-2px) rotate(1deg)} 80% {transform:translate(-3px,1px)} }
.stage.nausea svg { animation: wobble 3.2s ease-in-out infinite; filter: brightness(.55) saturate(.6) blur(.6px) hue-rotate(-25deg); }
@keyframes wobble { 0%,100% {transform:rotate(0) skewX(0) scale(1.04)} 25% {transform:rotate(1.6deg) skewX(2deg) scale(1.06)} 50% {transform:rotate(-1deg) skewX(-1.5deg) scale(1.03)} 75% {transform:rotate(-1.8deg) skewX(1deg) scale(1.07)} }
.stage.parched svg { filter: saturate(.5) contrast(.9); }
.flicker { animation: flick 4.3s infinite steps(1); }
@keyframes flick { 0%,40% {opacity:1} 41% {opacity:.2} 42% {opacity:1} 43% {opacity:.35} 45%,86% {opacity:1} 87% {opacity:.25} 88%,100% {opacity:1} }
.door, .switch, .find, .item, .socket { cursor: pointer; }
.prop { cursor: grab; }
.dragging, .dragging * { cursor: grabbing !important; }
.door .hov { opacity: 0; transition: opacity .2s; }
.door:hover .hov, .door:focus-visible .hov { opacity: .12; }
.stage svg [role=button]:focus-visible { outline: none; }
.door:focus-visible .frame { stroke: #fff; stroke-width: 3; }
.item:hover, .item:focus-visible, .prop:focus-visible, .prop:hover, .find:focus-visible, .switch:focus-visible, .socket:focus-visible { filter: drop-shadow(0 0 5px rgba(77,182,247,.9)); }
.stage[data-held="marker"] .backwall { cursor: crosshair; }
.stage[data-held] .floor { cursor: cell; }
.door.jiggle { animation: jiggle .35s; }
@keyframes jiggle { 0%,100% {transform:translateX(0)} 25% {transform:translateX(-5px)} 75% {transform:translateX(5px)} }
.pulse { animation: pulse 1.8s ease-in-out infinite; }
@keyframes pulse { 0%,100% {opacity:.5} 50% {opacity:1} }

.toast { position: absolute; left: 50%; bottom: 22%; transform: translateX(-50%); max-width: calc(100% - 32px); padding: 8px 14px;
  background: rgba(7,11,20,.9); border: 1px solid rgba(77,182,247,.4); font-family: var(--f-type); font-size: 15px; color: #eaf4ff; text-align: center; }
.gate { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(0,0,0,.62); padding: 16px; }
.gate form, .fridge { display: grid; gap: 10px; width: min(320px, 100%); padding: 22px; background: rgba(7,11,20,.95); border: 1px solid rgba(77,182,247,.35); }
/* The fridge, food shelves and every choice list sit in the middle of the view, like every other panel. */
.fridge { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(320px, calc(100% - 32px)); max-height: calc(100% - 32px); overflow-y: auto; overscroll-behavior: contain; box-sizing: border-box; }
.fridge ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.fridge li { display: flex; align-items: center; gap: 8px; }
.fridge li span { flex: 1; }
#choicesList button { width: 100%; text-align: left; }
#choicesList button.active { background: rgba(77,182,247,.22); border-color: #4DB6F7; color: #fff; }
#choicesList button.active::before { content: "> "; }
.gate h2, .fridge h2 { margin: 0; font-family: var(--f-type); font-weight: 400; font-size: 20px; color: #eaf4ff; }
.gate-err { margin: 0; color: #ffb3cf; }
.writer { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: grid; gap: 10px; width: min(420px, calc(100% - 32px)); padding: 14px; background: rgba(7,11,20,.95); border: 1px solid rgba(77,182,247,.5); }
.field { width: 100%; height: 38px; padding: 0 10px; background: #000; border: 1px solid rgba(77,182,247,.4); color: #fff; font-family: var(--f-mono); font-size: 14px; }
.act { height: 36px; padding: 0 14px; background: var(--blue); color: #fff; border: 0; font-family: var(--f-mono); font-weight: 600; cursor: pointer; }
.act:hover { background: #3aa3f5; }
.ghost { height: 32px; padding: 0 10px; background: none; border: 1px solid var(--line); cursor: pointer; font-family: var(--f-mono); font-size: 12px; }
.ghost:hover { border-color: var(--blue-l); }
.maplink { display: inline-flex; align-items: center; color: inherit; text-decoration: none; }

.bar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; padding-block: 12px 6px; }
.inv { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.inv .empty { opacity: .5; }
.slot { display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 12px 0 6px; border: 1px solid var(--line); background: none; cursor: pointer; font-size: 12px; }
.slot svg { width: 46px; height: 24px; }
.slot kbd { font: inherit; opacity: .5; }
.slot[aria-pressed="true"] { background: rgba(27,143,242,.2); border-color: var(--blue-l); color: #fff; }
.controls { display: flex; flex-wrap: wrap; gap: 8px; }
.bar { padding-block: 12px 18px; }
.lore .by { display: block; margin-top: 3px; font-family: var(--f-mono); font-size: 11px; color: var(--blue-l); opacity: .8; }
.panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }
.panel { min-width: 0; padding: 16px 18px 18px; border: 1px solid var(--line); background: rgba(27,143,242,.035); }
.panel h2 { margin: 0 0 10px; font-family: var(--f-type); font-weight: 400; font-size: 19px; color: #eaf4ff; }
.ad-panel { display: grid; justify-items: center; align-content: start; }
.ad-panel h2 { justify-self: start; }
.ad-box { display: block; width: 300px; max-width: 100%; height: auto; aspect-ratio: 300 / 250; }
/* A busy day finds many: the list scrolls inside its panel instead of stretching the row. */
.lore { list-style: none; margin: 0; padding: 0 6px 0 0; display: grid; gap: 10px; font-family: var(--f-type); font-size: 14px; line-height: 1.45; color: #dcebff;
  max-height: 300px; overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; overflow-wrap: anywhere; }
.board { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; font-variant-numeric: tabular-nums; }
.board li { display: grid; grid-template-columns: 1.6em 1fr auto auto; gap: 10px; padding: 5px 6px; }
.board li.you { background: rgba(27,143,242,.2); color: #fff; }
.board .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board .v { opacity: .75; }
.online { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr; gap: 2px; max-height: 240px; overflow: auto; font-family: var(--f-mono); font-size: 12px; }
/* One explorer a row, the whole name shown: a long one wraps rather than being cut. */
.online li { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; padding: 4px 6px; }
.online li .n { min-width: 0; overflow-wrap: anywhere; }
.online li .v { flex: none; opacity: .6; }
.online li.you { background: rgba(27,143,242,.2); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .flicker, .pulse, .stage.arrive, .stage.shake, .stage.nausea svg, .door.jiggle { animation: none; }
  .stage { transition: none; }
}

.restore { display: grid; gap: 6px; margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line); font-size: 12px; }
.restore-row { display: flex; gap: 6px; }
.restore-row .field { flex: 1; min-width: 0; }
.codecard { display: grid; gap: 10px; width: min(360px, 100%); padding: 22px; background: rgba(7,11,20,.95); border: 1px solid var(--blue-l); }
.codecard p { margin: 0; line-height: 1.5; }
.codecard code { font: 600 20px var(--f-mono); letter-spacing: .08em; color: #fff; padding: 10px; text-align: center; border: 1px dashed var(--blue-l); }
.fridge .price { color: #e7dab3; font-size: 12px; }
/* The store keeps to the left so the HUD corner, where the return code to paste is shown, stays clear.
   Header, code and tabs stay put; only the list scrolls. */
/* The store sits in the middle of the view, above the HUD, the objective and the quest tracker. */
/* One fixed size for the store and the inventory, its other tab: switching tabs or store sections never resizes it. */
.shop { left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 60; width: min(660px, calc(100% - 32px)); height: min(620px, calc(100% - 64px)); display: flex; flex-direction: column; gap: 12px; padding: 18px 20px; overflow: hidden; }
/* The header rows keep their height; only the list scrolls, inside the panel, at any screen size. */
.shop > :not(.store-main) { flex: none; }
.shop > .store-main { flex: 1 1 auto; min-height: 0; }
/* With the store open the quest tracker and the HUD corner step aside instead of peeking out around it. */
.stage-wrap:has(.shop:not([hidden])) :is(.track, .objective, .hud-corner) { visibility: hidden; }
.shop-head { display: flex; align-items: center; gap: 12px; }
/* Locked until the return code is pasted; open, the code is already filled in and its field stays out of the way. */
.shop.locked > :is(.shop-code, .shop-note, .store-tabs, .store-main), .shop:not(.locked) > :is(.shop-gate, .shop-code, .shop-note) { display: none; }
/* Centered across, in the upper part of the box. */
.shop.locked > .shop-gate { flex: 1 1 auto; display: grid; gap: 10px; align-content: start; justify-items: center; text-align: center; padding-top: 12%; font-size: 13px; }
.shop-gate-row { display: flex; gap: 8px; width: min(360px, 100%); }
.shop-gate-row .field { flex: 1; letter-spacing: .08em; text-align: center; }
.shop-where { max-width: 460px; margin: 0; font-size: 12px; line-height: 1.5; opacity: .8; }
.shop-head h2 { flex: 1; }
.shop-wallet { font: 600 13px var(--f-mono); color: #e7dab3; }
.shop-code { display: flex; align-items: center; gap: 10px; font: 11px var(--f-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--blue-l); }
.shop-code span { flex: none; }
.shop-code .field { height: 34px; letter-spacing: .08em; }
/* Only the note under the return code tucks up against it; notes inside the list keep their space. */
.shop > .shop-note { margin-top: -6px; font-size: 11px; opacity: .6; }
.store-tabs { flex-wrap: wrap; gap: 0; border-bottom: 1px solid var(--line); }
.store-tabs button { height: 34px; padding: 0 12px; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; font-size: 12px; opacity: .7; }
.store-tabs button:hover { opacity: 1; }
.store-tabs button[aria-selected="true"] { background: none; border-bottom-color: var(--blue-l); opacity: 1; }
.store-main { display: grid; grid-template-columns: 1fr; gap: 16px; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; }
.store-main:has(.store-preview:not([hidden])) { grid-template-columns: 190px minmax(0, 1fr); }
.store-body { display: grid; gap: 8px; align-content: start; min-width: 0; }
.store-body h3 { margin: 8px 0 0; font: 10px var(--f-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--blue-l); opacity: .85; }
.store-body h3:first-child { margin-top: 0; }
.store-body ul { gap: 0; }
.store-body li { min-height: 40px; padding: 4px 8px; border-bottom: 1px solid rgba(77,182,247,.12); }
.store-body li:hover { background: rgba(77,182,247,.06); }
.store-body li .price { min-width: 64px; text-align: right; }
.store-body li .ghost { min-width: 76px; }
.store-body small { display: block; font-size: 11px; opacity: .6; }
.store-preview { display: block; position: sticky; top: 0; width: 100%; height: 280px; background: radial-gradient(ellipse at 50% 85%, rgba(77,182,247,.14), transparent 70%); border: 1px solid var(--line); }
.store-preview[hidden] { display: none; }
@media (max-width: 620px) {
  .store-main:has(.store-preview:not([hidden])) { grid-template-columns: 1fr; }
  .store-preview { position: static; height: 220px; }
}
.store-preview:not([hidden]) { touch-action: none; cursor: grab; }
.paint-area { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-start; justify-content: center; }
.paint-area .paint-grid { flex: 1 1 200px; margin: 0; }
.paint-grid { display: block; width: 100%; max-width: 288px; aspect-ratio: 1; margin: 0 auto; image-rendering: pixelated; touch-action: none; cursor: crosshair; }
/* The map of the garment beside the grid: same areas, numbered, with a key and the area under the pointer. */
.paint-map { flex: 0 1 112px; display: grid; gap: 6px; font-size: 11px; }
.paint-map svg { width: 100%; max-width: 112px; aspect-ratio: 1; background: #24272b; border: 1px solid var(--line); }
.paint-map svg text { font-family: var(--f-mono); }
.paint-map g.on rect { fill-opacity: .55; }
.paint-map ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.paint-map li { display: flex; align-items: center; gap: 6px; min-height: 0; padding: 1px 4px; border: 0; opacity: .75; }
.paint-map li.on { opacity: 1; background: rgba(77,182,247,.12); }
.paint-map li i { width: 9px; height: 9px; flex: none; }
.paint-where { margin: 0; font: 600 11px var(--f-mono); color: var(--blue-l); min-height: 1.4em; }
.body-pick { display: flex; gap: 6px; }
.body-pick button[aria-pressed="true"] { border-color: var(--blue-l); color: #eaf4ff; background: rgba(77,182,247,.14); }
.paint-palette { display: flex; flex-wrap: wrap; gap: 4px; }
.paint-swatch { width: 26px; height: 26px; border: 1px solid var(--line); cursor: pointer; padding: 0; }
.paint-swatch[aria-pressed="true"] { outline: 2px solid #eaf4ff; outline-offset: 1px; }
.paint-swatch.erase { width: auto; padding: 0 8px; background: none; font-size: 11px; }
.paint-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch { width: 14px; height: 14px; flex: none; border: 1px solid var(--line); }
.store-body li.tryable { cursor: pointer; }
.store-body li.trying { background: rgba(77,182,247,.14); box-shadow: inset 2px 0 0 var(--blue-l); }
.shop-note { margin: 0; font-size: 12px; line-height: 1.5; opacity: .8; }
.panel h2.sub { margin-top: 16px; font-size: 15px; }
.compass { position: absolute; left: 50%; top: 14px; width: 0; height: 0; border-left: 10px solid transparent; border-right: 10px solid transparent;
  border-bottom: 26px solid #e5484d; transform-origin: 50% 70%; filter: drop-shadow(0 0 4px rgba(229,72,77,.8)); pointer-events: none; }

/* The hand-drawn map: graph paper over the view, inside it so it works in fullscreen. */
.sketch-panel { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 8; display: grid; gap: 10px; padding: 14px; width: min(760px, calc(100% - 24px)); max-height: calc(100% - 24px); background: rgba(7,11,20,.95); border: 1px solid rgba(77,182,247,.4); box-shadow: 0 18px 60px rgba(0,0,0,.6); color: #dcebff; font-size: 12px; }
.sketch-panel header { display: flex; justify-content: space-between; align-items: baseline; }
.sketch-panel h3 { margin: 0; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--blue-l); }
.sketch-panel canvas { width: 100%; max-height: calc(100vh - 170px); aspect-ratio: 1; object-fit: contain; cursor: crosshair; touch-action: none; background: #eef1ea; }
.sketch-tools { display: flex; flex-wrap: wrap; gap: 8px; }
.sketch-tools [aria-pressed="true"] { background: rgba(77,182,247,.22); border-color: #4DB6F7; color: #fff; }
.sketch-need { margin: 0; opacity: .8; }

/* A found note, read: a sheet of paper over the view. The mouse stays with the view; a click puts it away. */
.reader { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%) rotate(-1.2deg); z-index: 9; width: min(440px, calc(100% - 40px)); padding: 30px 32px 20px; background: #ece6d6; color: #2b2a26; box-shadow: 0 16px 50px rgba(0,0,0,.6); background-image: repeating-linear-gradient(transparent 0 27px, rgba(60,90,140,.18) 27px 28px); }
/* A note being read is the only thing on paper: the objective and tracker step aside under it. */
.stage-wrap:has(.reader:not([hidden])) :is(.track, .objective) { visibility: hidden; }
.reader-text { margin: 0 0 18px; font: 400 22px/28px 'Reenie Beanie', cursive; letter-spacing: .03em; white-space: pre-wrap; }
.reader-by { margin: 0 0 14px; font: 13px 'JetBrains Mono', monospace; opacity: .6; text-align: right; }
.reader-close { margin: 0; font: 11px 'JetBrains Mono', monospace; opacity: .55; text-align: center; }
.inv-notes-title { margin: 12px 0 6px; }
.inv-notes { margin: 0 0 10px; padding: 0; list-style: none; display: grid; gap: 4px; max-height: 120px; overflow: auto; }
.inv-notes li { cursor: pointer; padding: 4px 8px; border: 1px solid rgba(77,182,247,.18); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.inv-notes li:hover { border-color: #4DB6F7; }
/* Pause is how the mouse is let go: the same look as every other key in the bar, only in pink. */
.pause-key { background: none; border: 0; padding: 0; font: inherit; color: var(--pink); cursor: pointer; }
.pause-key kbd { border-color: var(--pink); color: var(--pink); }

/* A computer screen that has given up the whole floor plan: the map page, in a green-on-black frame. */
.terminal { position: absolute; inset: 6% 8%; z-index: 8; display: grid; grid-template-rows: auto 1fr; gap: 8px; padding: 12px; background: #020604; border: 2px solid #2f6b47; box-shadow: 0 0 40px rgba(60,255,140,.15) inset, 0 18px 60px rgba(0,0,0,.7); color: #8dffb6; font: 12px "JetBrains Mono", monospace; }
.terminal header { display: flex; justify-content: space-between; }
.terminal h3 { margin: 0; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; }
.terminal iframe { width: 100%; height: 100%; border: 0; filter: saturate(.4) hue-rotate(80deg) contrast(1.1); }
/* The HUD sits above the stage overlays, so it steps aside while the screen or a close look is up instead of covering it. */
.stage-wrap:has(#terminal:not([hidden]), .inspect:not([hidden]), .bk-settings:not([hidden])) :is(.hud-corner, .keys-bar, .compass, .cross, .eat-cue, .hint, .look, .toast) { display: none; }

/* The building's air: a vignette that closes in at the edges over a barely-there grain that holds
   still. A moving grain read as screen static. */
.grain { position: absolute; inset: 0; pointer-events: none; z-index: 4; mix-blend-mode: overlay; opacity: .06;
  background: radial-gradient(ellipse at center, transparent 45%, rgba(0,0,0,.55) 100%), var(--grain, none); }

/* Paused: the world blurs and dims behind the prompt; it comes back into focus on resume. */
.stage canvas:first-child { transition: filter .25s ease; }
.stage.paused > canvas:first-child { filter: blur(7px) brightness(.6) saturate(.7); }
/* The game page sits under the start screen; it must not scroll until the start screen is gone. */
body:has(.start) { overflow: hidden; }
/* The door in: the page opens on this, and the game starts only when the player chooses to enter. */
.start { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 24px; background:
  radial-gradient(ellipse at 50% 40%, rgba(77,182,247,.10), transparent 60%), #05080f; }
.start-card { max-width: 440px; display: grid; gap: 14px; text-align: center; color: #dcebff; }
.start-card h1 { margin: 12px 0 0; font: 400 clamp(34px, 7vw, 56px) 'Special Elite', 'Courier New', monospace; letter-spacing: .04em; color: #eaf4ff; }
.start-card p { margin: 0; line-height: 1.5; opacity: .85; }
.start-card .start-goal { color: #5dff9a; opacity: 1; }
.start-card .start-copy { font-size: 10px; opacity: .45; }
.start-logo { justify-self: center; width: 96px; height: 96px; }
.start-news { justify-self: center; min-height: 44px; padding: 0 12px; color: #5dff9a; font: 600 13px "JetBrains Mono", monospace; }
/* The start screen's list of what changed, from static/changelog.md (static/news.js). */
.news { width: min(480px, calc(100% - 32px)); max-height: min(70vh, calc(100% - 32px)); padding: 16px; overflow: auto;
  background: #0b1220; color: #dcebff; border: 1px solid #4DB6F7; }
.news::backdrop { background: rgba(0,0,0,.6); }
.news header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.news h2 { margin: 0; font: 400 24px 'Special Elite', 'Courier New', monospace; color: #eaf4ff; }
.news header .ghost { min-height: 44px; min-width: 64px; }
.news h3 { margin: 12px 0 4px; font: 600 12px "JetBrains Mono", monospace; color: #5dff9a; }
.news ul { margin: 0; padding-left: 18px; display: grid; gap: 6px; font-size: 14px; line-height: 1.45; }
.start-go { justify-self: center; margin-top: 8px; padding: 12px 22px; background: transparent; border: 1px solid #4DB6F7; color: #eaf4ff; font: 600 14px "JetBrains Mono", monospace; letter-spacing: .06em; cursor: pointer; }
.start-go:hover, .start-go:focus-visible { background: rgba(77,182,247,.14); outline: none; }
.start-small { font-size: 12px; opacity: .55; }
.entered .start-card { visibility: hidden; }

/* The build, faint in the corner: there for screenshots and bug reports, not in the way. */
.version { position: absolute; top: 8px; left: 10px; z-index: 6; pointer-events: none; font: 10px "JetBrains Mono", monospace; letter-spacing: .06em; color: #cfe6ff; }
#version { opacity: .3; }
/* Free mouse (game.js): the cursor turns the view, so it is hidden like a locked one. */
canvas.free-look { cursor: none; }
/* A newer build on the server: said once beside the version, with a reload that takes it. */
.update { margin-left: 8px; color: #ffd84a; }
.update[hidden] { display: none; }
.update-reload { pointer-events: auto; font: inherit; letter-spacing: inherit; color: #ffd84a; background: none; border: 0; padding: 0 2px; text-decoration: underline; cursor: pointer; }

/* The objective: a few words top center under the compass, with an arrow at the door that leads on.
   A new one shows large in the middle of the view first (.fresh, static/goal.js), then moves up. */
.objective { position: absolute; left: 50%; top: 42px; z-index: 4; transform: translate(-50%, 0); max-width: min(560px, calc(100% - 32px));
  transition: top .6s ease, transform .6s ease, font-size .6s ease, padding .6s ease; display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: rgba(7,11,20,.72); border: 1px solid rgba(255,207,90,.45); color: #ffe7a8; font: 600 13px "JetBrains Mono", monospace; letter-spacing: .02em; pointer-events: none; }
.objective.fresh { top: 36%; transform: translate(-50%, -50%); padding: 12px 20px; font-size: 18px; }
@media (prefers-reduced-motion: reduce) { .objective { transition: none; } }
.objective.done { border-color: rgba(93,255,154,.5); color: #b9ffd2; }
.obj-arrow { width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 14px solid #ffcf5a; transform-origin: 50% 60%; flex: none; }
.fade.white { background: #fffdf5; transition: opacity 1.2s ease; }

/* The ending: the run's numbers and today's board, over the white. */
.ending { position: absolute; inset: 0; z-index: 50; display: grid; place-items: center; background: rgba(250,248,240,.94); color: #10161f; }
.end-card { width: min(520px, calc(100% - 32px)); display: grid; gap: 12px; text-align: center; }
.end-card h2 { margin: 0; font: 400 48px "Special Elite", monospace; letter-spacing: .08em; }
.end-card h3 { margin: 6px 0 0; color: #10161f; font: 600 12px "JetBrains Mono", monospace; letter-spacing: .12em; text-transform: uppercase; opacity: .7; }
.end-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.end-stats div { display: grid; gap: 2px; padding: 10px 4px; border: 1px solid rgba(16,22,31,.2); }
.end-stats b { font: 600 22px "JetBrains Mono", monospace; }
.end-stats span { font-size: 11px; opacity: .7; }
.end-rank { margin: 0; font: 600 15px "JetBrains Mono", monospace; }
.end-board { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; max-height: 180px; overflow: auto; font: 13px "JetBrains Mono", monospace; }
.end-board li { display: grid; grid-template-columns: 3em 1fr 4em; text-align: left; padding: 2px 6px; }
.end-board li.me { background: rgba(255,207,90,.35); }
.end-board small { opacity: .6; font-size: 11px; }
.end-tomorrow { margin: 0; font-size: 14px; }
.end-actions { display: flex; gap: 10px; justify-content: center; }
.ending .ghost { color: #10161f; border-color: rgba(16,22,31,.4); }
@media (max-width: 560px) { .end-stats { grid-template-columns: repeat(2, 1fr); } }

/* ---- a narrow game view (a small window, a split screen) ----
   Sized by the view itself, not the window: the key strip keeps to one row of the keys that matter,
   and the HUD corner shrinks so it never covers half the room. */
.stage-wrap { container: stage / inline-size; }
@container stage (max-width: 760px) {
  .keys-bar { flex-wrap: nowrap; padding: 5px 10px; white-space: nowrap; }
  .kgroup { gap: 10px; padding: 0 8px; }
  .hud-corner { top: 8px; right: 8px; gap: 4px; padding: 6px 8px; font-size: 11px; max-width: min(240px, 46%); }
  .hud-corner .meter { gap: 6px; }
  .hud-corner .meter i { width: 72px; height: 6px; }
  .code-tag { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 10px; }
  .look { top: calc(50% + 34px); max-width: calc(100% - 24px); text-align: center; }
}
@container stage (max-width: 520px) {
  .keys-bar span:not(:first-of-type) { display: none; }
  .code-tag, .hud-corner .fx { display: none; }
  .hud-corner { max-width: 52%; }
}

/* ---- quests ----
   The objective and the tracker stack top left, kept narrower than the room left of the HUD corner. */
.track { position: absolute; left: 14px; top: 28px; z-index: 3; display: grid; gap: 4px; justify-items: start; pointer-events: none; max-width: min(360px, calc(100% - 370px)); }
.tracker { margin: 0; padding: 4px 8px; list-style: none; display: grid; gap: 1px; max-width: 100%; background: rgba(7,11,20,.6); border: 1px solid var(--line); font: 11px "JetBrains Mono", monospace; color: #cfe6ff; }
.tracker li { display: flex; justify-content: space-between; gap: 10px; padding: 1px 4px; white-space: nowrap; }
.tracker li span { overflow: hidden; text-overflow: ellipsis; }
.tracker li b { font-weight: 600; color: var(--blue-l); }
.tracker li.tick { animation: tr-tick 1s ease; }
.tracker li.done { color: #b9ffd2; animation: tr-done 3s ease forwards; }
.tracker li.done b { color: #5dff9a; }
@keyframes tr-tick { from { background: rgba(77,182,247,.4); } to { background: transparent; } }
@keyframes tr-done { from { background: rgba(93,255,154,.45); } to { background: rgba(93,255,154,.06); } }
@media (prefers-reduced-motion: reduce) { .tracker li.tick, .tracker li.done { animation: none; } }
.quest-key { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; }
.ql-open { margin-left: 8px; font-size: 11px; text-transform: none; letter-spacing: 0; }
.quest-log { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 47; width: min(480px, calc(100% - 32px)); max-height: calc(100% - 24px); overflow-y: auto; overscroll-behavior: contain;
  padding: 14px 18px; background: rgba(7,11,20,.95); border: 1px solid rgba(77,182,247,.4); box-shadow: 0 18px 60px rgba(0,0,0,.6); color: #dcebff; font-size: 12px; }
.quest-log header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.quest-log h3, .quest-log h4 { margin: 0; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--blue-l); }
.quest-log h4 { margin: 10px 0 6px; font-size: 10px; opacity: .8; }
.quest-log kbd { font: 600 10px "JetBrains Mono", monospace; padding: 1px 4px; border: 1px solid rgba(77,182,247,.4); margin-right: 3px; color: #eaf4ff; }
.quest-log ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.ql-goal li { padding-left: 18px; position: relative; color: rgba(220,235,255,.6); }
.ql-goal li::before { content: ""; position: absolute; left: 2px; top: 4px; width: 8px; height: 8px; border: 1px solid currentColor; }
.ql-goal li.now { color: #ffe7a8; }
.ql-goal li.done { color: #b9ffd2; text-decoration: line-through; text-decoration-color: rgba(185,255,210,.5); }
.ql-goal li.done::before { background: currentColor; }
.ql-list li { padding: 7px 9px; border: 1px solid var(--line); background: rgba(7,11,20,.5); }
.ql-list li.done { border-color: rgba(93,255,154,.5); }
.ql-head { display: flex; align-items: baseline; gap: 8px; }
.ql-head b { flex: 1; font: 400 14px "Special Elite", monospace; color: #eaf4ff; }
.ql-tier { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--blue-l); opacity: .8; }
.ql-n { font: 600 11px "JetBrains Mono", monospace; color: var(--blue-l); }
.ql-list li.done .ql-n { color: #5dff9a; }
.ql-list p { margin: 3px 0 5px; font-size: 11px; opacity: .75; }
.ql-bar { display: block; height: 4px; background: rgba(77,182,247,.15); }
.ql-bar b { display: block; height: 100%; background: var(--blue-l); }
.ql-list li.done .ql-bar b { background: #5dff9a; }
.ql-reward { display: block; margin-top: 4px; font-size: 10px; opacity: .7; }
.ql-reset { margin: 10px 0 0; font-size: 11px; opacity: .65; }
.ql-swap { float: right; height: auto; margin-top: -2px; padding: 1px 7px; color: #cfe6ff; font-size: 10px; text-transform: none; letter-spacing: 0; }
.ql-list li.ql-mini { padding: 4px 9px; }
.ql-mini .ql-head b { font-size: 12px; }
.ql-mini .ql-bar { margin-top: 3px; height: 3px; }
@container stage (max-width: 760px) {
  .track { top: 26px; left: 8px; max-width: calc(52% - 20px); }
}
@container stage (max-width: 520px) {
  .tracker { display: none; }
  .track { max-width: calc(46% - 16px); }
  .quest-log { padding: 10px 12px; width: calc(100% - 16px); max-height: calc(100% - 12px); }
}
