:root {
  color-scheme: dark;
  --brass-grad: linear-gradient(170deg, #7a5622 0%, #e8c77a 18%, #a87b34 38%, #f3dc9c 52%, #8a6428 70%, #c99a4e 88%, #6b4a1e 100%);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* rust.jpg: dark iron + rust, composited from ambientCG CC0 scans (Rust004/006/009) */
  --rivet: radial-gradient(circle at 40% 35%, #b9b3aa 0 .8px, #5b5650 1.6px, #1d1b19 2.8px, rgba(0, 0, 0, .45) 3.4px, transparent 4px);
  --engraved: 0 1px 0 rgba(255, 255, 255, .24), 0 -1px 0 rgba(0, 0, 0, .9), 0 0 1px #000;
  --steel: linear-gradient(170deg, #2b2a28 0%, #4a4743 16%, #22211f 38%, #3d3a36 54%, #1a1918 72%, #34312d 88%, #151413 100%);
  --wood: repeating-linear-gradient(91deg, rgba(0, 0, 0, .2) 0 1px, transparent 1px 6px, rgba(255, 170, 110, .05) 6px 8px, transparent 8px 15px),
    linear-gradient(180deg, #4d2513, #2c1309 60%, #1f0d06);
}

/* Nixie glow colours, set per state */
.st-green  { --glow: #3dff6e; --core: #e2ffe6; }
.st-orange { --glow: #ff8a14; --core: #fff0d6; }
.st-red    { --glow: #ff2a14; --core: #ffe0d8; }
.st-amber  { --glow: #ff6a10; --core: #ffe6c4; }

* { box-sizing: border-box; }

html { background: #0a0604; }

/* Fullscreen: everything fits the viewport, no scrolling */
body {
  margin: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  padding: 1.2vmin;
  color: #e9dcc0;
  font-family: "IM Fell English", Georgia, serif;
  background:
    radial-gradient(ellipse at 50% 30%, rgba(10, 6, 3, .4), rgba(6, 3, 2, .9) 80%),
    url("halle.jpg") center 30% / cover fixed,
    #0a0604;
}

/* film grain over everything */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: var(--grain);
  opacity: .2;
  mix-blend-mode: overlay;
}

/* pipes run over the board and frame, under the steam */
#pipes {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  pointer-events: none;
  overflow: visible;
}

#steam {
  position: fixed;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ---------- Frame & board ---------- */

.frame {
  position: relative;
  height: 100%;
  padding: max(10px, 1.1vmin);
  border-radius: 14px;
  background: var(--grain), url("rust.jpg") center / cover, var(--steel);
  background-blend-mode: normal, soft-light, normal;
  box-shadow:
    0 40px 90px rgba(0, 0, 0, .85),
    0 0 0 1px #000,
    inset 0 1px 0 rgba(255, 255, 255, .18),
    inset 0 -2px 3px rgba(0, 0, 0, .6);
}

/* rivets along all four edges */
.frame::before {
  content: "";
  position: absolute;
  inset: 2px;
  pointer-events: none;
  background:
    var(--rivet) 0 0 / 38px 8px repeat-x,
    var(--rivet) 0 100% / 38px 8px repeat-x,
    var(--rivet) 0 0 / 8px 38px repeat-y,
    var(--rivet) 100% 0 / 8px 38px repeat-y;
}

.board {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) minmax(0, 2.7fr);
  height: 100%;
  overflow: hidden;
  border-radius: 6px;
  background:
    radial-gradient(ellipse at 50% 40%, transparent 30%, rgba(0, 0, 0, .65)),
    var(--grain),
    url("rust.jpg") center / cover;
  box-shadow: inset 0 0 0 2px #050505, inset 0 0 70px rgba(0, 0, 0, .95);
}

/* Dark iron signs with neon letters that mostly burn steadily; now and
   then one stutters off (class .flicker, set from app.js), showing the
   letters cut into the metal underneath. */
.title, .plaque {
  --lit-color: color-mix(in srgb, var(--neon) 40%, #fff);
  --lit-glow: 0 0 .04em #fff, 0 0 .12em var(--neon), 0 0 .35em var(--neon), 0 0 .8em var(--neon), 0 0 1.8em color-mix(in srgb, var(--neon) 55%, transparent);
  position: relative;
  text-transform: uppercase;
  color: var(--lit-color);
  text-shadow: var(--lit-glow);
  background:
    var(--rivet) 9px 9px / 8px 8px no-repeat,
    var(--rivet) calc(100% - 9px) 9px / 8px 8px no-repeat,
    var(--rivet) 9px calc(100% - 9px) / 8px 8px no-repeat,
    var(--rivet) calc(100% - 9px) calc(100% - 9px) / 8px 8px no-repeat,
    linear-gradient(175deg, rgba(255, 255, 255, .07), transparent 40%, rgba(0, 0, 0, .35)),
    linear-gradient(rgba(22, 22, 22, .62), rgba(22, 22, 22, .62)),
    var(--grain),
    url("rust.jpg") var(--rust-at, 40% 30%) / 1400px,
    #141414;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), inset 0 0 1.2em rgba(0, 0, 0, .7), 0 8px 18px rgba(0, 0, 0, .85);
}
.title {
  --neon: #ff7a1a;
  justify-self: center;
  margin: 1.6vmin 0 0;
  padding: .26em 1.3em .2em;
  font: 900 clamp(22px, 4.6vmin, 60px) / 1.2 "Cinzel", serif;
  letter-spacing: .22em;
  border-radius: 2px;
}

/* own keyframe names: the glitching tubes already use "flicker" */
.flicker { animation: neon-drop 2.4s steps(1, end); }
@keyframes neon-drop {
  0%, 5%, 12%, 46%, 52%, 100% { color: var(--lit-color); text-shadow: var(--lit-glow); }
  /* off: the dark engraving shows */
  3%, 9%, 16%, 49% { color: #0d0d0d; text-shadow: var(--engraved); }
}
/* full outage: sputters, goes dark for a while, struggles back on */
.outage { animation: neon-out 6s steps(1, end); }
@keyframes neon-out {
  0%, 4%, 7%, 82%, 85.5%, 88%, 100% { color: var(--lit-color); text-shadow: var(--lit-glow); }
  2%, 5.5%, 9%, 84%, 87% { color: #0d0d0d; text-shadow: var(--engraved); }
}

/* ---------- Final event ---------- */

.finale {
  container-type: size;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .6vmin; /* not cqh: a container's own units resolve against its ancestor */
  border-bottom: 1px solid rgba(232, 199, 122, .2);
}
/* the event's name on a torn scrap of newspaper (shadow on the wrapper,
   since clip-path would cut it off) */
.paper {
  transform: rotate(-1.4deg);
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .8));
}
.finale-name {
  position: relative;
  z-index: 0;
  padding: .28em .9em .22em;
  font: 400 min(13cqh, 5cqw) / 1.1 "UnifrakturMaguntia", serif;
  color: #141210;
  background:
    radial-gradient(ellipse at 80% 20%, rgba(150, 110, 50, .18), transparent 50%),
    radial-gradient(ellipse at 10% 90%, rgba(130, 95, 45, .22), transparent 45%),
    var(--grain),
    linear-gradient(176deg, #e9e1cb, #d8cdb0);
  /* ragged, hand-torn edges */
  clip-path: polygon(0 6%, 4% 0, 11% 4%, 19% 1%, 27% 5%, 36% 0, 45% 4%, 53% 1%, 62% 5%, 70% 0, 79% 4%, 88% 1%, 95% 5%, 100% 2%,
    99% 24%, 100% 47%, 98% 70%, 100% 94%, 94% 100%, 86% 95%, 77% 100%, 68% 96%, 59% 100%, 50% 95%, 41% 99%, 32% 95%,
    23% 100%, 14% 96%, 6% 100%, 0 95%, 2% 72%, 0 50%, 1% 27%);
}
/* faint print showing through from the other side */
.finale-name::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: .08;
  background: repeating-linear-gradient(180deg, #000 0 1px, transparent 1px 5px);
}

/* ---------- Tracks: 1–3 left, 4–6 right ---------- */

#tracks {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(3, minmax(0, 1fr));
  grid-auto-flow: column;
}

.row {
  container-type: size;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.6vmin;
  border-top: 1px solid rgba(232, 199, 122, .14);
}
.row:nth-child(n + 4) { border-left: 1px solid rgba(232, 199, 122, .14); }

/* iron platform plaque; its neon burns in the portal's colour */
.plaque {
  --neon: var(--portal);
  padding: .26em 1.2em .2em;
  font: 900 min(17cqh, 6.4cqw) / 1.2 "Cinzel", serif;
  letter-spacing: .14em;
  border-radius: 2px;
}
/* darker, pitted face: the rust scan at a small scale so the pits read */
.title, .plaque {
  background:
    linear-gradient(175deg, rgba(255, 255, 255, .05), transparent 35%, rgba(0, 0, 0, .4)),
    linear-gradient(rgba(8, 8, 8, .55), rgba(8, 8, 8, .55)),
    url("rust.jpg") var(--rust-at, 60% 40%) / 520px,
    #0e0e0e;
  background-blend-mode: normal, normal, luminosity, normal;
  box-shadow: inset 0 0 1.4em rgba(0, 0, 0, .85), 0 8px 18px rgba(0, 0, 0, .85);
}
/* heavy cast frame: same scanned iron, bevel-lit, with corner rivets */
.title::before, .plaque::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: 9px;
  border-radius: inherit;
  pointer-events: none;
  background:
    var(--rivet) 3px 3px / 8px 8px no-repeat,
    var(--rivet) calc(100% - 3px) 3px / 8px 8px no-repeat,
    var(--rivet) 3px calc(100% - 3px) / 8px 8px no-repeat,
    var(--rivet) calc(100% - 3px) calc(100% - 3px) / 8px 8px no-repeat,
    linear-gradient(160deg, rgba(255, 255, 255, .14), transparent 30%, rgba(0, 0, 0, .55) 70%, rgba(255, 255, 255, .06)),
    linear-gradient(rgba(14, 12, 10, .45), rgba(14, 12, 10, .45)),
    url("rust.jpg") 20% 70% / 700px,
    #151311;
  box-shadow: 0 0 0 1px #000, inset 0 0 0 1px rgba(0, 0, 0, .8), inset 0 1px 0 rgba(255, 255, 255, .08);
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}

/* ---------- Nixie tubes ---------- */

.clock {
  --tw: min(5.5cqw, 22cqh);
  --th: calc(var(--tw) * 1.75);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: calc(var(--tw) * .1);
  padding: calc(var(--tw) * .22) calc(var(--tw) * .4) calc(var(--tw) * .55);
  border-radius: 7px;
  background: var(--grain), var(--wood);
  box-shadow:
    inset 0 1px 0 rgba(255, 190, 130, .18),
    inset 0 0 0 2px #140803,
    inset 0 0 calc(var(--tw) * .5) rgba(0, 0, 0, .7),
    0 3px 6px rgba(0, 0, 0, .8),
    0 0 calc(var(--tw) * 1.2) color-mix(in srgb, var(--glow) 30%, transparent),
    0 0 calc(var(--tw) * 3.5) color-mix(in srgb, var(--glow) 16%, transparent);
  animation: hum 3.7s ease-in-out infinite alternate;
}
.clock.big { --tw: min(5.8cqw, 30cqh); }

/* slow mains hum in the glow */
@keyframes hum {
  from { filter: brightness(1); }
  to { filter: brightness(1.15) saturate(1.1); }
}

.group { display: inline-flex; gap: inherit; }

.tube {
  position: relative;
  display: inline-block;
  width: var(--tw);
  height: var(--th);
  border-radius: 45% 45% 6% 6% / 22% 22% 3% 3%;
  border: 1px solid rgba(255, 240, 220, .16);
  background:
    linear-gradient(0deg, #0b0703 0, #2a1d0c 5%, #5a4222 7.5%, rgba(25, 16, 6, .7) 9%, transparent 15%),
    radial-gradient(ellipse at 50% 55%, color-mix(in srgb, var(--glow) 32%, transparent), transparent 72%),
    linear-gradient(90deg, rgba(255, 255, 255, .02), rgba(255, 255, 255, .12) 18%, rgba(255, 255, 255, 0) 30%, rgba(0, 0, 0, 0) 72%, rgba(255, 255, 255, .06) 86%, rgba(255, 255, 255, 0)),
    #0e0805;
  box-shadow: inset 0 0 calc(var(--tw) * .22) rgba(0, 0, 0, .9), inset 0 calc(var(--tw) * -.2) calc(var(--tw) * .2) rgba(0, 0, 0, .75);
}
/* round wooden socket; the tube's base sits in a dark brass ring as wide
   as the tube, centred on its bottom edge so only the front lip shows */
.tube::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -7%;
  right: -7%;
  bottom: calc(var(--tw) * -.3);
  height: calc(var(--tw) * .5);
  border-radius: 50% / 45%;
  background:
    radial-gradient(ellipse 50% 20% at 50% 40%, #120c05 0 86%, #7a5c30 88%, #4a3416 94%, #1d1308 98%, transparent 100%),
    linear-gradient(90deg, rgba(0, 0, 0, .6), rgba(255, 190, 130, .1) 30%, rgba(255, 190, 130, .04) 55%, rgba(0, 0, 0, .65)),
    var(--wood);
  box-shadow: 0 2px 3px rgba(0, 0, 0, .9);
}
/* hexagonal anode mesh in front of the cathodes + glass highlight */
.tube::after {
  content: "";
  position: absolute;
  inset: 6% 8% 8%;
  z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  background:
    linear-gradient(100deg, transparent 12%, rgba(255, 255, 255, .16) 18%, transparent 26%),
    repeating-linear-gradient(60deg, rgba(0, 0, 0, .34) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(-60deg, rgba(0, 0, 0, .34) 0 1px, transparent 1px 3px);
}

.cath {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding-top: 4%;
  font: 400 calc(var(--th) * .74) / 1 "Nixie One", monospace;
  color: rgba(150, 120, 95, .11);
}
.cath.on {
  z-index: 1;
  color: var(--core);
  text-shadow:
    0 0 1px var(--glow),
    0 0 calc(var(--tw) * .08) var(--glow),
    0 0 calc(var(--tw) * .25) var(--glow),
    0 0 calc(var(--tw) * .6) var(--glow),
    0 0 calc(var(--tw) * 1.2) color-mix(in srgb, var(--glow) 70%, transparent);
}

/* separators: neon dots in their own narrow tube */
.sep {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--th) * .2);
}
.point { justify-content: flex-end; padding-bottom: calc(var(--th) * .16); }
.point i:first-child { display: none; }
.sep i {
  position: relative;
  z-index: 1;
  width: calc(var(--tw) * .18);
  height: calc(var(--tw) * .18);
  border-radius: 50%;
  background: var(--core);
  box-shadow: 0 0 calc(var(--tw) * .12) var(--glow), 0 0 calc(var(--tw) * .35) var(--glow), 0 0 calc(var(--tw) * .7) color-mix(in srgb, var(--glow) 60%, transparent);
}

/* glitching clocks flicker and twitch */
.glitch .cath.on, .glitch .sep i { animation: flicker .16s steps(2) infinite; }
.clock.glitch { animation: twitch .5s steps(1) infinite; }
@keyframes flicker {
  0% { filter: brightness(1.35) saturate(1.2); }
  50% { filter: brightness(.7); }
}
@keyframes twitch {
  0%, 70% { transform: none; }
  72% { transform: translate(1px, -1px); }
  86% { transform: translate(-1px, 0) skewX(-1deg); }
}

/* ---------- Secret settings ---------- */

dialog {
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 0;
  border: 0;
  border-radius: 10px;
  color: #2b1906;
  background: var(--grain), linear-gradient(180deg, #efe2c2, #d9c69a);
  box-shadow: 0 0 0 6px #7a5622, 0 0 0 8px #e8c77a, 0 30px 80px #000;
}
dialog::backdrop { background: rgba(5, 3, 1, .75); }
form { padding: 20px; }
dialog h2 {
  margin: 0 0 12px;
  font: 400 34px "UnifrakturMaguntia", serif;
  text-align: center;
}
fieldset {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px 12px;
  margin: 0 0 12px;
  padding: 10px 12px 12px;
  border: 1px solid #8a6428;
  border-left: 6px solid var(--portal, #8a6428);
  border-radius: 6px;
}
legend { padding: 0 6px; font: 400 15px "IM Fell English SC", serif; letter-spacing: .15em; }
label { display: grid; gap: 2px; font-size: 14px; }
input {
  width: 100%;
  padding: 6px 8px;
  font: 15px "IM Fell English", Georgia, serif;
  color: #1d1105;
  background: #fbf5e4;
  border: 1px solid #8a6428;
  border-radius: 4px;
  color-scheme: light;
}
.pw { max-width: 280px; }
.msg { min-height: 1.3em; margin: 8px 0; font-style: italic; color: #8a1d0c; }
.buttons { display: flex; justify-content: flex-end; gap: 10px; }
button {
  padding: 8px 18px;
  font: 400 16px "IM Fell English SC", serif;
  letter-spacing: .1em;
  color: #2b1906;
  background: var(--brass-grad);
  border: 1px solid #4a3010;
  border-radius: 5px;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 244, 210, .6), 0 2px 4px rgba(0, 0, 0, .4);
}
button:active { transform: translateY(1px); }

/* ---------- Portrait phones: one column, scrolls ---------- */

@media (max-aspect-ratio: 4/5) {
  body { height: auto; overflow: auto; }
  .board { grid-template-rows: auto 34vw auto; }
  #tracks { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; }
  .row { height: 40vw; min-height: 140px; }
  .row:nth-child(n + 4) { border-left: 0; }
}
