:root {
  /* the building's materials — identical to The Floor upstairs */
  --sky: #0b0e1a;
  --slab: #2a2d3a;
  --pillar: #23262f;
  --wall: #171a24;
  --wall-lit: #1f2333;
  --line: #3a3f52;
  --skin: #e8c39e;
  --glow-mon: #7ec8ff;
  --glow-neon: #ff5c8a;
  --glow-warm: #ffb454;
  --glow-green: #6dff9c;
  --paper: #e6e2d8;
  --metal: #8b93a7;
  --lamp: #fff0d0;

  --sign: "Helvetica Neue", Inter, "Segoe UI", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body { margin: 0; background: var(--sky); color: var(--paper); }

body {
  font: 14px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
  height: 100svh;
  overflow: hidden;      /* the room fills the window. the page never scrolls. */
  display: flex;
  flex-direction: column;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ── the stage ───────────────────────────────────────── */

.lobby { position: relative; flex: 1; min-height: 0; }

#stage {
  position: absolute;    /* a definite box — otherwise the SVG sizes itself from its
                            own 4:3 viewBox and grows the page */
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  background: var(--sky);
}

/* film grain, same trick as upstairs — keeps the flats from looking like flats */
#grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

#plaque {
  position: fixed;
  display: none;
  z-index: 3;
  pointer-events: none;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #12141f;
  color: var(--paper);
  font: 12px/1.4 ui-monospace, monospace;
  max-width: 260px;
}

/* ── the sign on the wall ────────────────────────────── */

.sign { cursor: help; }

.sign-main, .sign-ghost, .sign-shadow {
  font-family: var(--sign);
  font-size: 25px;
  font-weight: 700;
  letter-spacing: 4px;
  text-anchor: middle;
}

.sign-main { fill: var(--paper); }
.sign-shadow { fill: #05070d; opacity: 0.9; }        /* the cut into the wall */
.sign-ghost { opacity: 0; }
.sign-c { fill: var(--glow-mon); }
.sign-m { fill: var(--glow-neon); }

/* sized to clear the stairwell door — it used to run straight under it */
.sign-sub {
  font-family: var(--sign);
  font-size: 5px;
  letter-spacing: 1.4px;
  fill: var(--metal);
  text-anchor: middle;
}

#stage.glitching .sign-main { animation: sign-shudder 260ms steps(2, end) infinite; }
#stage.glitching .sign-c { animation: sign-split-a 260ms steps(2, end) infinite; }
#stage.glitching .sign-m { animation: sign-split-b 260ms steps(2, end) infinite; }

@keyframes sign-shudder {
  0%, 100% { transform: none; }
  35% { transform: translate(1px, -0.8px); }
  70% { transform: translate(-1px, 0.8px); }
}
@keyframes sign-split-a {
  0%   { opacity: .9; transform: translate(-2.4px, .6px); }
  50%  { opacity: .75; transform: translate(-4px, -.8px); }
  100% { opacity: .3;  transform: translate(-1.2px, 0); }
}
@keyframes sign-split-b {
  0%   { opacity: .9; transform: translate(2.4px, -.6px); }
  50%  { opacity: .75; transform: translate(4px, .8px); }
  100% { opacity: .3;  transform: translate(1.2px, 0); }
}

/* ── the other one ───────────────────────────────────── */
/* Everything warm in this room is driven off two vars, so the whole building
   changes hands at once instead of the sign flipping on its own. */

body.alt { --lamp: #ffc2d5; --glow-warm: #ff5c8a; }

#stage.glitching { animation: stage-jolt 200ms steps(2, end) infinite; }
@keyframes stage-jolt {
  0%, 100% { transform: none; }
  40% { transform: translate(-2px, 1px); }
  80% { transform: translate(2px, -1px); }
}

.static { transition: opacity 120ms; }
#stage.glitching .static { opacity: 1; }

.tear-a { animation: tear-a 300ms steps(3, end) infinite; }
.tear-b { animation: tear-b 420ms steps(3, end) infinite; }
@keyframes tear-a {
  0% { transform: translateY(0); }
  50% { transform: translateY(64px); }
  100% { transform: translateY(-40px); }
}
@keyframes tear-b {
  0% { transform: translateY(0); }
  50% { transform: translateY(-92px); }
  100% { transform: translateY(48px); }
}

/* the dead screen wakes up for the one who's actually awake */
.screen-alt { transition: opacity 160ms; }
body.alt .screen-alt { opacity: 1; animation: crt 320ms steps(2, end) infinite; }
@keyframes crt { 0%, 100% { opacity: 1; } 50% { opacity: .72; } }

/* the note gets crossed out */
.note-saxx, .note-alt { transition: opacity 160ms; }
body.alt .note-saxx { opacity: 0; }
body.alt .note-alt { opacity: 1; }

/* and the clock gives up entirely */
body.alt .hands {
  transform-box: view-box;
  transform-origin: 414px 120px;
  animation: hands-lose-it 900ms linear infinite;
}
@keyframes hands-lose-it { to { transform: rotate(360deg); } }

/* ── posters ─────────────────────────────────────────── */

.poster-line {
  font-family: var(--sign);
  font-weight: 700;
  letter-spacing: .5px;
  fill: var(--paper);
  text-anchor: middle;
}

.poster-foot {
  font-family: ui-monospace, monospace;
  letter-spacing: .5px;
  fill: var(--metal);
  text-anchor: middle;
  opacity: .8;
}

/* ── the elevator ────────────────────────────────────── */

#callplate { cursor: pointer; }
#speaker { cursor: pointer; }
#speaker:hover rect, #speaker:focus-visible rect { stroke: var(--glow-warm); }
#speaker-led { transition: fill 200ms, filter 200ms; }

.ind {
  font: 11px ui-monospace, monospace;
  letter-spacing: 1px;
  fill: var(--glow-warm);
  text-anchor: middle;
}

.arrow { opacity: 0.3; }
.arrow.on { opacity: 1; animation: arrow-blink 700ms steps(1, end) infinite; }
@keyframes arrow-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .35; } }

.callhint {
  font: 5px ui-monospace, monospace;
  letter-spacing: 1.4px;
  fill: var(--metal);
  text-anchor: middle;
  opacity: .7;
}

/* the button breathes so you know it's the way out of this page */
.callbtn { transition: fill 200ms, stroke 200ms, filter 200ms; }
.callbtn { animation: btn-idle 3.6s ease-in-out infinite; }
@keyframes btn-idle {
  0%, 100% { stroke: var(--metal); }
  50% { stroke: var(--glow-warm); }
}

#callplate:hover .callbtn,
#callplate:focus-visible .callbtn,
.callbtn.lit {
  fill: var(--glow-warm);
  stroke: #fff2d8;
  filter: drop-shadow(0 0 5px var(--glow-warm));
  animation: none;
}

.callbtn.lit { animation: btn-hot 1.1s ease-in-out infinite; }
@keyframes btn-hot {
  0%, 100% { filter: drop-shadow(0 0 4px var(--glow-warm)); }
  50% { filter: drop-shadow(0 0 11px var(--glow-warm)); }
}

.door { transition: transform 1000ms cubic-bezier(0.6, 0, 0.25, 1); }
.door-lines, .door-seam { transition: opacity 400ms; }

.doors.open .door-l { transform: translateX(-52px); }
.doors.open .door-r { transform: translateX(52px); }
.doors.open .door-lines,
.doors.open .door-seam { opacity: 0; }

.car-light, .car-fit, .spill { transition: opacity 900ms ease-out; }

/* the whole room brightens a touch as the doors part */
body.boarding #stage { transition: filter 900ms ease-out; filter: brightness(1.12); }

/* ── the room comes on ───────────────────────────────── */
/* A cold strip light doesn't strike clean — it gutters a couple of times first. */

.blackout { animation: strike 1500ms steps(1, end) forwards; }
@keyframes strike {
  0%   { opacity: 1; }
  14%  { opacity: .45; }
  18%  { opacity: .95; }
  30%  { opacity: .25; }
  36%  { opacity: .8; }
  52%  { opacity: .1; }
  58%  { opacity: .4; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .blackout { animation: none; opacity: 0; } }

/* ── Lili ────────────────────────────────────────────── */
/* She's curled up asleep. Press the button and she's awake and watching. */

.lili-asleep, .lili-alert { transition: opacity 260ms ease-out; }
body.called .lili-asleep { opacity: 0; }
body.called .lili-alert { opacity: 1; }
body.called .lili-alert { animation: startle 420ms ease-out; }
@keyframes startle {
  0% { transform: translateY(0); }
  35% { transform: translateY(-1.6px); }
  100% { transform: translateY(0); }
}

/* ── ambient life ────────────────────────────────────── */

.lamp-tube { animation: strip-flicker 9s steps(1, end) infinite; }
.lamp-cone { animation: cone-flicker 9s steps(1, end) infinite; }
@keyframes strip-flicker {
  0%, 61%, 100% { opacity: .9; }
  62%, 63% { opacity: .35; }
  64% { opacity: .85; }
  65%, 66% { opacity: .4; }
}
@keyframes cone-flicker {
  0%, 61%, 100% { opacity: 1; }
  62%, 66% { opacity: .55; }
}

.dead-screen { animation: none; }

.luna { animation: breathe 5.4s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
.lili { animation: breathe 6.6s ease-in-out infinite; animation-delay: -2s; transform-box: fill-box; transform-origin: 50% 100%; }
@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.035); }
}

/* ── outside ─────────────────────────────────────────── */

.drop { animation-name: fall; animation-timing-function: linear; animation-iteration-count: infinite; }
@keyframes fall {
  0% { transform: translateY(0); opacity: 0; }
  10% { opacity: .5; }
  90% { opacity: .5; }
  100% { transform: translateY(160px); opacity: 0; }
}

/* the lamp's reflection never quite settles */
.puddle { animation: ripple 4.2s ease-in-out infinite; }
@keyframes ripple {
  0%, 100% { opacity: .22; transform: scaleX(1); }
  50% { opacity: .3; transform: scaleX(1.6); }
}

/* a car goes past every so often. nobody in it is coming here. */
.headlight { animation: pass 14s cubic-bezier(0.4, 0, 0.7, 1) infinite; }
@keyframes pass {
  0%, 62% { transform: translateX(0); opacity: 0; }
  66% { opacity: .85; }
  74% { transform: translateX(84px); opacity: .85; }
  78%, 100% { transform: translateX(96px); opacity: 0; }
}

/* and its light crosses the lobby floor a beat later */
.sweep { animation: sweep 14s ease-in-out infinite; }
@keyframes sweep {
  0%, 64% { opacity: 0; }
  70% { opacity: .1; }
  76% { opacity: .04; }
  80%, 100% { opacity: 0; }
}

/* ── B1 ──────────────────────────────────────────────── */

.stairs { cursor: pointer; }

.exit {
  font: 5px var(--sign);
  font-weight: 700;
  letter-spacing: 1px;
  fill: var(--glow-green);
  text-anchor: middle;
  opacity: .85;
}

.stencil-b1 {
  font: 9px var(--sign);
  font-weight: 700;
  letter-spacing: 2px;
  fill: var(--paper);
  text-anchor: middle;
  opacity: .55;
}

.stencil-sub {
  font: 4px ui-monospace, monospace;
  letter-spacing: .4px;
  fill: var(--metal);
  text-anchor: middle;
  opacity: .7;
}

.stairs:hover .stencil-b1,
.stairs:focus-visible .stencil-b1 { opacity: .95; }
.stairs:hover .stencil-sub,
.stairs:focus-visible .stencil-sub { fill: var(--glow-green); opacity: 1; }

/* the stairwell light is on its last legs */
.stairlight { animation: dying 6.5s steps(1, end) infinite; }
@keyframes dying {
  0%, 70%, 100% { opacity: .13; }
  72%, 74% { opacity: .04; }
  76% { opacity: .18; }
  78% { opacity: .06; }
}

/* ── Luna ────────────────────────────────────────────── */


/* the brass catches the picture light every so often */
.shine { animation: shine 7s ease-in-out infinite; }
@keyframes shine {
  0%, 72%, 100% { opacity: 0; transform: translateX(0); }
  78% { opacity: .5; }
  92% { opacity: 0; transform: translateX(17px); }
}

.gag { fill: transparent; cursor: help; }

/* ── under the stage ─────────────────────────────────── */

.hint {
  margin: 0;
  padding: 14px 20px 0;
  text-align: center;
  font-size: 12px;
  color: #6b7290;
}

.hint a { color: var(--glow-mon); text-decoration: none; }
.hint a:hover, .hint a:focus-visible { text-decoration: underline; }

.foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  padding: 12px 20px 20px;
  font-size: 12px;
}

.foot a { color: #6b7290; text-decoration: none; }
.foot a:hover, .foot a:focus-visible { color: var(--glow-mon); }

:focus-visible { outline: 2px solid var(--glow-warm); outline-offset: 2px; }

/* Portrait: the room can't fill the window without slicing the sign off one wall
   and the desk off the other, so it sits as a whole picture, centred. */
/* Portrait: JS switches preserveAspectRatio to `meet` so the whole room shows,
   letterboxed. The stage still fills its box — the page still never scrolls. */

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; }
  .sign-ghost { display: none; }
}
