/* ============================================================
   YMRTECH — PROBE THEME  (the single source of truth)
   ============================================================
   The visual language of https://ymrtech.com/account/speed-test,
   generalised into one flat stylesheet that every surface uses:
   the public site, the client portal (/account, /install, /account/*)
   and the operator console (/admin).

   RULES FOR EVERYONE WHO TOUCHES A PAGE:

     1. Never write a colour literal in a page. Use var(--…). The only
        hex values in the whole estate live in the :root block below.
     2. Spacing/radius/type scale come from the tokens too (--r, --gap,
        --wrap). If a page needs a new value, add it HERE, not inline.
     3. A page may add layout rules (grids, widths, page-specific bits)
        in its own <style>, but the palette, the card/pill/table/terminal
        components and the header/footer chrome come from this file.
     4. Keep a copy of this file in the clientsv repo byte-identical to
        the one in the ymrtech site repo (internal/api/static/theme.css
        vs assets/css/theme.css) — it is duplicated on purpose: the
        portal must render with the marketing site down.

   The palette is the tunnel-probe palette: near-black ground, one
   signal green, one cyan for links/accents, amber for warnings, red for
   errors, and a desaturated teal-grey for body text. The whole page is
   monospace; headings are small, uppercase and letter-spaced so the
   content — not the chrome — has the weight.
   ============================================================ */

:root {
  /* ── surface ─────────────────────────────────────────────── */
  --bg:        #04070b;   /* page ground */
  --bg-glow:   #0c2230;   /* the radial wash behind the header */
  --panel:     #0a1017;   /* cards, terminal blocks */
  --panel2:    #0d151d;   /* inputs, inner tiles, table stripes */
  --line:      #16333c;   /* every border, every rule */
  --line-hot:  #1d4a3a;   /* border on hover / of a live element */

  /* ── signal ──────────────────────────────────────────────── */
  --green:     #2bff88;   /* the one bright colour: values, ok, brand */
  --green-dim: #127a48;   /* green at rest: rails, borders, dim bars */
  --cyan:      #35e6ff;   /* links, section headings, live readouts */
  --amber:     #ffb454;   /* warnings, peak, pending */
  --red:       #ff5f6d;   /* errors, revoked, failures */

  /* ── text ────────────────────────────────────────────────── */
  --text:      #cfe9e4;   /* body */
  --muted:     #6b8794;   /* secondary, labels, meta */

  /* ── derived signal fills (kept here, never inline) ──────── */
  --green-fill: #08170f;  /* primary button ground */
  --green-hi:   #8affc4;  /* the lighter green the wire canvas paints its live glyphs */
  --amber-fill: #1c1408;  /* warn note ground */
  --amber-line: #4a3a12;  /* warn note border */
  --red-fill:   #1d0b0e;  /* error note ground */
  --cyan-fill:  #07171d;  /* info note ground */
  --hover:      rgba(43, 255, 136, .06);
  --overlay:    rgba(0, 0, 0, .75);  /* modal scrim (the QR sheet) */
  --on-light:   #ffffff;  /* the light ground a QR code needs to be scannable */
  --scan:       rgba(0, 0, 0, .22);    /* the CRT veil */
  --glow-c:     rgba(43, 255, 136, .25);

  /* ── geometry & type ─────────────────────────────────────── */
  --mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", Menlo, Consolas,
          "Liberation Mono", monospace;
  --wrap: 940px;          /* the reading column, everywhere */
  --r: 8px;               /* card/panel radius */
  --r-sm: 6px;            /* control radius */
  --gap: 1rem;
  --fs: 14px;
  --fs-sm: .82rem;
  --fs-xs: .72rem;
  --glow: 0 0 6px var(--glow-c);
}

/* ── light ground ─────────────────────────────────────────────────
   The probe look on white paper: the same skeleton, the same monospace,
   the same small uppercase letter-spaced headings — only the ground and
   the ink invert, and every signal colour is darkened so it holds its
   contrast on white instead of glowing. --on-light stays #ffffff in both
   schemes: a QR code needs a white ground to be scannable.

   Mechanism: two explicit token sets, selected by (a) the OS preference
   via @media (prefers-color-scheme: light), and (b) the data-theme the
   switch pins. Deliberately not a feature-query-guarded colour function:
   that is unavailable on phones and tablets a couple of years old, and an
   engine that skips it keeps the dark palette for everyone who asked for
   light, on every page, however often the switch is tapped. Plain media
   queries and attribute selectors work everywhere, scripting or not.
   The two light blocks below are identical — the theme gate compares
   them, and fails if they ever drift apart. */

/* 1. the OS asked for light and nothing is pinned */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --bg:         #f7f9fb;
    --bg-glow:    #e3edf4;
    --panel:      #ffffff;
    --panel2:     #f1f5f8;
    --line:       #d6e0e6;
    --line-hot:   #8fc4aa;
    --green:      #0b7a45;
    --green-dim:  #7dad95;
    --green-hi:   #14955a;
    --cyan:       #0a7391;
    --amber:      #8f5b00;
    --red:        #bf2a39;
    --text:       #26343a;
    --muted:      #5d6e76;
    --green-fill: #e7f5ed;
    --amber-fill: #fdf4e2;
    --amber-line: #e9d5a6;
    --red-fill:   #fdecee;
    --cyan-fill:  #e7f4f9;
    --hover:      rgba(11, 122, 69, .07);
    --overlay:    rgba(24, 44, 54, .55);
    --scan:       rgba(24, 44, 54, .05);
    --glow-c:     rgba(11, 122, 69, .18);
  }
}

/* 2. an explicit choice: light. (The dark pin needs no token block — the
   :root set above is already dark; it only re-declares color-scheme.) */
:root[data-theme="light"] {
  color-scheme: light;
  --bg:         #f7f9fb;
  --bg-glow:    #e3edf4;
  --panel:      #ffffff;
  --panel2:     #f1f5f8;
  --line:       #d6e0e6;
  --line-hot:   #8fc4aa;
  --green:      #0b7a45;
  --green-dim:  #7dad95;
  --green-hi:   #14955a;
  --cyan:       #0a7391;
  --amber:      #8f5b00;
  --red:        #bf2a39;
  --text:       #26343a;
  --muted:      #5d6e76;
  --green-fill: #e7f5ed;
  --amber-fill: #fdf4e2;
  --amber-line: #e9d5a6;
  --red-fill:   #fdecee;
  --cyan-fill:  #e7f4f9;
  --hover:      rgba(11, 122, 69, .07);
  --overlay:    rgba(24, 44, 54, .55);
  --scan:       rgba(24, 44, 54, .05);
  --glow-c:     rgba(11, 122, 69, .18);
}

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

html { color-scheme: light dark; -webkit-text-size-adjust: 100%; }

/* An explicit choice beats the OS preference. data-theme is written before
   first paint by the inline one-liner in each page's <head> (no flash of
   the wrong theme) and thereafter by the .theme-toggle switch; the choice
   lives in localStorage under "ymr-theme", and its absence means "follow
   the OS", which is also the default for a first-time visitor. */
:root[data-theme="dark"]  { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

body {
  margin: 0;
  background: var(--bg);
  background-image: radial-gradient(1200px 500px at 50% -180px, var(--bg-glow) 0%, transparent 70%);
  background-repeat: no-repeat;
  color: var(--text);
  font: var(--fs)/1.55 var(--mono);
  overflow-x: hidden;
}

a { color: var(--cyan); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* the fixed CRT scanline veil — one div, .scan, first child of body.
   Multiply blending keeps it a texture, not a layer of grey. */
.scan {
  position: fixed; inset: 0; pointer-events: none; z-index: 9;
  background: repeating-linear-gradient(180deg, var(--scan) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply;
}
@media (prefers-reduced-motion: reduce) { .scan { display: none; } }

/* ── layout ──────────────────────────────────────────────────── */
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 1.4rem 1rem 4rem; }
.container { max-width: 1100px; margin: 0 auto; padding: 0 1rem; }
.section { padding: 2rem 0; }
.stack { display: grid; gap: var(--gap); }
.row { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.sep { color: var(--line); }

/* ── headings: small, uppercase, letter-spaced ───────────────── */
h1, h2, h3, h4 {
  margin: 0 0 .6rem;
  font-weight: 400;
  letter-spacing: .18em;
  text-transform: uppercase;
  line-height: 1.3;
}
h1 { font-size: 1.05rem; color: var(--green); }
h2 { font-size: .78rem; color: var(--cyan); margin-bottom: .7rem; }
h3 { font-size: .78rem; color: var(--cyan); letter-spacing: .14em; }
h4 { font-size: var(--fs-sm); color: var(--muted); letter-spacing: .12em; }
h1 .cur {                      /* the blinking caret after a page title */
  display: inline-block; width: .6ch; background: var(--green);
  animation: b 1.05s steps(1) infinite;
}
@keyframes b { 50% { opacity: 0 } }
@media (prefers-reduced-motion: reduce) { h1 .cur { animation: none } }

.sub { color: var(--muted); font-size: var(--fs-sm); margin: .35rem 0 1.1rem; }

p { margin: .6rem 0; }
ul, ol { padding-left: 1.3rem; }
li { margin: .25rem 0; }
hr { border: 0; border-top: 1px solid var(--line); margin: 1.4rem 0; }

/* muted / dim / comment text */
.muted, .dim { color: var(--muted); }
.dim { color: var(--green-dim); }
.comment { color: var(--muted); font-style: italic; }
.accent { color: var(--cyan); }
.text-secondary { color: var(--muted); }
.small { font-size: var(--fs-sm); }
.color-success { color: var(--green); }
.color-info    { color: var(--cyan); }
.color-warning { color: var(--amber); }
.color-error   { color: var(--red); }
.color-git     { color: var(--muted); }

code, kbd, samp {
  font: inherit; color: var(--green); background: var(--panel2);
  border: 1px solid var(--line); border-radius: 4px; padding: 0 .3rem;
}
pre {
  font: 12.5px/1.6 var(--mono); color: var(--text); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r); padding: .8rem 1rem;
  overflow-x: auto; margin: .8rem 0;
}
pre code { border: 0; background: none; padding: 0; color: inherit; }

blockquote {
  margin: .9rem 0; padding: .1rem 1rem; color: var(--muted);
  border-left: 2px solid var(--line);
}

/* ── cards ───────────────────────────────────────────────────── */
.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1rem; margin: 0 0 1rem;
}
.card > h2, .card > .card-title { font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: var(--cyan); margin: 0 0 .7rem; }
.card-header {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  border-bottom: 1px solid var(--line); padding-bottom: .5rem; margin: -.25rem 0 .8rem;
}
.card-body > :first-child { margin-top: 0 }
.card-body > :last-child { margin-bottom: 0 }
.card-text { color: var(--text); font-size: var(--fs-sm); }
.card-actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .7rem; }
.card.warnbox, .warnbox { border-color: var(--amber-line); }
.card.badbox, .badbox { border-color: var(--red); }

/* ── controls ────────────────────────────────────────────────── */
button, .btn, input[type="submit"] {
  font: inherit; background: transparent; color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .5rem .9rem; cursor: pointer; display: inline-block;
}
button:hover:not(:disabled), .btn:hover { border-color: var(--green); color: var(--green); text-decoration: none; }
button.primary, .btn.primary {
  border-color: var(--green-dim); color: var(--green); background: var(--green-fill);
}
.btn-cyan { border-color: var(--line); color: var(--cyan); }
.btn-cyan:hover { border-color: var(--cyan); color: var(--cyan); }
button:disabled { opacity: .4; cursor: not-allowed; }

/* ── the theme switch ─────────────────────────────────────────────
   One control on every surface: the public site's header, the portal
   topbar, the console bar. A pen-drawn half-disc rather than an icon
   glyph — the same trick as the hamburger, so the Nerd font subset never
   needs regenerating — the live scheme spelled out, and a 44px hit area
   that works with a thumb. It is never inside the collapsing mobile menu:
   it stays in the bar, next to the hamburger.

   The label names the scheme you are IN, not the one a tap would give
   you, and aria-pressed is true when light is on. Shift-click (desktop)
   or long-press (mobile) clears the pinned choice and hands the decision
   back to the OS — see theme.js, which is the only code that writes
   data-theme. */
.theme-toggle {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 44px; padding: .4rem .65rem;
  background: var(--panel2); border: 1px solid var(--line);
  border-radius: var(--r-sm); color: var(--muted);
  font: inherit; font-size: var(--fs-xs); line-height: 1;
  text-transform: uppercase; letter-spacing: .12em;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.theme-toggle:hover, .theme-toggle:active { border-color: var(--green-dim); color: var(--text); }
.theme-toggle:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.theme-toggle .ico {
  width: 14px; height: 14px; flex: none; border-radius: 50%;
  border: 1.5px solid currentColor;
  background: linear-gradient(90deg, currentColor 0 50%, transparent 50%);
}
.theme-toggle[aria-pressed="true"] .ico {
  background: linear-gradient(90deg, transparent 0 50%, currentColor 50%);
}
/* the same switch folded into a status line or a footer: no chrome, it
   inherits the colour and the type around it */
.theme-toggle.bare {
  min-height: 0; padding: 0; background: none; border: 0;
  color: inherit; letter-spacing: inherit; font-size: inherit;
  text-decoration: underline; text-underline-offset: 2px; text-decoration-style: dotted;
}
.theme-toggle.bare .ico { width: 11px; height: 11px; border-width: 1px; }
/* a phone keeps the switch, drops the word — the header one only: the bare
   variant folded into a status line has no room to shrink into a lone disc */
@media (max-width: 520px) {
  .theme-toggle:not(.bare) .txt { display: none; }
  .theme-toggle:not(.bare) { min-width: 44px; justify-content: center; }
  .theme-toggle:not(.bare) .ico { width: 17px; height: 17px; }
}

select, input, textarea, .form-control, .form-select {
  font: inherit; background: var(--panel2); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: .45rem .6rem;
}
input:focus, select:focus, textarea:focus, .form-control:focus {
  outline: none; border-color: var(--green-dim);
}
.form-group { margin: .55rem 0 }
.form-label { display: block; color: var(--muted); font-size: var(--fs-xs); letter-spacing: .12em; text-transform: uppercase; margin-bottom: .25rem; }
.form-check-input { accent-color: var(--green); }

/* ── pills / badges / tags ───────────────────────────────────── */
.pill {
  display: inline-block; padding: .05rem .45rem; border: 1px solid var(--line);
  border-radius: 999px; font-size: var(--fs-xs); color: var(--muted);
  letter-spacing: .04em; white-space: nowrap;
}
.pill.on, .pill.ok, .pill.active { border-color: var(--green-dim); color: var(--green); }
.pill.off, .pill.warn, .pill.busy, .pill.retry { border-color: var(--amber-line); color: var(--amber); }
.pill.failed, .pill.err, .pill.revoked { border-color: var(--line); color: var(--red); }
.pill.pipe { color: var(--cyan) }
.pill.privacy, .pill.tier-privacy { color: var(--green); border-color: var(--green-dim); }
.pill.security, .pill.tier-security { color: var(--cyan); border-color: var(--line); }
.pill.tier, .pill.none { color: var(--muted) }
.tag { display: inline-block; font-size: var(--fs-xs); color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: .05rem .5rem; margin-right: .3rem; }
.module-badge { display: inline-block; font-size: var(--fs-xs); padding: .1rem .5rem; border: 1px solid var(--line); border-radius: 999px; color: var(--muted); }
.module-badge.success { color: var(--green); border-color: var(--green-dim); }

/* ── tables ──────────────────────────────────────────────────── */
.tblwrap { overflow-x: auto }
table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin: .6rem 0; }
th, td { text-align: left; padding: .42rem .5rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th {
  color: var(--muted); font-weight: 400; font-size: var(--fs-xs);
  letter-spacing: .12em; text-transform: uppercase; white-space: nowrap;
}
td { white-space: nowrap }
td.wrap, th.wrap { white-space: normal }
tbody tr:hover { background: var(--hover) }

/* ── key/value grids (portal + console) ──────────────────────── */
.kv { display: grid; grid-template-columns: 9rem 1fr; gap: .15rem .75rem; font-size: .92rem; margin: .5rem 0; }
.kv span:nth-child(odd), .kv dt { color: var(--muted) }
.kv dd { margin: 0 }

/* the readout tiles: label / big value / unit (the probe's "result" row) */
.big { display: grid; grid-template-columns: repeat(3, 1fr); gap: .7rem; }
.big > div { border: 1px solid var(--line); border-radius: var(--r); padding: .7rem; background: var(--panel2); }
.big .k, .stat-label { font-size: var(--fs-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.big .v, .stat-value { font-size: 1.55rem; color: var(--green); margin-top: .25rem; }
.big .u { font-size: var(--fs-xs); color: var(--muted); }
.stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .7rem; margin: 1rem 0; }
.stat-box { border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); padding: .8rem; text-align: center; }
.stat-box .stat-value { display: block; font-size: 1.3rem; line-height: 1.2; }
.stat-box .stat-label { display: block; margin-top: .25rem; }
.verdict { margin-top: .8rem; font-size: var(--fs-sm); color: var(--cyan) }
.verdict.warn, .verdict.unk { color: var(--amber) }
.err, .error { color: var(--red); font-size: var(--fs-sm); min-height: 1.2em; margin: .25rem 0 }
.note {
  border: 1px solid var(--line); border-left: 2px solid var(--cyan);
  border-radius: var(--r-sm); background: var(--panel2);
  padding: .55rem .8rem; margin: .7rem 0; font-size: var(--fs-sm); color: var(--muted);
}
.note.warn { border-left-color: var(--amber); background: var(--amber-fill); border-color: var(--amber-line) }
.note.err  { border-left-color: var(--red);   background: var(--red-fill); border-color: var(--red) }
/* a verdict as a boxed panel — the DNS leak test's result, distinct from the
   one-line .verdict that sits under a result card */
.verdictbox { border: 1px solid var(--line); border-radius: var(--r); padding: 1rem 1.1rem; margin: 1rem 0; background: var(--panel) }
.verdictbox h2 { margin: 0 0 .35rem }
.verdictbox.ok  { border-color: var(--green-dim); background: var(--green-fill) }
.verdictbox.bad { border-color: var(--amber-line); background: var(--amber-fill) }
.verdictbox.unk { border-color: var(--line); background: var(--panel) }
.pill.parked { font-size: var(--fs-xs); color: var(--muted) }
.err.ok { color: var(--green) }
.livebox { border-top: 1px dashed var(--line); margin-top: .6rem; padding-top: .4rem }
.rulelist { list-style: none; padding: 0; margin: .5rem 0 }
.rulelist li { border-bottom: 1px solid var(--line); padding: .35rem 0; font-size: 12.5px }
.hidden { display: none !important }

/* ── terminal blocks (log panes, command lists) ──────────────── */
.terminal, .terminal-window, .term {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; margin: .9rem 0;
}
.terminal-header {
  display: flex; align-items: center; gap: .4rem; padding: .4rem .7rem;
  border-bottom: 1px solid var(--line); background: var(--panel2);
}
.terminal-title { font-size: var(--fs-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-left: .3rem }
.terminal-dot { width: .55rem; height: .55rem; border-radius: 50%; background: var(--line) }
.terminal-dot.green  { background: var(--green-dim) }
.terminal-dot.yellow { background: var(--amber) }
.terminal-dot.red    { background: var(--red) }
.terminal-body, .tui {
  padding: .7rem .9rem; white-space: pre; overflow-x: auto; margin: 0;
  font: 12.5px/1.6 var(--mono); color: var(--green);
}
.terminal-body .dim, .tui .dim { color: var(--green-dim) }
.terminal-body .vel, .tui .vel { color: var(--cyan) }
.terminal-body .peak, .tui .peak { color: var(--amber) }
.terminal-body .err, .terminal-body .errline { color: var(--red) }
.terminal-line { font-size: 12.8px; line-height: 1.7; color: var(--text); white-space: pre-wrap }
.terminal-line .ok { color: var(--green) }
.terminal-line .warn { color: var(--amber) }
.terminal-line .err { color: var(--red) }
.terminal-line .t { color: var(--muted) }
.log { white-space: pre-wrap; word-break: break-word; max-height: 220px; overflow: auto; font-size: 12.5px }
.log .t { color: var(--muted) } .log .ok { color: var(--green) }
.log .warn { color: var(--amber) } .log .err { color: var(--red) }

/* shell prompt lines (site hero + guides) */
.prompt-line { font-size: 12.8px; line-height: 1.8; white-space: pre-wrap }
.prompt { color: var(--green) }
.cmd { color: var(--text) }
.output { color: var(--muted) }
.output.accent { color: var(--cyan) }

/* ── tiers (portal chooser) ──────────────────────────────────── */
.tiercards { display: grid; gap: .5rem; margin: .6rem 0 .25rem }
.tiercard {
  display: flex; gap: .6rem; align-items: flex-start; border: 1px solid var(--line);
  border-radius: var(--r); padding: .55rem .75rem; cursor: pointer;
  background: var(--panel2); margin: 0;
}
.tiercard:hover { border-color: var(--line-hot) }
.tiercard:has(input:checked) { border-color: var(--green-dim); background: var(--green-fill) }
.tiercard input { width: auto; margin: .3rem 0 0; flex: none }
.tiercard .tname { color: var(--text) }
.tiercard .thelp { display: block; color: var(--muted); font-size: .8rem }

/* ── tabs / nav ──────────────────────────────────────────────── */
.tabs { display: flex; gap: .2rem; border-bottom: 1px solid var(--line); margin: 0 0 1rem; flex-wrap: wrap }
.tab, .tabs a, .nav-link {
  color: var(--muted); font-size: var(--fs-sm); padding: .4rem .7rem;
  border: 1px solid transparent; border-bottom: 0; border-radius: var(--r-sm) var(--r-sm) 0 0;
}
.tab:hover, .tabs a:hover, .nav-link:hover { color: var(--green); text-decoration: none }
.tab.active, .tabs a.active, .nav-link.active { color: var(--green); border-color: var(--line); background: var(--panel) }

/* site chrome: header bar, footer, status line, portal topbar */
.site-header, .topbar {
  border-bottom: 1px solid var(--line); background: var(--panel);
  padding: .5rem 0; margin-bottom: 1.6rem;
}
.site-header .container, .topbar-inner { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.brand, .navbar-brand, .topbar-brand { color: var(--text); font-size: var(--fs-sm); letter-spacing: .06em; text-decoration: none }
.brand:hover, .topbar-brand:hover { color: var(--green); text-decoration: none }
.site-nav, .topbar-links, .navbar-links { display: flex; flex-wrap: wrap; gap: .1rem; margin-left: auto; align-items: center }
/* a page-top row for a surface with no bar of its own (the portal's
   sub-pages): something on the left, the theme switch on the right. */
.pagebar { display: flex; align-items: center; gap: 1rem; margin: 0 0 1.25rem }
.pagebar p { margin: 0 }
.pagebar .theme-toggle { margin-left: auto }

.topbar-link, .topbar-cta, .nav-cta {
  color: var(--muted); font-size: var(--fs-sm); padding: .3rem .6rem;
  border: 1px solid transparent; border-radius: var(--r-sm);
}
.topbar-link:hover, .nav-cta:hover { color: var(--green); border-color: var(--line); text-decoration: none }
.topbar-link.active, .nav-link.active { color: var(--green) }
.nav-cta, .topbar-cta { color: var(--green); border-color: var(--green-dim) }
.topbar-user { color: var(--muted); font-size: var(--fs-xs) }
.topbar-auth { display: flex; gap: .4rem; align-items: center; margin-left: .5rem }

.site-footer, .footer {
  border-top: 1px solid var(--line); margin-top: 3rem; padding: 1.2rem 0 1.6rem;
  color: var(--muted); font-size: var(--fs-xs); text-align: center;
}
.site-footer a, .footer a { color: var(--muted) }
.site-footer a:hover, .footer a:hover { color: var(--green); text-decoration: none }

.status-bar {
  display: flex; gap: 1rem; justify-content: space-between; flex-wrap: wrap;
  border-top: 1px solid var(--line); background: var(--panel);
  padding: .3rem .8rem; font-size: var(--fs-xs); color: var(--muted);
  position: sticky; bottom: 0;
}

/* ── page furniture ──────────────────────────────────────────── */
.page-header, .post-header { margin: 0 0 1rem; }
.page-title, .post-title { font-size: 1.05rem; letter-spacing: .18em; text-transform: uppercase; color: var(--green); margin: 0 }
.post-meta, .post-tags { color: var(--muted); font-size: var(--fs-xs); margin-top: .3rem }
.cta-section {
  border: 1px solid var(--line); border-left: 2px solid var(--green-dim);
  border-radius: var(--r); background: var(--panel); padding: 1rem 1.1rem; margin: 2rem 0;
}
.cta-title { font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: var(--cyan); margin: 0 0 .4rem }
.cta-text { color: var(--muted); font-size: var(--fs-sm); margin: 0 0 .8rem }
.ascii-banner { color: var(--green-dim); font-size: 12px; line-height: 1.1; margin: 0 0 1rem; overflow-x: auto; white-space: pre }
.marquee-container { display: none }

/* ── misc ────────────────────────────────────────────────────── */
details {
  border: 1px solid var(--line); border-radius: var(--r); padding: .6rem .8rem;
  background: var(--panel); margin: 1rem 0;
}
summary { cursor: pointer; color: var(--cyan); font-size: .8rem; letter-spacing: .1em; text-transform: uppercase }
summary:hover { color: var(--green) }
details p, details li { font-size: var(--fs-sm); color: var(--muted) }
.spinner {
  display: inline-block; width: .85em; height: .85em; border: 2px solid var(--amber);
  border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite;
  vertical-align: -2px; margin-right: .35rem;
}
@keyframes spin { to { transform: rotate(360deg) } }
canvas.wire, #wire {
  display: block; width: 100%; height: 200px; border: 1px solid var(--line);
  border-radius: var(--r); image-rendering: pixelated;
  background: radial-gradient(700px 160px at 50% 50%, var(--bg-glow) 0%, var(--bg) 75%);
}
.actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center }
.devhead { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap }
.flash { animation: flash 1s ease-out 1 }
@keyframes flash { from { background: var(--green-fill) } to { background: var(--panel) } }

@media (max-width: 620px) {
  .big { grid-template-columns: 1fr }
  .kv { grid-template-columns: 1fr; gap: 0 }
  .kv span:nth-child(odd) { margin-top: .4rem }
  canvas.wire, #wire { height: 170px }
}