/* Daily Color Puzzle — HUD theme.
   Layout rules are unchanged from the previous stylesheet; only the visual
   language moved: deep navy grounds, cyan instrumentation, hairline rules,
   monospaced readouts and corner brackets. */

:root {
  --page-bg: #030711;
  --game-bg: #060e1e;
  --panel-bg: #08152a;
  --topbar-bg: #071528;
  --tube-bg: #08182c;
  --tube-edge: #14456b;
  --slot-bg: #050f1d;

  --ink: #d6f2ff;
  --ink-dim: #5e8fb4;
  --accent: #22e0ff;
  --accent-deep: #2f6dff;
  --accent-ink: #001420;
  --good: #31ffb2;

  --accent-rgb: 34 224 255;
  --deep-rgb: 47 109 255;
  --good-rgb: 49 255 178;
  --danger-rgb: 255 45 60;
  --panel-rgb: 6 14 30;
  --bar-rgb: 7 21 40;
  --page-rgb: 3 7 17;

  --panel-alpha: 0.15;
  --bar-alpha: 0.42;
  --placeholder: #3d6a8c;
  --table-head: #06121f;

  /* canvas map */
  --map-land: 120 214 255;
  --map-grid: 34 224 255;
  --map-star: 190 232 255;
  --map-streak: 225 250 255;


  /* Derived from --accent-rgb, so each theme gets its own automatically. */
  --line: rgb(var(--accent-rgb) / 0.16);
  --line-soft: rgb(var(--accent-rgb) / 0.09);
  --glow: 0 0 12px rgb(var(--accent-rgb) / 0.35);

  --font-ui: "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "Roboto Mono", "DejaVu Sans Mono", monospace;

  --c0:  #ff2d3c; /* red */
  --c1:  #ffa62b; /* orange */
  --c2:  #f2ee4a; /* yellow */
  --c3:  #31ff5a; /* green */
  --c4:  #22e6f5; /* cyan */
  --c5:  #3d6bff; /* blue */
  --c6:  #7a3ff5; /* violet */
  --c7:  #ff2be0; /* magenta */
  --c8:  #a3199f; /* purple */
  --c9:  #e6ecf5; /* white */

  /* Label ink, picked per color so the colorblind tags stay legible. */
  --t0: #fff; --t1: #000; --t2: #000; --t3: #000; --t4: #000;
  --t5: #fff; --t6: #fff; --t7: #000; --t8: #fff; --t9: #000;
}

/* The viewer's system setting decides until they pick one explicitly. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
  --page-bg: #e9f1f8;
  --game-bg: #f5fafd;
  --panel-bg: #ffffff;
  --topbar-bg: #e6eff8;
  --tube-bg: #ffffff;
  --tube-edge: #8fb8d4;
  --slot-bg: #dfeaf4;

  --ink: #0a2436;
  --ink-dim: #3d5c70;
  --accent: #075b7c;
  --accent-deep: #2550b8;
  --accent-ink: #ffffff;
  --good: #076844;

  --accent-rgb: 7 91 124;
  --deep-rgb: 37 80 184;
  --good-rgb: 7 104 68;
  --danger-rgb: 190 30 45;
  --panel-rgb: 255 255 255;
  --bar-rgb: 219 233 245;
  --page-rgb: 233 241 248;

  --panel-alpha: 0.94;
  --bar-alpha: 0.97;
  --placeholder: #7d97a8;
  --table-head: #dce9f4;

  /* canvas map */
  --map-land: 18 92 138;
  --map-grid: 7 91 124;
  --map-star: 90 140 175;
  --map-streak: 20 90 130;
  }
}

:root[data-theme="light"] {
  --page-bg: #e9f1f8;
  --game-bg: #f5fafd;
  --panel-bg: #ffffff;
  --topbar-bg: #e6eff8;
  --tube-bg: #ffffff;
  --tube-edge: #8fb8d4;
  --slot-bg: #dfeaf4;

  --ink: #0a2436;
  --ink-dim: #3d5c70;
  --accent: #075b7c;
  --accent-deep: #2550b8;
  --accent-ink: #ffffff;
  --good: #076844;

  --accent-rgb: 7 91 124;
  --deep-rgb: 37 80 184;
  --good-rgb: 7 104 68;
  --danger-rgb: 190 30 45;
  --panel-rgb: 255 255 255;
  --bar-rgb: 219 233 245;
  --page-rgb: 233 241 248;

  --panel-alpha: 0.94;
  --bar-alpha: 0.97;
  --placeholder: #7d97a8;
  --table-head: #dce9f4;

  /* canvas map */
  --map-land: 18 92 138;
  --map-grid: 7 91 124;
  --map-star: 90 140 175;
  --map-streak: 20 90 130;
}

:root[data-theme="dark"] {
  --page-bg: #030711;
  --game-bg: #060e1e;
  --panel-bg: #08152a;
  --topbar-bg: #071528;
  --tube-bg: #08182c;
  --tube-edge: #14456b;
  --slot-bg: #050f1d;

  --ink: #d6f2ff;
  --ink-dim: #5e8fb4;
  --accent: #22e0ff;
  --accent-deep: #2f6dff;
  --accent-ink: #001420;
  --good: #31ffb2;

  --accent-rgb: 34 224 255;
  --deep-rgb: 47 109 255;
  --good-rgb: 49 255 178;
  --danger-rgb: 255 45 60;
  --panel-rgb: 6 14 30;
  --bar-rgb: 7 21 40;
  --page-rgb: 3 7 17;

  --panel-alpha: 0.15;
  --bar-alpha: 0.42;
  --placeholder: #3d6a8c;
  --table-head: #06121f;

  /* canvas map */
  --map-land: 120 214 255;
  --map-grid: 34 224 255;
  --map-star: 190 232 255;
  --map-streak: 225 250 255;
}


* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 18px 14px 28px;
  background-color: var(--page-bg);
  /* Instrument grid, faint, plus a cool corner wash. */
  background-image:
    radial-gradient(90% 70% at 12% 0%, rgb(var(--deep-rgb) / 0.16), transparent 60%),
    radial-gradient(80% 60% at 100% 100%, rgb(var(--accent-rgb) / 0.10), transparent 60%);
  color: var(--ink);
  font: 16px/1.5 var(--font-ui);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  min-height: 100vh;
}

h1 {
  /* Sits on top of the body's 12px gap, so the title gets room to breathe
     without pushing the panels off a viewport-height layout. */
  margin: 12px 0 14px;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
  text-align: center;
  font-family: var(--font-mono);
  font-size: clamp(20px, 4.4vw, 34px);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  animation: title-in 0.7s ease both;
}
.title-text {
  animation: title-glow 3.4s ease-in-out infinite;
}
h1 .date {
  font-weight: 400;
  font-size: 0.52em;
  color: var(--accent);
  letter-spacing: 0.12em;
  text-shadow: 0 0 14px rgb(var(--accent-rgb) / 0.5);
}

@keyframes title-glow {
  0%, 100% {
    text-shadow: 0 0 14px rgb(var(--accent-rgb) / 0.4), 0 0 44px rgb(var(--accent-rgb) / 0.12);
  }
  50% {
    text-shadow: 0 0 22px rgb(var(--accent-rgb) / 0.85), 0 0 66px rgb(var(--accent-rgb) / 0.35);
  }
}
@keyframes title-in {
  from { opacity: 0; transform: translateY(-10px); letter-spacing: 0.4em; }
  to   { opacity: 1; transform: none; letter-spacing: 0.16em; }
}

/* Reticle mark, built from the same dial vocabulary as the rank gauge. */
.logo {
  width: 1.5em;
  height: 1.5em;
  flex: 0 0 auto;
  overflow: visible;
}
.logo-ticks {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-dasharray: 0.8 5;
  opacity: 0.85;
  transform-origin: 50% 50%;
  animation: spin-cw 18s linear infinite;
}
.logo-sweep {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 30 86;
  opacity: 0.9;
  transform-origin: 50% 50%;
  animation: spin-ccw 7s linear infinite;
  filter: drop-shadow(0 0 4px rgb(var(--accent-rgb) / 0.8));
}
.logo-hex {
  fill: rgb(var(--accent-rgb) / 0.07);
  stroke: var(--accent);
  stroke-width: 1.6;
  stroke-linejoin: round;
}
.logo-bar { filter: drop-shadow(0 0 3px currentColor); }
.logo-bar.b1 { fill: #31ff5a; color: #31ff5a; }
.logo-bar.b2 { fill: #f2ee4a; color: #f2ee4a; }
.logo-bar.b3 { fill: #ff2be0; color: #ff2be0; }

/* Stacked by default; the two-column desktop layout is opted into below. */
.layout {
  width: min(760px, 100%);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* Stacked: the puzzle leads, the instrumentation follows. */
.game { order: 1; }
.hud-rank { order: 2; }
.hud-zone { order: 3; }
.leaderboard { order: 4; }
.hud-rank .gauge { min-height: 150px; }

/* ---------- world map ----------
   A dotted equirectangular map drawn on canvas from Natural Earth coastlines.
   It fills the puzzle panel body and never takes a pointer event. */

.worldmap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.75;
}

/* An absolutely positioned canvas paints above its static siblings, so the
   panel's own contents are lifted over it explicitly. */
.game > .topbar,
.game > .board,
.game > .controls { position: relative; z-index: 1; }

/* ---------- theme toggle ----------
   Pinned opposite the countdown so the two corners balance, and out of the
   game controls where it competed with the play buttons. */



/* ---------- countdown ---------- */

.countdown {
  align-self: stretch;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.cd-time {
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.45);
}
.cd-time b { color: var(--ink-dim); font-weight: 400; margin: 0 1px 0 0; }
.cd-tz {
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  padding: 1px 4px;
}

/* ---------- panel shell ---------- */

/* Fully clear: any tint or blur here is laid directly over the globe, which
   is the one thing this panel is meant to reveal. The top and bottom bars and
   the tubes carry their own backgrounds, so nothing loses legibility. */
.game {
  background: transparent !important;
  backdrop-filter: none !important;
}

.game,
.leaderboard,
.hud {
  position: relative;
  width: 100%;
  background:
    linear-gradient(180deg, rgb(var(--accent-rgb) / 0.05), transparent 120px),
    rgb(var(--panel-rgb) / var(--panel-alpha));
  backdrop-filter: blur(2px);
  border: 1px solid var(--line);
  border-radius: 2px;
  overflow: hidden;
  box-shadow:
    inset 0 0 40px rgb(var(--accent-rgb) / 0.05),
    0 0 0 1px rgb(var(--page-rgb) / 0.9),
    0 14px 40px rgba(0, 0, 0, 0.6);
}

/* Corner brackets, the HUD tell. */
.game::before, .game::after,
.leaderboard::before, .leaderboard::after,
.hud::before, .hud::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  pointer-events: none;
  z-index: 4;
  border: 0 solid var(--accent);
}
.game::before, .leaderboard::before, .hud::before {
  top: -1px; left: -1px;
  border-top-width: 2px;
  border-left-width: 2px;
}
.game::after, .leaderboard::after, .hud::after {
  bottom: -1px; right: -1px;
  border-bottom-width: 2px;
  border-right-width: 2px;
}

/* ---------- chamfered left-column panels ----------
   The reference cuts the top-left corner of its left-hand blocks and fills
   the notch with diagonal hatching. clip-path removes the border along the
   cut, so the angled edge is redrawn as a rotated hairline. */

.hud-rank, .game {
  --chamfer: 34px;
  clip-path: polygon(
    var(--chamfer) 0, 100% 0, 100% 100%, 0 100%, 0 var(--chamfer)
  );
}

/* The top-left bracket would sit in the removed corner, so it becomes the
   angled edge itself. */
.hud-rank::before, .game::before {
  content: "";
  position: absolute;
  top: calc(var(--chamfer) / 2);
  left: calc(var(--chamfer) / 2 - (var(--chamfer) * 1.4142) / 2);
  width: calc(var(--chamfer) * 1.4142);
  height: 0;
  border: 0;
  border-top: 1px solid var(--accent);
  transform: rotate(-45deg);
  transform-origin: 50% 50%;
  box-shadow: 0 0 8px rgb(var(--accent-rgb) / 0.5);
  z-index: 4;
}

.hud-hatch {
  position: absolute;
  top: 0;
  left: var(--chamfer);
  width: 58px;
  height: 30px;
  background: repeating-linear-gradient(
    -45deg,
    rgb(var(--accent-rgb) / 0.42) 0 2px,
    transparent 2px 7px
  );
  clip-path: polygon(0 0, 100% 0, calc(100% - 14px) 100%, 0 100%);
  pointer-events: none;
  z-index: 3;
}

/* A short instrument rail down the cut edge, as on the reference dial. */
.hud-rail {
  position: absolute;
  left: 8px;
  top: calc(var(--chamfer) + 14px);
  width: 4px;
  height: 54px;
  background: repeating-linear-gradient(
    180deg,
    var(--accent) 0 4px,
    transparent 4px 10px
  );
  opacity: 0.5;
  pointer-events: none;
  z-index: 3;
}

.hud-rank .hud-head { padding-left: calc(var(--chamfer) + 66px); gap: 8px; }
.hud-rank .hud-head .btn-sm { flex: 0 0 auto; padding: 5px 10px; font-size: 10px; }
.hud-rank .hud-tag { overflow: hidden; text-overflow: ellipsis; }
.game .topbar { padding-left: calc(var(--chamfer) + 66px); }

/* ---------- HUD panel chrome ---------- */

.hud { display: flex; flex-direction: column; min-height: 0; }

.hud-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 14px;
  background: rgb(var(--bar-rgb) / var(--bar-alpha));
  border-bottom: 1px solid var(--line);
}
.hud-head h2 {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.4);
}
.hud-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  white-space: nowrap;
}

/* ---------- rank gauge ---------- */

.rank-row {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: 8px;
  /* Extra left padding so the label clears the decorative rail. */
  padding: 6px 14px 8px 26px;
}
.rank-row .rank-stat { align-self: center; }
.rank-stat { margin: 0; min-width: 0; }
.rank-stat:last-child { text-align: right; }
.rank-stat dt {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  white-space: nowrap;
}
.rank-stat dd {
  margin: 2px 0 0;
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 14px rgb(var(--accent-rgb) / 0.35);
}

.gauge {
  position: relative;
  flex: 1 1 auto;
  display: grid;
  place-items: center;
  padding: 10px;
  min-height: 0;
}
.gauge-svg {
  width: min(100%, 190px);
  height: auto;
  max-height: 100%;
  display: block;
  overflow: visible;
}
.g-ticks {
  fill: none;
  stroke: rgb(var(--accent-rgb) / 0.4);
  stroke-width: 5;
  stroke-dasharray: 1 7;
  transform-origin: 50% 50%;
  animation: spin-cw 26s linear infinite;
}
.g-track { fill: none; stroke: rgb(var(--accent-rgb) / 0.14); stroke-width: 8; }
.g-fill {
  fill: none;
  stroke: var(--accent);
  stroke-width: 8;
  stroke-linecap: butt;
  stroke-dasharray: 0 999;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  transition: stroke-dasharray 0.5s ease;
  filter: drop-shadow(0 0 6px rgb(var(--accent-rgb) / 0.8));
}
/* Dashed, so the counter-rotation is actually visible — a plain ring would
   look static however fast it turned. */
.g-inner {
  fill: rgb(var(--accent-rgb) / 0.05);
  stroke: rgb(var(--accent-rgb) / 0.3);
  stroke-width: 2;
  stroke-dasharray: 18 12;
  transform-origin: 50% 50%;
  animation: spin-ccw 34s linear infinite;
}

@keyframes spin-cw  { from { transform: rotate(0deg); }   to { transform: rotate(360deg); } }
@keyframes spin-ccw { from { transform: rotate(0deg); }   to { transform: rotate(-360deg); } }

.gauge-center {
  position: absolute;
  inset: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  pointer-events: none;
  text-align: center;
}
.gauge-center b {
  font-family: var(--font-mono);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 18px rgb(var(--accent-rgb) / 0.6);
}
.gauge-center span {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.hud-readout {
  display: flex;
  margin: 0;
  border-top: 1px solid var(--line-soft);
}
.hud-readout div {
  flex: 1 1 0;
  min-width: 0;
  padding: 8px 6px;
  text-align: center;
  border-left: 1px solid var(--line-soft);
}
.hud-readout div:first-child { border-left: 0; }
.hud-readout dt {
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.hud-readout dd {
  margin: 2px 0 0;
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---------- top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 16px;
  background: rgb(var(--bar-rgb) / var(--bar-alpha));
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.brand {
  font-weight: 700;
  font-size: 12px;
  color: var(--accent);
  padding-left: 14px;
  position: relative;
}
.brand::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -3px;
  background: var(--accent);
  box-shadow: var(--glow);
}
.stat { color: var(--ink-dim); font-weight: 500; }
.stat b {
  color: var(--ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 10px rgb(var(--accent-rgb) / 0.4);
}
.goal {
  margin-left: auto;
  padding: 5px 12px;
  border: 1px solid var(--accent);
  background: rgb(var(--accent-rgb) / 0.12);
  color: var(--accent);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.1em;
  white-space: nowrap;
  box-shadow: inset 0 0 14px rgb(var(--accent-rgb) / 0.16);
}

/* ---------- board ---------- */

.board {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  padding: 18px clamp(14px, 4vw, 40px);
  justify-items: center;
  background: transparent;
}

.tube {
  --lift: 0px;
  position: relative;
  width: 100%;
  max-width: 104px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 5px;
  padding: 7px;
  border: 1px solid var(--tube-edge);
  border-radius: 2px;
  background: linear-gradient(180deg, rgb(var(--accent-rgb) / 0.06), transparent 60%), rgba(8, 24, 44, 0.9);
  cursor: pointer;
  transition: transform 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
  font: inherit;
  color: inherit;
}
.tube:hover:not(:disabled) {
  border-color: rgb(var(--accent-rgb) / 0.6);
  box-shadow: 0 0 14px rgb(var(--accent-rgb) / 0.16);
}
.tube:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.tube.selected {
  border-color: var(--accent);
  box-shadow:
    inset 0 0 18px rgb(var(--accent-rgb) / 0.18),
    0 0 0 1px var(--accent),
    0 0 22px rgb(var(--accent-rgb) / 0.4);
  transform: translateY(-4px);
}
/* A finished tube keeps a steady glow in its own colour, and flashes a ring
   outward at the moment it completes. --done-c is set per tube from JS. */
.tube.done {
  border-color: color-mix(in srgb, var(--done-c) 65%, transparent);
  box-shadow:
    inset 0 0 20px color-mix(in srgb, var(--done-c) 20%, transparent),
    0 0 16px color-mix(in srgb, var(--done-c) 40%, transparent);
  animation: done-breathe 2.8s ease-in-out infinite;
}
.tube.done .block {
  box-shadow:
    inset 0 -2px 6px rgba(0, 0, 0, 0.4),
    0 0 14px color-mix(in srgb, var(--c) 65%, transparent);
}

@keyframes done-breathe {
  0%, 100% {
    box-shadow:
      inset 0 0 20px color-mix(in srgb, var(--done-c) 18%, transparent),
      0 0 14px color-mix(in srgb, var(--done-c) 32%, transparent);
  }
  50% {
    box-shadow:
      inset 0 0 26px color-mix(in srgb, var(--done-c) 30%, transparent),
      0 0 26px color-mix(in srgb, var(--done-c) 62%, transparent);
  }
}

/* The completion flash: an expanding ring, drawn on a pseudo-element so it
   cannot fight the tube's own lift transform when selected. */
.tube.just-done::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 5px;
  border: 2px solid var(--done-c);
  pointer-events: none;
  animation: done-ring 0.9s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}

@keyframes done-ring {
  0%   { opacity: 0.95; transform: scale(1);    filter: drop-shadow(0 0 10px var(--done-c)); }
  70%  { opacity: 0.35; transform: scale(1.16); }
  100% { opacity: 0;    transform: scale(1.26); filter: drop-shadow(0 0 0 var(--done-c)); }
}
.tube.nudge { animation: nudge 0.26s ease; }

@keyframes nudge {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-5px); }
  75%      { transform: translateX(5px); }
}

.slot {
  height: 23px;
  border-radius: 7px;
  background: var(--slot-bg);
  box-shadow: inset 0 0 0 1px rgb(var(--accent-rgb) / 0.07);
}

/* Per-color classes rather than inline style attributes, so the deployed
   site can ship a Content-Security-Policy without 'unsafe-inline'. */
.block.c0 { --c: var(--c0); --t: var(--t0); }
.block.c1 { --c: var(--c1); --t: var(--t1); }
.block.c2 { --c: var(--c2); --t: var(--t2); }
.block.c3 { --c: var(--c3); --t: var(--t3); }
.block.c4 { --c: var(--c4); --t: var(--t4); }
.block.c5 { --c: var(--c5); --t: var(--t5); }
.block.c6 { --c: var(--c6); --t: var(--t6); }
.block.c7 { --c: var(--c7); --t: var(--t7); }
.block.c8 { --c: var(--c8); --t: var(--t8); }
.block.c9 { --c: var(--c9); --t: var(--t9); }

/* Blocks keep their ten colors — that is game information, not decoration —
   but pick up the emissive treatment of the theme. */
.block {
  position: relative;
  height: 23px;
  border-radius: 7px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 78%, #fff), var(--c));
  box-shadow:
    inset 0 -2px 6px rgba(0, 0, 0, 0.4),
    0 0 10px color-mix(in srgb, var(--c) 45%, transparent);
  transition: transform 0.12s ease;
  display: grid;
  place-items: center;
}
.block::before {
  content: "";
  position: absolute;
  inset: 3px 6px auto 6px;
  height: 5px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.4);
}
.block .tag {
  position: relative;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--t);
  opacity: 0.78;
  letter-spacing: 0.04em;
  display: none;
}
body.labels .block .tag { display: block; }

/* Selected blocks nudge downward, the direction they leave the tube. */
.tube.selected .block.lifted { transform: translateY(3px) scale(1.03); }

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

.controls {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: rgb(var(--bar-rgb) / var(--bar-alpha));
  border-top: 1px solid var(--line);
  min-width: 0;
}
.controls #restartBtn { flex: 0 0 auto; }
.controls-right { margin-left: auto; display: flex; gap: 10px; flex: 0 0 auto; }

/* Your solve history, inline in the game footer. Scrolls sideways so a long
   history never widens the panel. */
.histstrip {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: thin;
  padding: 2px 0;
}
/* The readable part: today, in words. */
.hist-summary {
  flex: 0 0 auto;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
  white-space: nowrap;
}
.hist-summary b {
  color: var(--accent);
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 10px rgb(var(--accent-rgb) / 0.5);
}
.hist-unsolved { font-weight: 500; }
.hist-latest {
  margin-left: 6px;
  padding: 2px 8px;
  border: 1px solid var(--line);
  background: rgb(var(--accent-rgb) / 0.06);
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-dim);
}

.hist-label {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
  padding-right: 2px;
}

.chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: rgb(var(--accent-rgb) / 0.04);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: default;
}
.chip b {
  font-size: 10px;
  font-weight: 500;
  color: var(--ink-dim);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.chip-best { border-color: rgb(var(--good-rgb) / 0.55); box-shadow: inset 0 0 12px rgb(var(--good-rgb) / 0.1); }
.chip-best b { color: var(--good); }
.chip-today {
  border-color: var(--accent);
  background: rgb(var(--accent-rgb) / 0.12);
  box-shadow: inset 0 0 12px rgb(var(--accent-rgb) / 0.18);
}
.chip-today b { color: var(--accent); }

/* ---------- controls ----------
   Every control is a notched HUD plate: the element's own background is the
   1px edge and an inset pseudo-element supplies the fill, because clip-path
   removes a real border. Two corners are cut, matching the panels. */

.btn,
.themetoggle,
.datepick,
.cal-nav {
  --btn-edge: var(--accent);
  --btn-fill: color-mix(in srgb, rgb(var(--accent-rgb)) 12%, var(--game-bg));
  --btn-ink: var(--accent);
  --notch: 9px;

  position: relative;
  border: 0;
  border-radius: 0;
  padding: 10px 18px;
  background: var(--btn-edge);
  color: var(--btn-ink);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  clip-path: polygon(
    var(--notch) 0, 100% 0,
    100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%,
    0 100%, 0 var(--notch)
  );
  transition: color 0.14s ease, background 0.14s ease;
}

/* The fill sits above the edge and below the label. */
.btn::before,
.themetoggle::before,
.datepick::before,
.cal-nav::before {
  content: "";
  position: absolute;
  inset: 1px;
  z-index: -1;
  background: var(--btn-fill);
  clip-path: polygon(
    calc(var(--notch) - 1px) 0, 100% 0,
    100% calc(100% - var(--notch) + 1px), calc(100% - var(--notch) + 1px) 100%,
    0 100%, 0 calc(var(--notch) - 1px)
  );
  transition: background 0.14s ease;
}

.btn:hover:not(:disabled),
.themetoggle:hover,
.datepick:hover,
.cal-nav:hover:not(:disabled) { --btn-fill: color-mix(in srgb, rgb(var(--accent-rgb)) 28%, var(--game-bg)); }

/* clip-path would cut an outline off, so focus is drawn inside the shape. */
.btn:focus-visible::after,
.themetoggle:focus-visible::after,
.datepick:focus-visible::after,
.cal-nav:focus-visible::after {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid var(--btn-ink);
  pointer-events: none;
}
.btn:focus-visible,
.themetoggle:focus-visible,
.datepick:focus-visible,
.cal-nav:focus-visible { outline: none; --btn-fill: color-mix(in srgb, rgb(var(--accent-rgb)) 30%, var(--game-bg)); }

.btn:disabled { opacity: 0.3; cursor: default; }

.btn-primary {
  --btn-fill: var(--accent);
  --btn-ink: var(--accent-ink);
  box-shadow: 0 0 18px rgb(var(--accent-rgb) / 0.4);
}
.btn-primary:hover:not(:disabled) { --btn-fill: #6bebff; }

.btn-ghost {
  --btn-edge: rgb(var(--accent-rgb) / 0.5);
  --btn-fill: var(--game-bg);
  --btn-ink: var(--ink);
}
.btn-ghost:hover:not(:disabled) { --btn-fill: color-mix(in srgb, rgb(var(--accent-rgb)) 18%, var(--game-bg)); }

.btn-icon {
  width: 42px;
  padding: 10px 0;
  font-size: 14px;
  text-align: center;
}
.btn-icon[aria-pressed="true"] {
  --btn-fill: var(--accent);
  --btn-ink: var(--accent-ink);
  box-shadow: 0 0 18px rgb(var(--accent-rgb) / 0.4);
}

#helpBtn {
  --btn-edge: rgb(var(--danger-rgb) / 0.75);
  --btn-fill: color-mix(in srgb, rgb(var(--danger-rgb)) 16%, var(--game-bg));
  --btn-ink: #ff6470;
}
#helpBtn:hover:not(:disabled) { --btn-fill: color-mix(in srgb, rgb(var(--danger-rgb)) 30%, var(--game-bg)); }

/* Declared after the shared control block so these win over it — including
   position, which the shared rule sets to relative. */
.themetoggle {
  --notch: 10px;
  position: fixed;
  top: 12px;
  right: 14px;
  z-index: 21;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  font-size: 24px;
  line-height: 1;
}

/* ---------- overlays ---------- */

.overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgb(var(--page-rgb) / 0.88);
  z-index: 5;
}
.overlay[hidden] { display: none; }

/* Page-level modals: the identity gate must cover the whole screen, not just
   one panel, and the profile dialog no longer belongs to the leaderboard. */
.overlay-fixed { position: fixed; z-index: 60; }

.panel {
  position: relative;
  width: min(420px, 100%);
  background:
    linear-gradient(180deg, rgb(var(--accent-rgb) / 0.07), transparent 90px),
    var(--panel-bg);
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 22px;
  box-shadow:
    inset 0 0 40px rgb(var(--accent-rgb) / 0.08),
    0 0 40px rgb(var(--accent-rgb) / 0.18),
    0 18px 44px rgba(0, 0, 0, 0.7);
}
.panel h2 {
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 14px rgb(var(--accent-rgb) / 0.5);
}
.panel-h3 {
  margin: 18px 0 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-dim);
}
.panel .idrow { padding: 0; margin-bottom: 10px; }
.panel-actions-wrap { margin-bottom: 16px; }
.panel .formnote { display: block; margin: 0 0 4px; }
.panel p { margin: 0 0 12px; color: var(--ink-dim); font-size: 14px; }
.win-line { color: var(--ink) !important; font-size: 15px; }

.rules { margin: 0 0 14px; padding-left: 18px; color: var(--ink-dim); font-size: 14px; }
.rules li { margin-bottom: 7px; }
.rules b { color: var(--accent); }
.keys { font-size: 12px; }
kbd {
  border: 1px solid var(--line);
  background: rgb(var(--accent-rgb) / 0.08);
  border-radius: 2px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
}

.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin: 0 0 18px;
  text-align: center;
}
.stats div {
  background: rgb(var(--accent-rgb) / 0.06);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 10px 6px;
}
.stats dt {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
}
.stats dd {
  margin: 3px 0 0;
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 700;
  color: var(--accent);
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.45);
}

/* ---------- leaderboard ---------- */

.lb-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 16px;
  background: rgb(var(--bar-rgb) / var(--bar-alpha));
  border-bottom: 1px solid var(--line);
}
.lb-head h2 {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.4);
}
.lb-head .btn-sm { flex: 0 0 auto; }

.live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.live i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 8px rgb(var(--good-rgb) / 0.8);
  animation: live-pulse 2s ease-in-out infinite;
}
.live[data-state="paused"] i { background: var(--ink-dim); box-shadow: none; animation: none; }
.live[data-state="offline"] i { background: #ff6470; box-shadow: 0 0 8px rgba(255, 100, 112, 0.7); animation: none; }
@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

/* The trigger reads as a field; the calendar itself is ours, because a native
   date popup is browser chrome and cannot take the theme. */
.datepick {
  --notch: 7px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  letter-spacing: 0.06em;
  padding: 5px 9px;
}
.datepick[aria-expanded="true"] { --btn-fill: rgb(var(--accent-rgb) / 0.28); }
.datepick-ico { opacity: 0.75; font-size: 10px; }

/* ---------- calendar ---------- */

.cal {
  position: fixed;
  z-index: 70;
  width: 232px;
  padding: 10px;
  background:
    linear-gradient(180deg, rgb(var(--accent-rgb) / 0.08), transparent 70px),
    var(--panel-bg);
  border: 1px solid var(--accent);
  border-radius: 2px;
  box-shadow:
    inset 0 0 30px rgb(var(--accent-rgb) / 0.08),
    0 0 30px rgb(var(--accent-rgb) / 0.22),
    0 16px 40px rgba(0, 0, 0, 0.7);
}
.cal[hidden] { display: none; }

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.cal-month {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.45);
}
.cal-nav {
  --notch: 6px;
  font-size: 13px;
  line-height: 1;
  padding: 3px 9px;
}
.cal-nav:disabled { opacity: 0.25; cursor: default; }

.cal-dow, .cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.cal-dow {
  margin-bottom: 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  text-align: center;
}

.cal-day {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: 2px;
  background: rgb(var(--accent-rgb) / 0.05);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.cal-day:hover:not(:disabled) { background: rgb(var(--accent-rgb) / 0.22); border-color: var(--accent); }
.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cal-day:disabled { opacity: 0.18; cursor: default; background: transparent; }
.cal-day.blank { background: none; border: 0; cursor: default; }
.cal-day.now { border-color: rgb(var(--accent-rgb) / 0.55); color: var(--accent); }
.cal-day.sel {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
  box-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.55);
}

.cal-foot { margin-top: 8px; display: flex; justify-content: flex-end; }
.btn-xs { padding: 4px 8px; font-size: 10px; line-height: 1.2; border-color: rgb(var(--accent-rgb) / 0.35); }

/* Readout meters, as under the reference's numeric panels. */
.meter {
  margin-top: 6px;
  height: 5px;
  background: rgb(var(--accent-rgb) / 0.1);
  border: 1px solid var(--line-soft);
  border-radius: 1px;
  overflow: hidden;
}
.meter-fill {
  display: block;
  width: 0;
  height: 100%;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent));
  box-shadow: 0 0 8px rgb(var(--accent-rgb) / 0.65);
  transition: width 0.5s ease;
}

.segs { margin-top: 6px; display: flex; gap: 2px; }
.rank-stat:last-child .segs { justify-content: flex-end; }
.seg {
  width: 8px;
  height: 5px;
  background: rgb(var(--accent-rgb) / 0.12);
  border: 1px solid var(--line-soft);
}
.seg.on {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 7px rgb(var(--accent-rgb) / 0.7);
}
.lb-sub { margin: 2px 0 0; font-size: 12px; color: var(--ink-dim); }

.lb-summary { display: flex; gap: 16px; margin: 0 auto 0 0; padding-left: 8px; }
.lb-summary div { text-align: right; }
.lb-summary dt {
  font-family: var(--font-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
}
.lb-summary dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.lb-block { border-top: 1px solid var(--line-soft); }
.lb-h3 {
  margin: 0;
  padding: 10px 16px 0;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
}
.lb-note { margin: 4px 0 0; padding: 0 16px; font-size: 11px; color: var(--ink-dim); }

.lb-wrap {
  max-height: 260px;
  overflow-y: auto;
  overflow-x: auto;
  margin-top: 8px;
}

.solved-chip {
  padding: 4px 10px;
  border: 1px solid rgb(var(--good-rgb) / 0.6);
  background: rgb(var(--good-rgb) / 0.12);
  color: var(--good);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  box-shadow: inset 0 0 12px rgb(var(--good-rgb) / 0.15);
}

.lb .when { color: var(--ink-dim); white-space: nowrap; }
.pb {
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid rgb(var(--good-rgb) / 0.5);
  background: rgb(var(--good-rgb) / 0.12);
  color: var(--good);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* ---------- score-zone chart ---------- */

.zone-stats {
  display: flex;
  gap: 22px;
  margin: 8px 0 0;
  padding: 0 16px;
}
.zone-stats dt {
  font-family: var(--font-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
}
.zone-stats dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.4);
}

.chart { padding: 10px 16px 0; }

.zbars {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  height: 60px;
  padding-top: 15px;
  border-bottom: 1px solid var(--line);
}
/* Capped so a handful of bars do not stretch into slabs. */
.zbar {
  position: relative;
  flex: 1 1 auto;
  max-width: 56px;
  height: 100%;
  display: flex;
  align-items: flex-end;
  min-width: 0;
}
.zfill {
  width: 100%;
  min-height: 2px;
  border-radius: 1px 1px 0 0;
  background: linear-gradient(180deg, var(--accent-deep), rgb(var(--deep-rgb) / 0.45));
  box-shadow: inset 0 0 0 1px rgb(var(--deep-rgb) / 0.7);
}
.zbar.mine .zfill {
  background: linear-gradient(180deg, var(--accent), rgb(var(--accent-rgb) / 0.5));
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 14px rgb(var(--accent-rgb) / 0.5);
}

/* Direct label so the player's bin is not identified by color alone. */
.zbar.mine::before {
  content: "You " attr(data-you);
  position: absolute;
  bottom: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%);
  padding: 1px 7px;
  border-radius: 2px;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.5);
}

.zbar:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 22px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: 5px 9px;
  border: 1px solid var(--accent);
  border-radius: 2px;
  background: var(--panel-bg);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 0 18px rgb(var(--accent-rgb) / 0.3);
}

.zaxis {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.idrow {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 16px 16px;
}
.idrow code {
  flex: 1 1 260px;
  min-width: 0;
  overflow-x: auto;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: rgb(var(--accent-rgb) / 0.05);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--accent);
  white-space: nowrap;
}
.btn-sm { --notch: 7px; padding: 8px 12px; font-size: 11px; }

.txt {
  flex: 1 1 220px;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid rgb(var(--accent-rgb) / 0.35);
  border-radius: 2px;
  background: rgb(var(--accent-rgb) / 0.05);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 14px;
}
.txt::placeholder { color: var(--placeholder); }
.txt:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 16px rgb(var(--accent-rgb) / 0.3);
}

.formnote { font-size: 12px; color: var(--ink-dim); font-family: var(--font-mono); min-height: 1em; }

/* auth form */
.fld { display: block; margin-bottom: 12px; }
.fld > span {
  display: block;
  margin-bottom: 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.fld .txt { flex: none; width: 100%; }

.authswap {
  margin: 14px 0 0 !important;
  font-size: 13px;
  text-align: center;
}
.linkbtn {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-weight: 700;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}
.linkbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.whoami {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 700;
  color: var(--accent) !important;
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.4);
}
.anon { color: var(--ink-dim); font-style: italic; }

/* ---------- rank badges ---------- */

.badge {
  width: 15px;
  height: 15px;
  margin-right: 5px;
  vertical-align: -3px;
  fill: currentColor;
}
.badge-gold   { color: #ffd24d; filter: drop-shadow(0 0 5px rgba(255, 210, 77, 0.75)); }
.badge-silver { color: #d3dde8; filter: drop-shadow(0 0 5px rgba(211, 221, 232, 0.6)); }
.badge-bronze { color: #d98a4a; filter: drop-shadow(0 0 5px rgba(217, 138, 74, 0.6)); }
.lb tr.podium-1 .rank { color: #ffd24d; }
.lb tr.podium-2 .rank { color: #d3dde8; }
.lb tr.podium-3 .rank { color: #d98a4a; }

/* ---------- celebration ---------- */

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

.champ {
  position: fixed;
  inset: 0;
  z-index: 81;
  display: grid;
  place-content: center;
  gap: 6px;
  text-align: center;
  pointer-events: none;
  animation: champ-in 0.5s ease both;
}
.champ[hidden] { display: none; }
.champ-rank {
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(72px, 16vw, 168px);
  font-weight: 700;
  line-height: 1;
  color: #ffd24d;
  text-shadow:
    0 0 24px rgba(255, 210, 77, 0.9),
    0 0 70px rgba(255, 210, 77, 0.55);
}
.champ-line {
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(13px, 2.4vw, 20px);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ink);
  text-shadow: 0 0 18px rgb(var(--accent-rgb) / 0.7);
}
@keyframes champ-in {
  from { opacity: 0; transform: scale(0.82); }
  to   { opacity: 1; transform: scale(1); }
}
.champ.out { animation: champ-out 0.7s ease both; }
@keyframes champ-out {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(1.12); }
}

.zone-pct {
  color: var(--accent) !important;
  font-weight: 700;
  text-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.5);
}

.zone-caption {
  margin: 8px 0 0;
  padding: 0 16px 12px;
  font-size: 11px;
  color: var(--ink-dim);
}

.lb {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.lb th {
  position: sticky;
  top: 0;
  background: var(--table-head);
  color: var(--ink-dim);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-align: left;
  padding: 6px 12px;
  border-bottom: 1px solid var(--line);
}
.lb td { padding: 7px 14px; border-top: 1px solid var(--line-soft); }
.lb th:first-child, .lb td:first-child { padding-left: 16px; }
.lb th:last-child, .lb td:last-child { padding-right: 16px; }
.lb .rank { width: 1%; white-space: nowrap; color: var(--ink-dim); font-weight: 700; }
.lb .moves { text-align: right; font-weight: 700; color: var(--ink); }
.lb .tries { text-align: right; color: var(--ink-dim); width: 1%; white-space: nowrap; }
.lb tr.top .rank { color: var(--accent); text-shadow: 0 0 10px rgb(var(--accent-rgb) / 0.5); }
.lb tr.today,
.lb tr.me {
  background: rgb(var(--accent-rgb) / 0.1);
  box-shadow: inset 2px 0 0 var(--accent);
}
.lb tr.today .date::after {
  content: "today";
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 2px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.lb-hint { font-weight: 500; text-transform: none; letter-spacing: 0.04em; opacity: 0.7; }

.lb-foot {
  margin: 0;
  padding: 8px 16px 12px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.lb-empty {
  padding: 22px 16px;
  text-align: center;
  color: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
}

.panel-actions { display: flex; gap: 10px; margin: 0; }

/* The Done row closes the dialog, so it is separated from the form above it
   rather than sitting flush against it. Scoped to the profile panel so the
   win and help dialogs keep their own spacing. */
#profileOverlay .panel > .panel-actions:last-child {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}
.panel-actions .btn {
  flex: 1;
  text-align: center;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}

/* ---------- footnote & prose ---------- */

.footnote {
  width: min(760px, 100%);
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--line-soft);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.foot-sep { opacity: 0.35; }
.foot-tg { color: var(--accent) !important; }
.foot-tg:hover { text-shadow: 0 0 10px rgb(var(--accent-rgb) / 0.6); }
.foot-by b {
  color: var(--accent);
  font-weight: 700;
  text-shadow: 0 0 10px rgb(var(--accent-rgb) / 0.5);
}
.footnote a, .prose a:not(.btn) { color: var(--ink-dim); }
.footnote a:hover { color: var(--accent); }

.prose { padding: 24px; line-height: 1.65; }
.prose h2 {
  margin: 22px 0 6px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.prose p { margin: 0; color: var(--ink-dim); }
.prose b { color: var(--ink); }
.prose h2.warn { color: #ff6470; }
.prose .warn-note { color: #ff8a94 !important; }

/* Scrollbars, so they belong to the instrument panel too. */
.lb-wrap, .histstrip, .idrow code { scrollbar-width: thin; scrollbar-color: rgb(var(--accent-rgb) / 0.4) transparent; }
.lb-wrap::-webkit-scrollbar, .histstrip::-webkit-scrollbar { width: 8px; height: 8px; }
.lb-wrap::-webkit-scrollbar-thumb, .histstrip::-webkit-scrollbar-thumb {
  background: rgb(var(--accent-rgb) / 0.3);
  border-radius: 0;
}
.lb-wrap::-webkit-scrollbar-track, .histstrip::-webkit-scrollbar-track { background: rgb(var(--accent-rgb) / 0.05); }


/* ---------- cursors ----------
   A thin reticle for the page and a bracketed target over anything you can
   act on. Each shape is drawn twice: a dark outline underneath so it stays
   visible over the bright colour blocks, then the cyan stroke on top. */

:root {
  --cur-aim: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23020508' stroke-opacity='.7' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M12 2.5v5.5M12 16v5.5M2.5 12h5.5M16 12h5.5'/%3E%3C/g%3E%3Cg fill='none' stroke='%2322e0ff' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M12 2.5v5.5M12 16v5.5M2.5 12h5.5M16 12h5.5'/%3E%3C/g%3E%3Ccircle cx='12' cy='12' r='2.6' fill='none' stroke='%23020508' stroke-opacity='.7' stroke-width='2.6'/%3E%3Ccircle cx='12' cy='12' r='1.6' fill='%2322e0ff'/%3E%3C/svg%3E") 12 12;

  --cur-target: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cg fill='none' stroke='%23020508' stroke-opacity='.7' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9.5V4h5.5M18.5 4H24v5.5M24 18.5V24h-5.5M9.5 24H4v-5.5M14 8.5v2.5M14 17v2.5M8.5 14h2.5M17 14h2.5'/%3E%3C/g%3E%3Cg fill='none' stroke='%2322e0ff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9.5V4h5.5M18.5 4H24v5.5M24 18.5V24h-5.5M9.5 24H4v-5.5M14 8.5v2.5M14 17v2.5M8.5 14h2.5M17 14h2.5'/%3E%3C/g%3E%3Ccircle cx='14' cy='14' r='2.2' fill='%2322e0ff'/%3E%3C/svg%3E") 14 14;
}

body { cursor: var(--cur-aim), crosshair; }

.tube,
.btn,
.linkbtn,
.datepick,
.cal-day,
.cal-nav,
.zbar,
.chip,
a { cursor: var(--cur-target), pointer; }

/* Text entry keeps a caret — a reticle over a password field helps nobody. */
.txt, input[type="text"], input[type="password"] { cursor: text; }

.btn:disabled,
.cal-day:disabled,
.cal-nav:disabled { cursor: var(--cur-aim), not-allowed; }

/* ---------- light-mode adjustments ----------
   Emissive glow is the whole point on a dark ground and pure noise on a light
   one, so the halos come off and the panel edges do the work instead. */

:root[data-theme="light"] :is(
  h1, .title-text, .brand, .stat b, .goal, .hud-head h2, .lb-head h2, .lb-h3,
  .cd-time, .gauge-center b, .zone-stats dd, .rank-stat dd, .hist-summary b,
  .foot-by b, .whoami, .panel h2, .champ-rank, .champ-line, .lb tr.top .rank,
  .zone-pct, .solved-chip, .cal-month
) { text-shadow: none; }

:root[data-theme="light"] .title-text { animation: none; }
:root[data-theme="light"] :is(.badge, .g-fill, .logo-sweep, .logo-bar) { filter: none; }

:root[data-theme="light"] :is(.game, .leaderboard, .hud) {
  box-shadow: 0 1px 2px rgb(10 36 54 / 0.06), 0 8px 24px rgb(10 36 54 / 0.10);
  border-color: rgb(var(--accent-rgb) / 0.28);
}
:root[data-theme="light"] .btn-primary { box-shadow: none; }
:root[data-theme="light"] .btn-primary:hover:not(:disabled) { --btn-fill: #0d86b3; }
:root[data-theme="light"] .panel {
  box-shadow: 0 18px 44px rgb(10 36 54 / 0.22);
}
:root[data-theme="light"] .tube.selected {
  box-shadow: 0 0 0 2px var(--accent), 0 6px 14px rgb(10 36 54 / 0.18);
}
:root[data-theme="light"] .worldmap { opacity: 0.3; }
:root[data-theme="light"] .game {
  background: rgb(var(--panel-rgb) / 0.62) !important;
}
:root[data-theme="light"] :is(.topbar, .controls) {
  background: rgb(var(--bar-rgb) / 0.97);
}
:root[data-theme="light"] .tube {
  background: linear-gradient(180deg, rgb(var(--accent-rgb) / 0.05), transparent 60%), #ffffff;
  border-color: var(--tube-edge);
}
:root[data-theme="light"] .slot {
  background: var(--slot-bg);
  box-shadow: inset 0 0 0 1px rgb(var(--accent-rgb) / 0.1);
}
:root[data-theme="light"] .overlay { background: rgb(233 241 248 / 0.86); }
:root[data-theme="light"] .block::before { background: rgb(255 255 255 / 0.5); }

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

@media (max-width: 760px) {
  /* Keep the countdown clear of the fixed toggle in the corner. */
  .countdown { padding-right: 44px; }
  .controls { flex-wrap: wrap; }
  .hist-summary { order: 3; flex: 1 1 100%; white-space: normal; }
  .histstrip { order: 4; flex: 1 1 100%; }
  .controls-right { margin-left: auto; }
}

@media (max-width: 520px) {
  .board { grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 18px 12px; }
  .goal { display: none; }
  .topbar { gap: 12px; }
  .btn { padding: 10px 14px; }
}

/* ---------- two-column, viewport-height layout ----------
   Opted into only when the viewport can actually hold the board without
   clipping; anything smaller keeps the stacked, page-scrolling version. */

@media (min-width: 1080px) and (min-height: 820px) {
  body {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    padding-bottom: 12px;
  }

  .layout {
    width: min(1440px, 100%);
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    /* Two columns: the board takes the whole left side, the instrument rail
       stacks down the right. Rank sits above the score zone and is the
       taller of the two; the leaderboard absorbs the remaining height. */
    grid-template-columns: minmax(0, 1fr) minmax(370px, 440px);
    grid-template-rows: 178px 146px minmax(0, 1fr);
    gap: 12px;
    align-items: stretch;
  }

  .game        { order: 0; grid-column: 1; grid-row: 1 / 4; }
  .hud-rank    { order: 0; grid-column: 2; grid-row: 1; }
  .hud-zone    { order: 0; grid-column: 2; grid-row: 2; }
  .leaderboard { order: 0; grid-column: 2; grid-row: 3; }

  .game { display: flex; flex-direction: column; min-height: 0; }
  .board { flex: 1 1 auto; align-content: center; min-height: 0; }

  /* A taller board deserves bigger pieces. */
  .tube { max-width: 132px; gap: 7px; padding: 9px; }
  .slot, .block { height: 29px; }
  .block .tag { font-size: 14px; }

  /* Rank: dial centred, best move left, attempts right. */
  /* min-height belongs to the stacked layout only; here it forced the gauge
     to 150px inside a 134px row and pushed the dial through the panel edge. */
  .hud-rank .gauge { padding: 2px; min-width: 0; min-height: 0; }
  .hud-rank .gauge-svg { width: 112px; height: 112px; max-height: 100%; }
  .hud-rank .gauge-center b { font-size: 24px; }
  .hud-rank .gauge-center span { font-size: 8px; }

  /* Score zone: the distribution plus where you stand. */
  .hud-zone #zone { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; min-height: 0; }
  /* The stat row repeats the rank panel, so it stays hidden. The caption is
     kept: it is where the standing is spelled out in words. */
  .hud-zone .zone-stats { display: none; }
  .hud-zone .zone-caption { padding: 0 14px 8px; margin-top: 5px; font-size: 11px; }
  .hud-zone .chart { padding: 6px 14px 8px; }
  .hud-zone .zbars { height: 46px; padding-top: 12px; }
  .hud-zone .zaxis { margin-top: 4px; }

  /* The right column is the one that fills the viewport. */
  .leaderboard {
    height: 100%;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .lb-head, .lb-block { flex: 0 0 auto; }

  /* Only this block flexes, so it owns the single scrollbar. */
  .lb-grow {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  .lb-grow .lb-wrap {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
  }

  /* Every other table sits at its natural height. */
  .lb-block:not(.lb-grow) .lb-wrap {
    max-height: none;
    overflow: visible;
  }

  .footnote { width: min(1440px, 100%); flex: 0 0 auto; }
  .countdown {
    position: fixed;
    top: 14px;
    left: 16px;
    z-index: 20;
    align-self: auto;
  }
  h1 { font-size: 26px; gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
