/* ==========================================================================
   stackoverflo.lol — retro arcade theme
   Dual-mode design tokens. Dark = CRT arcade cabinet. Light = 8-bit game manual.
   ========================================================================== */

:root {
  /* type — Silkscreen for display/labels, VT323 for numerals, IBM Plex Mono
     for copy. `--fs` is the global size unit every font-size multiplies, so
     the whole scale can be nudged from one place. */
  --fs: 1.15px;
  --font-display: "Silkscreen", ui-monospace, monospace;
  --font-num: "VT323", "Courier New", monospace;
  --font-body: "IBM Plex Mono", ui-monospace, "Courier New", monospace;

  /* geometry */
  --px: 4px;              /* pixel unit — all borders/offsets are multiples */
  --radius: 0px;          /* retro = no rounding, ever */
  --header-h: 64px;

  /* motion */
  --snap: 90ms steps(3, end);
  --ease: 160ms cubic-bezier(.2, .8, .2, 1);
}

/* ------------------------------- DARK (default) ------------------------- */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  --bg-void: #08060f;
  --bg-base: #0d0a1a;
  --bg-panel: #141028;
  --bg-panel-2: #1c1638;
  --bg-inset: #0a0816;

  --grid-line: #241c4a;
  --grid-line-strong: #33276b;

  --fg: #e8e4ff;
  --fg-dim: #9c93c9;
  --fg-faint: #635a8f;

  --accent: #b26cff;         /* primary purple */
  --accent-2: #7c3aed;
  --accent-ink: #10061f;
  --accent-glow: rgba(178, 108, 255, .45);

  --cyan: #35e6ff;
  --lime: #7dff5a;
  --amber: #ffc44d;
  --rose: #ff4d7d;

  --ok: var(--lime);
  --bad: var(--rose);

  --bevel-light: rgba(255, 255, 255, .16);
  --bevel-dark: rgba(0, 0, 0, .62);
  --shadow-hard: 0 var(--px) 0 0 #05030c, 0 0 0 var(--px) #05030c;

  --scanline: rgba(0, 0, 0, .22);
  --vignette: rgba(0, 0, 0, .55);
  --glow-strength: 1;
}

/* ------------------------------- LIGHT ---------------------------------- */
[data-theme="light"] {
  color-scheme: light;

  --bg-void: #ded7c8;
  --bg-base: #f4efe2;
  --bg-panel: #fffdf6;
  --bg-panel-2: #f0e9d8;
  --bg-inset: #e7e0cd;

  --grid-line: #d3c9b2;
  --grid-line-strong: #b9ab8c;

  --fg: #1d1630;
  --fg-dim: #5b5175;
  --fg-faint: #928aa8;

  --accent: #6d28d9;
  --accent-2: #4c1d95;
  --accent-ink: #fffdf6;
  --accent-glow: rgba(109, 40, 217, .22);

  --cyan: #0f7d94;
  --lime: #2f8f2a;
  --amber: #9a6a00;
  --rose: #c81e4f;

  --ok: var(--lime);
  --bad: var(--rose);

  --bevel-light: rgba(255, 255, 255, .95);
  --bevel-dark: rgba(84, 70, 44, .35);
  --shadow-hard: 0 var(--px) 0 0 #1d1630, 0 0 0 var(--px) #1d1630;

  --scanline: rgba(120, 105, 70, .07);
  --vignette: rgba(120, 105, 70, .16);
  --glow-strength: 0;
}

/* ============================== base =================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg-base);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: calc(14 * var(--fs));
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* CRT overlay — scanlines + vignette. Purely decorative, pointer-transparent. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  background:
    repeating-linear-gradient(
      to bottom,
      transparent 0 2px,
      var(--scanline) 2px 3px
    ),
    radial-gradient(120% 120% at 50% 50%, transparent 55%, var(--vignette) 100%);
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: .02em;
  margin: 0;
}

h1 { font-size: calc(20 * var(--fs)); }
h2 { font-size: calc(15 * var(--fs)); }
h3 { font-size: calc(12 * var(--fs)); }
h4 { font-size: calc(11 * var(--fs)); }

p { margin: 0 0 1em; }

a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color var(--ease), color var(--ease);
}
a:hover { border-bottom-color: var(--accent); }

code, kbd {
  font-family: var(--font-body);
  background: var(--bg-inset);
  border: 2px solid var(--grid-line);
  padding: 1px 5px;
  font-size: .92em;
}

:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
}

::selection { background: var(--accent); color: var(--accent-ink); }

/* ============================== primitives ============================= */

.panel {
  background: var(--bg-panel);
  border: var(--px) solid var(--grid-line-strong);
  box-shadow:
    inset 2px 2px 0 var(--bevel-light),
    inset -2px -2px 0 var(--bevel-dark);
}

.panel--inset {
  background: var(--bg-inset);
  box-shadow:
    inset 2px 2px 0 var(--bevel-dark),
    inset -2px -2px 0 var(--bevel-light);
}

.panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  background: var(--bg-panel-2);
  border-bottom: var(--px) solid var(--grid-line-strong);
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-dim);
}

.panel__body { padding: 10px; }

/* --- buttons --- */
.btn {
  --btn-bg: var(--bg-panel-2);
  --btn-fg: var(--fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 3px solid var(--fg);
  border-bottom-width: 6px;
  cursor: pointer;
  user-select: none;
  transition: transform var(--snap), filter var(--ease);
}
.btn:hover { filter: brightness(1.14); }
.btn:active {
  transform: translateY(3px);
  border-bottom-width: 3px;
}
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .42;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-ink);
  border-color: var(--accent-2);
  text-shadow: none;
}
.btn--primary:not([disabled]) {
  box-shadow: 0 0 calc(18px * var(--glow-strength)) var(--accent-glow);
}

.btn--ghost {
  --btn-bg: transparent;
  border-color: var(--grid-line-strong);
  border-bottom-width: 3px;
  color: var(--fg-dim);
}
.btn--ghost:hover { color: var(--fg); border-color: var(--accent); }

.btn--sm { padding: 6px 10px; font-size: calc(9 * var(--fs)); border-width: 2px; border-bottom-width: 4px; }
.btn--icon { padding: 8px; min-width: 34px; }

/* --- form controls --- */
.field { display: block; margin-bottom: 14px; }

.field__label {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 6px;
}

.field__hint { font-family: var(--font-body); font-size: calc(12 * var(--fs)); color: var(--fg-faint); text-transform: none; letter-spacing: 0; }

.input, .select, .textarea {
  width: 100%;
  padding: 9px 10px;
  font-family: var(--font-body);
  font-size: calc(13 * var(--fs));
  color: var(--fg);
  background: var(--bg-inset);
  border: 3px solid var(--grid-line-strong);
  box-shadow: inset 2px 2px 0 var(--bevel-dark);
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--accent);
  outline: none;
}
.textarea { resize: vertical; min-height: 76px; line-height: 1.5; }
.select { appearance: none; cursor: pointer; padding-right: 28px;
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-dim) 50%),
                    linear-gradient(135deg, var(--fg-dim) 50%, transparent 50%);
  background-position: right 14px top 55%, right 8px top 55%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
/* --- inline validation, shown against the offending control --- */
.input--invalid, .textarea--invalid, .select--invalid {
  border-color: var(--bad);
  box-shadow: inset 2px 2px 0 var(--bevel-dark), 0 0 0 2px var(--bad);
}
.field__error {
  display: none;
  align-items: flex-start;
  gap: 6px;
  margin-top: 5px;
  color: var(--bad);
  font-size: calc(11 * var(--fs));
  line-height: 1.45;
}
.field__error::before {
  content: "\25B2";
  font-size: calc(8 * var(--fs));
  line-height: 1.7;
  flex: none;
}
.field.is-invalid .field__error { display: flex; }
.field.is-invalid .field__label { color: var(--bad); }

/* --- badges / chips --- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px;
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .07em;
  text-transform: uppercase;
  border: 2px solid currentColor;
  color: var(--fg-dim);
}
.badge--accent { color: var(--accent); }
.badge--ok { color: var(--ok); }
.badge--bad { color: var(--bad); }
.badge--cyan { color: var(--cyan); }
.badge--amber { color: var(--amber); }

/* --- X profile chip: the mark plus the handle, whole thing clickable --- */
.x-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 2px solid var(--grid-line-strong);
  background: var(--bg-inset);
  color: var(--fg);
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .06em;
  cursor: pointer;
  transition: color var(--ease), border-color var(--ease), background var(--ease);
}
.x-link:hover,
.x-link:focus-visible {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
}
.x-mark {
  display: block;
  width: calc(11 * var(--fs));
  height: calc(11 * var(--fs));
  flex: none;
}

/* --- stat readouts --- */
.stat { display: flex; flex-direction: column; gap: 1px; }
.stat__k {
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.stat__v {
  font-family: var(--font-num);
  font-size: calc(26 * var(--fs));
  line-height: 1;
  color: var(--fg);
}
.stat__v--accent { color: var(--accent); text-shadow: 0 0 calc(12px * var(--glow-strength)) var(--accent-glow); }
.stat__v--cyan { color: var(--cyan); }
.stat__v--lime { color: var(--lime); }

/* --- live dot --- */
.live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .1em;
  color: var(--lime);
  text-transform: uppercase;
}
.live::before {
  content: "";
  width: 7px; height: 7px;
  background: var(--lime);
  animation: blink 1.4s steps(2, end) infinite;
}
@keyframes blink { 50% { opacity: .15; } }

/* --- tables --- */
.table { width: 100%; border-collapse: collapse; font-size: calc(13 * var(--fs)); }
.table th {
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .08em;
  text-transform: uppercase;
  text-align: left;
  color: var(--fg-faint);
  padding: 8px 10px;
  border-bottom: 3px solid var(--grid-line-strong);
  white-space: nowrap;
}
.table td { padding: 9px 10px; border-bottom: 2px solid var(--grid-line); vertical-align: middle; }
.table tbody tr:hover { background: var(--bg-panel-2); }
.table .num { font-family: var(--font-num); font-size: calc(18 * var(--fs)); }

/* ============================== app shell ============================== */

.site {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 14px;
  height: var(--header-h);
  padding: 0 16px;
  background: var(--bg-void);
  border-bottom: var(--px) solid var(--accent-2);
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-display);
  font-size: calc(13 * var(--fs));
  color: var(--fg);
  border: 0;
  white-space: nowrap;
}
.brand:hover { border: 0; }
/* Brand mark is the logo artwork itself; sized by height so the intrinsic
   150x160 ratio keeps its own width. `pixelated` because the mark is a
   hard-edged block motif — smooth downscaling muddies the bevels. */
.brand__mark {
  height: 22px;
  width: auto;
  flex: none;
  image-rendering: pixelated;
  filter: drop-shadow(0 0 calc(5px * var(--glow-strength)) var(--accent-glow));
}
.brand__lol { color: var(--accent); }

.nav { display: flex; align-items: center; gap: 4px; margin-left: 8px; }
.nav a {
  padding: 8px 10px;
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--fg-dim);
  border: 0;
}
.nav a:hover { color: var(--fg); background: var(--bg-panel); border: 0; }
.nav a[aria-current="page"] { color: var(--accent); background: var(--bg-panel); }

.topbar__spacer { flex: 1; }

.topbar__price {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 5px 10px;
  border: 2px solid var(--grid-line-strong);
  background: var(--bg-panel);
  white-space: nowrap;
}
.topbar__price b { font-family: var(--font-num); font-size: calc(21 * var(--fs)); color: var(--amber); line-height: 1; }
.topbar__price span { font-family: var(--font-display); font-size: calc(9 * var(--fs)); color: var(--fg-faint); letter-spacing: .08em; }

.theme-toggle {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  background: var(--bg-panel);
  border: 3px solid var(--grid-line-strong);
  color: var(--amber);
  cursor: pointer;
  font-size: calc(15 * var(--fs));
  line-height: 1;
}
.theme-toggle:hover { border-color: var(--accent); }


/* ================================ footer =============================== */

.footer {
  margin-top: auto;
  background: var(--bg-void);
  border-top: var(--px) solid var(--accent-2);
  color: var(--fg-dim);
  font-size: calc(12 * var(--fs));
}

/* pixel sawtooth ridge, drawn with gradients so it costs no assets */
.footer__ridge {
  height: 8px;
  background:
    repeating-linear-gradient(90deg,
      var(--accent) 0 8px, transparent 8px 16px,
      var(--cyan) 16px 24px, transparent 24px 32px);
  opacity: .55;
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 26px;
  max-width: 1180px;
  margin: 0 auto;
  padding: 26px 16px 20px;
}

.footer__col h4 {
  font-size: calc(10 * var(--fs));
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 10px;
}
.footer__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.footer__col a { color: var(--fg-dim); border: 0; }
.footer__col a:hover { color: var(--accent); border: 0; }

.footer__tag {
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  line-height: 1.7;
  color: var(--fg);
  margin: 10px 0 12px;
}
.footer__tag b { color: var(--accent); }

.footer__meter {
  display: flex;
  gap: 2px;
  margin-bottom: 10px;
}
.footer__meter i {
  width: 10px; height: 10px;
  background: var(--grid-line-strong);
}
.footer__meter i[data-on="1"] { background: var(--accent); }

.footer__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  max-width: 1180px;
  margin: 0 auto;
  padding: 12px 16px 26px;
  border-top: 2px solid var(--grid-line);
  color: var(--fg-faint);
  font-size: calc(11 * var(--fs));
}
.footer__coin {
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  color: var(--amber);
  letter-spacing: .08em;
}

/* Builder credit (X / @saas_buildr), beside the live tally on every public
   page. Deliberately styled as chrome, not a CTA: it inherits the footer's
   dim colour and only brightens on hover, so it cannot compete with the buy
   flow. The glyph is the shared .x-mark from ui.js X_MARK, which already
   sizes itself and sets flex:none, and is filled with currentColor — so
   neither theme nor :hover needs an icon rule of its own. */
.footer__builder {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  color: var(--fg-dim);
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .06em;
  white-space: nowrap;
}
.footer__builder:hover,
.footer__builder:focus-visible { color: var(--accent); border: 0; }

/* ============================== layout utils =========================== */

.wrap { width: 100%; max-width: 1180px; margin: 0 auto; padding: 24px 16px 48px; }
.wrap--wide { max-width: 1480px; }
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }
.gap-4 { gap: 4px; } .gap-6 { gap: 6px; } .gap-8 { gap: 8px; }
.gap-10 { gap: 10px; } .gap-14 { gap: 14px; } .gap-20 { gap: 20px; }
.wrapf { flex-wrap: wrap; }
.mt-10 { margin-top: 10px; } .mt-20 { margin-top: 20px; }
.mb-10 { margin-bottom: 10px; } .mb-20 { margin-bottom: 20px; }
.grow { flex: 1; min-width: 0; }
.dim { color: var(--fg-dim); }
.faint { color: var(--fg-faint); }
.small { font-size: calc(12 * var(--fs)); }
.num { font-family: var(--font-num); }
.center { text-align: center; }
.hide { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.section-title::after {
  content: "";
  flex: 1;
  height: var(--px);
  background: repeating-linear-gradient(to right, var(--grid-line-strong) 0 8px, transparent 8px 12px);
}

/* ============================== tower view ============================= */

.tower-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 316px;
  gap: 14px;
  align-items: start;
  padding: 14px;
}

.stage {
  position: relative;
  height: calc(100vh - var(--header-h) - 28px);
  min-height: 460px;
  background: var(--bg-void);
  border: var(--px) solid var(--grid-line-strong);
  overflow: hidden;
}

#tower-canvas { display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; }
#tower-canvas.is-dragging { cursor: grabbing; }
#tower-canvas.is-placing { cursor: crosshair; }

.stage__overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 10px;
}
/* pointer-events is an inherited property, so the overlay opts out wholesale
   and only the HUD widgets opt back in.

   This used to be `.stage__overlay > * { pointer-events: auto }`, but the
   overlay's direct children are .stage__row layout containers, not widgets:
   full-width flex rows whose height comes from their tallest child (the 300px
   minimap). Granting them `auto` laid two invisible mats over the canvas — a
   44px strip at the top and a 283px strip at the bottom — which swallowed
   every pointer event across the full width, including the empty gap between
   the search box and the toolbar. Blocks under a strip could not be hovered
   or clicked while blocks between them worked, which is what made the dead
   zones look random; click-to-place on /buy was lost in the same bands.

   So the rows stay transparent and only their widget children take input. */
.stage__row { pointer-events: none; }
.stage__row > * { pointer-events: auto; }

.stage__tl, .stage__bl, .stage__br, .stage__tr { display: flex; gap: 8px; align-items: flex-start; }
.stage__row { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.stage__row--bottom { align-items: flex-end; }

.toolbar {
  display: flex;
  gap: 3px;
  padding: 4px;
  background: var(--bg-panel);
  border: 3px solid var(--grid-line-strong);
}
.toolbar button {
  display: grid;
  place-items: center;
  min-width: 30px; height: 30px;
  padding: 0 7px;
  background: transparent;
  border: 0;
  color: var(--fg-dim);
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  cursor: pointer;
}
.toolbar button:hover { background: var(--bg-panel-2); color: var(--fg); }
.toolbar button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.toolbar__sep { width: 2px; background: var(--grid-line-strong); margin: 3px 2px; }

.zoom-readout {
  font-family: var(--font-num);
  font-size: calc(17 * var(--fs));
  color: var(--cyan);
  padding: 0 6px;
  align-self: center;
  min-width: 52px;
  text-align: center;
}

.search {
  position: relative;
  width: 260px;
}
.search .input { padding-left: 30px; font-size: calc(12 * var(--fs)); }
.search::before {
  content: "\1F50D";
  position: absolute;
  left: 8px; top: 50%;
  transform: translateY(-50%);
  font-size: calc(12 * var(--fs));
  opacity: .7;
  pointer-events: none;
}
.search__results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  max-height: 320px;
  overflow-y: auto;
  background: var(--bg-panel);
  border: 3px solid var(--accent-2);
  z-index: 40;
}
.search__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 9px;
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--grid-line);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: calc(12 * var(--fs));
  text-align: left;
  cursor: pointer;
}
.search__item:hover, .search__item[data-active="true"] { background: var(--accent); color: var(--accent-ink); }
.search__item .faint { color: inherit; opacity: .7; }
.search__swatch { width: 20px; height: 20px; border: 2px solid var(--bevel-dark); flex: none; }
.search__empty { padding: 12px; color: var(--fg-faint); font-size: calc(12 * var(--fs)); }

/* The minimap is a movement HUD, not permanent furniture: it appears while the
   camera is moving and fades once the view settles (app.js toggles .is-moving).
   pointer-events must follow opacity, otherwise an invisible 74px strip keeps
   swallowing clicks aimed at the tower behind it. Because it is only clickable
   while visible, app.js keeps it alive on pointerenter — that pair is what makes
   it reachable instead of something that vanishes as you reach for it. */
.minimap-wrap {
  width: 74px;
  background: var(--bg-panel);
  border: 3px solid var(--grid-line-strong);
  padding: 4px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(6px);
  transition: opacity .2s ease, transform .2s ease;
}
.minimap-wrap.is-moving {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}
/* PRD §56: motion is decoration here, so drop the slide and cross-fade only. */
@media (prefers-reduced-motion: reduce) {
  .minimap-wrap { transform: none; transition: opacity .12s linear; }
}
#minimap { display: block; width: 100%; height: 252px; cursor: pointer; }
.minimap-wrap__label {
  font-family: var(--font-display);
  font-size: calc(8 * var(--fs));
  letter-spacing: .1em;
  color: var(--fg-faint);
  text-align: center;
  padding-bottom: 3px;
  text-transform: uppercase;
}

/* opening-shot caption, fades out the moment the visitor takes over */
.intro-hint {
  position: absolute;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  z-index: 25;
  padding: 7px 12px;
  max-width: calc(100% - 24px);
  text-align: center;
  background: var(--bg-panel);
  border: 3px solid var(--accent);
  color: var(--fg-dim);
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .05em;
  pointer-events: none;
  box-shadow: var(--shadow-hard);
  animation: fade var(--ease);
  transition: opacity 380ms ease, transform 380ms ease;
}
.intro-hint.is-out {
  opacity: 0;
  transform: translateX(-50%) translateY(8px);
}

.hover-card {
  position: absolute;
  z-index: 30;
  min-width: 150px;
  max-width: 240px;
  padding: 7px 9px;
  background: var(--bg-panel);
  border: 3px solid var(--accent);
  pointer-events: none;
  font-size: calc(12 * var(--fs));
  box-shadow: var(--shadow-hard);
}
.hover-card b { display: block; font-family: var(--font-display); font-size: calc(10 * var(--fs)); margin-bottom: 3px; }

.sidebar { display: flex; flex-direction: column; gap: 12px; }

.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  background: var(--grid-line);
}
.stat-grid .stat { padding: 9px 10px; background: var(--bg-panel); }

.feed { max-height: 268px; overflow-y: auto; }
.feed__item {
  display: flex;
  gap: 8px;
  padding: 7px 10px;
  border-bottom: 2px solid var(--grid-line);
  font-size: calc(12 * var(--fs));
  animation: slide-in 240ms ease;
}
@keyframes slide-in { from { opacity: 0; transform: translateX(-10px); } }
.feed__dot { width: 7px; height: 7px; margin-top: 5px; flex: none; background: var(--fg-faint); }
.feed__dot--buy { background: var(--lime); }
.feed__dot--row { background: var(--amber); }
.feed__dot--price { background: var(--rose); }
.feed__dot--reserve { background: var(--cyan); }
.feed__dot--milestone { background: var(--accent); }
.feed__t { font-family: var(--font-num); font-size: calc(14 * var(--fs)); color: var(--fg-faint); margin-left: auto; flex: none; }

/* ============================== modal ================================== */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(6, 4, 14, .78);
  animation: fade var(--ease);
}
[data-theme="light"] .modal-backdrop { background: rgba(60, 50, 30, .55); }
@keyframes fade { from { opacity: 0; } }

.modal {
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--bg-panel);
  border: var(--px) solid var(--accent);
  box-shadow: 0 0 calc(46px * var(--glow-strength)) var(--accent-glow);
  animation: pop 160ms cubic-bezier(.2, 1.4, .4, 1);
}
.modal--wide { max-width: 680px; }
@keyframes pop { from { transform: scale(.9); opacity: 0; } }

.modal__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-panel-2);
  border-bottom: var(--px) solid var(--accent-2);
}
.modal__close {
  margin-left: auto;
  width: 32px; height: 32px;
  background: transparent;
  border: 3px solid var(--grid-line-strong);
  color: var(--fg-dim);
  font-family: var(--font-display);
  font-size: calc(11 * var(--fs));
  cursor: pointer;
  flex: none;
}
.modal__close:hover { border-color: var(--bad); color: var(--bad); }
.modal__body { padding: 14px; }
.modal__foot {
  display: flex;
  gap: 8px;
  padding: 12px 14px;
  border-top: var(--px) solid var(--grid-line-strong);
  background: var(--bg-panel-2);
  flex-wrap: wrap;
}

.product-hero { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 14px; }
.product-hero__logo {
  width: 88px; height: 88px;
  flex: none;
  display: grid;
  place-items: center;
  border: 3px solid var(--bevel-dark);
  font-family: var(--font-display);
  font-size: calc(22 * var(--fs));
  overflow: hidden;
}
.product-hero__logo img { width: 100%; height: 100%; object-fit: contain; }

.kv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 2px;
  background: var(--grid-line);
  border: 2px solid var(--grid-line);
}
.kv { padding: 8px 10px; background: var(--bg-inset); }
.kv__k { font-family: var(--font-display); font-size: calc(9 * var(--fs)); letter-spacing: .08em; text-transform: uppercase; color: var(--fg-faint); }
.kv__v { font-family: var(--font-num); font-size: calc(20 * var(--fs)); line-height: 1.1; }

.shape-mini { display: grid; gap: 1px; }
.shape-mini i { width: 8px; height: 8px; }
.shape-mini i[data-on="1"] { background: var(--accent); }
.shape-mini i[data-on="0"] { background: var(--grid-line); }

/* ============================== designer =============================== */

.buy-layout {
  display: grid;
  grid-template-columns: 330px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  padding: 16px;
}
.buy-layout--place { grid-template-columns: 288px minmax(0, 1fr); }

.steps {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-bottom: 14px;
  background: var(--grid-line);
  border: 2px solid var(--grid-line);
  overflow-x: auto;
}
.step-chip {
  flex: 1;
  min-width: 74px;
  padding: 9px 8px;
  background: var(--bg-panel);
  border: 0;
  color: var(--fg-faint);
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
}
.step-chip b { display: block; font-family: var(--font-num); font-size: calc(18 * var(--fs)); line-height: 1; margin-bottom: 2px; }
.step-chip[aria-current="true"] { background: var(--accent); color: var(--accent-ink); }
.step-chip[data-done="true"] { color: var(--lime); }
.step-chip[disabled] { cursor: not-allowed; opacity: .55; }

.designer-grid {
  display: grid;
  gap: 2px;
  background: var(--grid-line);
  border: 3px solid var(--grid-line-strong);
  padding: 2px;
  width: max-content;
  margin: 0 auto;
  touch-action: none;
}
.designer-cell {
  width: 26px; height: 26px;
  background: var(--bg-inset);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: background var(--snap);
}
.designer-cell:hover { background: var(--bg-panel-2); box-shadow: inset 0 0 0 2px var(--accent); }
.designer-cell[data-on="1"] {
  background: var(--accent);
  box-shadow: inset 2px 2px 0 var(--bevel-light), inset -2px -2px 0 var(--bevel-dark);
}
.designer-cell[data-on="1"]:hover { background: var(--accent-2); }
.designer-cell[data-orphan="1"] { background: var(--bad); }

.swatches { display: flex; flex-wrap: wrap; gap: 5px; }
.swatch {
  width: 28px; height: 28px;
  border: 3px solid var(--grid-line-strong);
  cursor: pointer;
  padding: 0;
}
.swatch[aria-pressed="true"] { border-color: var(--fg); box-shadow: 0 0 0 2px var(--accent); }

.dropzone {
  display: grid;
  place-items: center;
  gap: 6px;
  padding: 18px 12px;
  text-align: center;
  background: var(--bg-inset);
  border: 3px dashed var(--grid-line-strong);
  color: var(--fg-faint);
  font-size: calc(12 * var(--fs));
  cursor: pointer;
}
.dropzone:hover, .dropzone.is-over { border-color: var(--accent); color: var(--fg-dim); }
.dropzone__preview { width: 62px; height: 62px; object-fit: contain; }

.price-lines { border: 2px solid var(--grid-line); }
.price-line {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-bottom: 2px solid var(--grid-line);
  font-size: calc(13 * var(--fs));
}
.price-line:last-child { border-bottom: 0; }
.price-line--total {
  background: var(--bg-panel-2);
  font-family: var(--font-display);
  font-size: calc(11 * var(--fs));
  align-items: center;
}
.price-line--total b { font-family: var(--font-num); font-size: calc(27 * var(--fs)); color: var(--amber); line-height: 1; }

.validity {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 10px;
  border: 3px solid var(--grid-line-strong);
  background: var(--bg-inset);
  font-size: calc(12 * var(--fs));
}
.validity--ok { border-color: var(--ok); color: var(--ok); }
.validity--bad { border-color: var(--bad); color: var(--bad); }
.validity__icon { font-family: var(--font-display); font-size: calc(12 * var(--fs)); flex: none; line-height: 1.3; }

.countdown {
  font-family: var(--font-num);
  font-size: calc(40 * var(--fs));
  line-height: 1;
  color: var(--amber);
  letter-spacing: .04em;
}
.countdown--urgent { color: var(--bad); animation: blink .7s steps(2, end) infinite; }

.legal-check { display: flex; gap: 9px; align-items: flex-start; font-size: calc(12 * var(--fs)); margin-bottom: 12px; }
.legal-check input { margin-top: 3px; width: 16px; height: 16px; accent-color: var(--accent); flex: none; }

.preview-tile {
  display: grid;
  place-items: center;
  padding: 14px;
  background: var(--bg-inset);
  border: 3px solid var(--grid-line-strong);
}

.notice {
  padding: 9px 11px;
  border-left: 6px solid var(--amber);
  background: var(--bg-panel-2);
  color: var(--fg-dim);
  font-size: calc(12 * var(--fs));
}
.notice--bad { border-left-color: var(--bad); }
.notice--ok { border-left-color: var(--ok); }

/* toast */
.toasts {
  position: fixed;
  bottom: 16px; left: 50%;
  transform: translateX(-50%);
  z-index: 500;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
}
.toast {
  padding: 10px 16px;
  background: var(--bg-panel);
  border: 3px solid var(--accent);
  color: var(--fg);
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .05em;
  box-shadow: var(--shadow-hard);
  animation: pop 160ms cubic-bezier(.2, 1.4, .4, 1);
  max-width: 88vw;
  text-align: center;
}
.toast--bad { border-color: var(--bad); }
.toast--ok { border-color: var(--ok); }

/* how-it-works / content pages */
.prose { max-width: 720px; }
.prose h2 { margin: 28px 0 12px; color: var(--accent); }
.prose h3 { margin: 20px 0 8px; }
.prose ul, .prose ol { margin: 0 0 1em; padding-left: 22px; }
.prose li { margin-bottom: 6px; }
.prose pre {
  padding: 12px;
  background: var(--bg-inset);
  border: 3px solid var(--grid-line-strong);
  overflow-x: auto;
  font-size: calc(12 * var(--fs));
  line-height: 1.5;
}

.tier-table td:last-child, .tier-table th:last-child { text-align: right; }

.tabs { display: flex; gap: 2px; background: var(--grid-line); border: 2px solid var(--grid-line); margin-bottom: 14px; width: max-content; }
.tab {
  padding: 9px 15px;
  background: var(--bg-panel);
  border: 0;
  color: var(--fg-dim);
  font-family: var(--font-display);
  font-size: calc(10 * var(--fs));
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
.tab[aria-selected="true"] { background: var(--accent); color: var(--accent-ink); }

.rank {
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  font-family: var(--font-display);
  font-size: calc(12 * var(--fs));
  border: 2px solid var(--grid-line-strong);
  color: var(--fg-dim);
}
.rank--1 { border-color: var(--amber); color: var(--amber); }
.rank--2 { border-color: var(--cyan); color: var(--cyan); }
.rank--3 { border-color: var(--rose); color: var(--rose); }

/* clickable logo + product name, used in the directory and both boards */
.brand-cell {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 3px 6px 3px 3px;
  margin: -3px 0 -3px -3px;
  border: 2px solid transparent;
  color: var(--fg);
}
.brand-cell:hover,
.brand-cell:focus-visible {
  border-color: var(--accent);
  background: var(--bg-panel-2);
  color: var(--fg);
}
.brand-cell:hover .logo-chip,
.brand-cell:focus-visible .logo-chip { border-color: var(--accent); }
.brand-cell:hover b { color: var(--accent); }
/* Sized by its content, capped only for pathologically long names. The floor
   stops the column collapsing to an ellipsis when the table is squeezed. */
.brand-cell__text {
  display: grid;
  gap: 1px;
  min-width: 12ch;
}
.brand-cell__text b,
.brand-cell__text span {
  max-width: 26ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logo-chip {
  width: 30px; height: 30px;
  flex: none;
  display: grid;
  place-items: center;
  border: 2px solid var(--bevel-dark);
  font-family: var(--font-display);
  font-size: calc(11 * var(--fs));
  overflow: hidden;
}
.logo-chip img { width: 100%; height: 100%; object-fit: contain; }

/* ---------------------- how-it-works explainer diagrams ----------------------
   The SVGs carry no colour of their own: every square is a class, and the fill
   comes from the same tokens as the rest of the page, so one set of markup
   works in both themes. Widths are fluid rather than fixed so a diagram never
   forces the prose column to scroll sideways. */
.dgm { margin: 18px 0 24px; }
.dgm__svg {
  display: block;
  width: 100%;
  height: auto;
  background: var(--bg-inset);
  border: var(--px) solid var(--grid-line-strong);
  box-shadow:
    inset 2px 2px 0 var(--bevel-dark),
    inset -2px -2px 0 var(--bevel-light);
}
.dgm__c { stroke: var(--grid-line); stroke-width: 1; }
.dgm__c.is-empty { fill: var(--bg-inset); }
/* Three neutral tints, so two adjacent sold blocks read as two blocks rather
   than one merged mass. Deliberately not accent/rose/amber — those three are
   reserved for "yours", "illegal" and "sealed".
   Mixed against --bg-inset rather than picked from the palette directly: a
   fixed token that separates cleanly from the empty squares in the dark theme
   (--grid-line-strong) lands within a few percent of them in the light one,
   which erased whole blocks. Mixing keeps all three steps a fixed distance
   from whatever the empty square currently is. */
.dgm__c.is-sold-1 { fill: color-mix(in srgb, var(--fg) 34%, var(--bg-inset)); }
.dgm__c.is-sold-2 { fill: color-mix(in srgb, var(--fg) 52%, var(--bg-inset)); }
.dgm__c.is-sold-3 { fill: color-mix(in srgb, var(--fg) 70%, var(--bg-inset)); }
.dgm__c.is-new { fill: var(--accent); }
.dgm__c.is-bad { fill: var(--bad); }
.dgm__c.is-void { fill: var(--amber); }
.dgm__ground { fill: var(--accent); }

.dgm__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}
.dgm__case { min-width: 0; }
/* capped so a four-square diagram does not blow up to half the prose column */
.dgm__pair .dgm__svg { max-width: 220px; }
.dgm__label {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: calc(9 * var(--fs));
  letter-spacing: .06em;
}
.dgm__label--ok { color: var(--ok); }
.dgm__label--bad { color: var(--bad); }

.dgm__cap {
  margin-top: 10px;
  color: var(--fg-dim);
  font-size: calc(12 * var(--fs));
  line-height: 1.55;
}
.dgm__cap b { color: var(--fg); }

.dgm__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin-top: 10px;
  color: var(--fg-dim);
  font-size: calc(12 * var(--fs));
}
.dgm__key { display: inline-flex; align-items: center; gap: 7px; }
.dgm__sw {
  width: 13px;
  height: 13px;
  border: 2px solid var(--grid-line-strong);
  flex: none;
}
.dgm__sw--sold { background: color-mix(in srgb, var(--fg) 52%, var(--bg-inset)); }
.dgm__sw--new { background: var(--accent); }
.dgm__sw--empty { background: var(--bg-inset); }

@media (max-width: 560px) {
  /* side by side stops teaching anything once each case is 120px wide */
  .dgm__pair { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .dgm__pair .dgm__svg { max-width: 200px; }
}

/* ============================== responsive ============================= */

@media (max-width: 1080px) {
  .tower-layout { grid-template-columns: minmax(0, 1fr); }
  .stage { height: 62vh; }
  .buy-layout, .buy-layout--place { grid-template-columns: minmax(0, 1fr); }
  .minimap-wrap { display: none; }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 20px; }
}

@media (max-width: 720px) {
  :root { --header-h: 56px; }
  .nav { display: none; }
  .topbar__price b { font-size: calc(17 * var(--fs)); }
  .stage__overlay { padding: 6px; }
  .stage__row { flex-wrap: wrap; }
  .search { width: 100%; }
  .toolbar { flex-wrap: wrap; }
  /* wide records tables scroll inside their panel instead of the page */
  .wrap, .wrap--wide { padding-left: 10px; padding-right: 10px; }
  .panel { overflow-x: auto; }
  /* size to content and scroll inside the panel, rather than squeezing
     columns until the product names become ellipses */
  .table { font-size: calc(12 * var(--fs)); width: max-content; min-width: 100%; }
  .table th { font-size: calc(9 * var(--fs)); }
  .table th, .table td { white-space: nowrap; }
  .modal__foot .btn { flex: 1; }
  h1 { font-size: calc(15 * var(--fs)); }
  h2 { font-size: calc(12 * var(--fs)); }
  .stat__v { font-size: calc(21 * var(--fs)); }
  .designer-cell { width: 22px; height: 22px; }
  .mobile-hint { display: block; }
  .footer__grid { grid-template-columns: 1fr; gap: 18px; padding-bottom: 14px; }
  /* the temporary font picker lives in the footer on small screens, so the
     topbar keeps room for the wordmark and the live price */
  .topbar { gap: 8px; padding: 0 10px; }
  .brand { font-size: calc(11 * var(--fs)); gap: 6px; }
  .brand__mark { height: 18px; }
  .topbar__price { padding: 4px 7px; }
  .topbar__price span { display: none; }
  .theme-toggle { width: 34px; height: 34px; }
}

.mobile-hint { display: none; }
