/* =====================================================================
   MycoCap - forest-floor pixel UI
   Tokens, components and page furniture. Plain CSS, no build step.
   One loud effect per view: a spore glow, a CRT field, or a terminal.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. TOKENS
   --------------------------------------------------------------------- */
:root {
  /* ===================================================================
     LIGHT is the base palette. These values apply with no data-theme
     attribute at all, so a first-time visitor - and a visitor with no
     JavaScript - gets the light theme. Forest and Brown are override
     blocks further down, placed after :root, so they win on equal
     specificity whenever their attribute is present.
     =================================================================== */

  --bg-void:     #f0eade;
  --bg-dark:     #faf6ea;
  --surface:     #fffdf7;
  --surface-2:   #f1ebdc;
  --border:      #c8bda3;
  --border-hi:   #a2947a;
  --ink-900:     #2a3a2f;
  --alt-bg:      rgba(216, 206, 184, 0.55);
  --head-bg:     rgba(240, 234, 222, 0.96);
  --film-bg:     rgba(216, 206, 184, 0.5);
  --bar-grad:    linear-gradient(90deg, #ded4bd, #cec2a6);

  --spore:       #0f6335;
  --spore-deep:  #42c273;
  --spore-dim:   #6fae86;
  --spore-edge:  #1c7a45;
  --spore-on:    #04240f;
  --lantern:     #ffb84d;
  --lantern-text:#8a5410;
  --lantern-dim: #8a5410;
  --lantern-on:  #2a1600;
  /* Support CTA label. A notch darker than --lantern-text because it is read
     on the warm tinted surface, not on the page: 5.7:1 there, 6.1:1 on the
     page itself. */
  --support-fg:  #6f4409;
  --rust:        #c0432f;
  --rust-text:   #a8331f;
  --rust-dim:    #8f3324;
  --rust-on:     #ffffff;
  --info:        #1f6f9c;
  --info-text:   #1a5f85;
  --info-dim:    #7ba9c4;
  --info-on:     #ffffff;

  --text:        #1c2a20;
  --text-2:      #41544a;
  --text-muted:  #4d5e53;   /* darkened: muted body text sits on the tinted alt band */

  --glow-rgb:    31, 143, 77;
  --lantern-rgb: 196, 133, 40;
  --glow-soft:   0.03;
  --glow-mid:    0.07;
  --glow-ring:   0.12;
  --glow-strong: 0.16;
  --scan:        0.035;
  --myco: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='540' height='400' viewBox='0 0 540 400'%3E%3Cg fill='none' stroke='%231f6b45' stroke-opacity='.1' stroke-width='2'%3E%3Cpath d='M-20 60H80l60 60v80l80 80v100l80 60'/%3E%3Cpath d='M80 60V0'/%3E%3Cpath d='M140 200H60l-40 40'/%3E%3Cpath d='M220 280h120l60-60h160'/%3E%3Cpath d='M400 220V120l60-60h100'/%3E%3Cpath d='M400 120l-60-60V-20'/%3E%3Cpath d='M220 380h120l60-40'/%3E%3Cpath d='M-20 320h80l60-60'/%3E%3Cpath d='M460 60V-20'/%3E%3Cpath d='M120 260v120h60'/%3E%3Cpath d='M560 340h-80v60'/%3E%3Cpath d='M300 440v-60'/%3E%3C/g%3E%3Cg fill='%231f6b45' fill-opacity='.13'%3E%3Ccircle cx='80' cy='60' r='2.5'/%3E%3Ccircle cx='140' cy='200' r='2.5'/%3E%3Ccircle cx='220' cy='280' r='2.5'/%3E%3Ccircle cx='400' cy='220' r='2.5'/%3E%3Ccircle cx='400' cy='120' r='2.5'/%3E%3Ccircle cx='120' cy='260' r='2.5'/%3E%3Ccircle cx='460' cy='60' r='2.5'/%3E%3Ccircle cx='340' cy='380' r='2.5'/%3E%3Ccircle cx='60' cy='320' r='2.5'/%3E%3Ccircle cx='220' cy='380' r='2.5'/%3E%3C/g%3E%3C/svg%3E");
  --focus-ring:  #8a5410;
  --focus-halo:  rgba(138, 84, 16, 0.2);
  --hero-shadow:
    0 2px 0 rgba(255, 255, 255, 0.85),
    0 0 14px rgba(31, 143, 77, 0.18);

  --slot-bg:       #1e2a23;
  --slot-rgb:      124, 255, 178;
  --slot-fg:       #7cffb2;
  --slot-dim:      #8fa79a;
  --slot-sprocket: rgba(30, 42, 35, 0.85);
  --cart-label-grad: linear-gradient(90deg, #ffc766, #d99a2e);
  --cart-label-fg:   #2a1600;

  /* --- lightbox: the veil behind it + the dark mat the shot sits on --- */
  --lb-scrim:    rgba(16, 24, 20, 0.84);
  --lb-mat:      #202723;

  --term-bg:     #1a231d;
  --term-bar:    #253029;
  --term-border: #3d5245;
  --term-edge:   #4a6353;
  --term-text:   #d7e3da;
  --term-out:    #9aada2;
  --term-prompt: #ffc266;
  --term-ok:     #7ce0a0;
  --term-flag:   #7cc6f0;

/* --- type --- */
  --font-display: 'Press Start 2P', 'Courier New', ui-monospace, monospace;
  --font-body:    'Pixelify Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono:    'IBM Plex Mono', Consolas, 'Courier New', ui-monospace, monospace;

  /* --- 4px grid --- */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

  --page: 1120px;
  --head-h: 68px;
}

/* =====================================================================
   BROWN - warm woodland / bolete: bark, honey and cream
   ===================================================================== */
[data-theme="brown"] {
  --bg-void:     #1c120b;
  --bg-dark:     #26180f;
  --surface:     #332114;
  --surface-2:   #3e2a19;
  --border:      #4a3320;
  --border-hi:   #6d4a28;
  --ink-900:     #120a05;
  --alt-bg:      rgba(38, 24, 15, 0.62);
  --head-bg:     rgba(28, 18, 11, 0.95);
  --film-bg:     rgba(38, 24, 15, 0.5);
  --bar-grad:    linear-gradient(90deg, #5a3a1c, #3f2812);

  --spore:       #edc98d;
  --spore-deep:  #d29a34;
  --spore-dim:   #8a6320;
  --spore-edge:  #a8762a;
  --spore-on:    #1b1006;
  --lantern:     #ffb84d;
  --lantern-text:#ffb84d;
  --lantern-dim: #a86f1f;
  --lantern-on:  #2a1600;
  --support-fg:  #ffb84d;   /* 7.3:1 on the support tint */
  --rust:        #e0705a;
  --rust-text:   #ff9d86;
  --rust-dim:    #8a3a28;
  --rust-on:     #1b0d08;
  --info:        #c2c47a;
  --info-text:   #d3d595;
  --info-dim:    #8a8c4a;
  --info-on:     #16170a;

  --text:        #f3e6d2;
  --text-2:      #c9b498;
  --text-muted:  #a08c72;

  --glow-rgb:    255, 190, 110;
  --lantern-rgb: 210, 154, 52;
  --glow-soft:   0.022;
  --glow-mid:    0.13;
  --glow-ring:   0.18;
  --glow-strong: 0.32;
  --scan:        0.055;
  --myco: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='540' height='400' viewBox='0 0 540 400'%3E%3Cg fill='none' stroke='%23ffbe6e' stroke-opacity='.14' stroke-width='2'%3E%3Cpath d='M-20 60H80l60 60v80l80 80v100l80 60'/%3E%3Cpath d='M80 60V0'/%3E%3Cpath d='M140 200H60l-40 40'/%3E%3Cpath d='M220 280h120l60-60h160'/%3E%3Cpath d='M400 220V120l60-60h100'/%3E%3Cpath d='M400 120l-60-60V-20'/%3E%3Cpath d='M220 380h120l60-40'/%3E%3Cpath d='M-20 320h80l60-60'/%3E%3Cpath d='M460 60V-20'/%3E%3Cpath d='M120 260v120h60'/%3E%3Cpath d='M560 340h-80v60'/%3E%3Cpath d='M300 440v-60'/%3E%3C/g%3E%3Cg fill='%23ffbe6e' fill-opacity='.22'%3E%3Ccircle cx='80' cy='60' r='2.5'/%3E%3Ccircle cx='140' cy='200' r='2.5'/%3E%3Ccircle cx='220' cy='280' r='2.5'/%3E%3Ccircle cx='400' cy='220' r='2.5'/%3E%3Ccircle cx='400' cy='120' r='2.5'/%3E%3Ccircle cx='120' cy='260' r='2.5'/%3E%3Ccircle cx='460' cy='60' r='2.5'/%3E%3Ccircle cx='340' cy='380' r='2.5'/%3E%3Ccircle cx='60' cy='320' r='2.5'/%3E%3Ccircle cx='220' cy='380' r='2.5'/%3E%3C/g%3E%3C/svg%3E");
  --focus-ring:  #ffcf7a;
  --focus-halo:  rgba(255, 207, 122, 0.18);
  --hero-shadow:
    0 0 6px rgba(237, 201, 141, 0.62),
    0 0 18px rgba(210, 154, 52, 0.4),
    0 0 40px rgba(210, 154, 52, 0.24);

  --slot-bg:       #150e07;
  --slot-rgb:      237, 201, 141;
  --slot-fg:       #edc98d;
  --slot-dim:      #a08c72;
  --slot-sprocket: rgba(21, 14, 7, 0.85);
  --cart-label-grad: linear-gradient(90deg, #e8b05e, #b5842e);
  --cart-label-fg:   #2a1600;

  --lb-scrim:    rgba(9, 5, 2, 0.88);
  --lb-mat:      #241a13;

  --term-bg:     #150e07;
  --term-bar:    #26180f;
  --term-border: #4a3320;
  --term-edge:   #6d4a28;
  --term-text:   #f3e6d2;
  --term-out:    #a08c72;
  --term-prompt: #ffb84d;
  --term-ok:     #edc98d;
  --term-flag:   #d3d595;
}

/* =====================================================================
   FOREST - deep forest night: spore glow on the damp forest floor
   ===================================================================== */
[data-theme="forest"] {
  /* --- surfaces (deep forest night) --- */
  --bg-void:     #0b1410;
  --bg-dark:     #101f18;
  --surface:     #16291f;
  --surface-2:   #1b3327;
  --border:      #2c4636;
  --border-hi:   #3d6049;
  --ink-900:     #060d09;
  --alt-bg:      rgba(16, 31, 24, 0.62);
  --head-bg:     rgba(11, 20, 16, 0.95);
  --film-bg:     rgba(16, 31, 24, 0.5);
  --bar-grad:    linear-gradient(90deg, #12603a, #0d3f24);

  /* --- accents --- */
  --spore:       #7cffb2;   /* accent ink: links, active, glow */
  --spore-deep:  #3ef07a;   /* primary fills */
  --spore-dim:   #1f8f4d;   /* accent borders */
  --spore-edge:  #1c9b52;   /* accent fill outline */
  --spore-on:    #06210f;   /* text drawn on a spore fill */
  --lantern:     #ffb84d;   /* lantern amber - fills, highlights */
  --lantern-text:#ffb84d;   /* amber as text on a surface */
  --lantern-dim: #a86f1f;
  --lantern-on:  #2a1600;   /* text drawn on an amber fill */
  --support-fg:  #ffb84d;   /* 6.9:1 on the support tint */
  --rust:        #e2554a;   /* cap rust - fills, borders, marks */
  --rust-text:   #ff8f82;   /* cap rust as text on a surface */
  --rust-dim:    #7d2a22;
  --rust-on:     #240604;   /* text drawn on a rust fill */
  --info:        #5ec8ff;
  --info-text:   #5ec8ff;
  --info-dim:    #2c7fb0;
  --info-on:     #06181f;

  /* --- text --- */
  --text:        #e8f2e4;
  --text-2:      #a9c3ad;
  --text-muted:  #7d9683;

  /* --- atmosphere: glows, scanlines, focus --- */
  --glow-rgb:    62, 240, 122;
  --lantern-rgb: 255, 184, 77;
  --glow-soft:   0.022;   /* page dither */
  --glow-mid:    0.13;    /* page wash + hover rings */
  --glow-ring:   0.18;    /* small accent dot halo */
  --glow-strong: 0.35;    /* logo halo */
  --scan:        0.055;
  --myco: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='540' height='400' viewBox='0 0 540 400'%3E%3Cg fill='none' stroke='%237cffb2' stroke-opacity='.13' stroke-width='2'%3E%3Cpath d='M-20 60H80l60 60v80l80 80v100l80 60'/%3E%3Cpath d='M80 60V0'/%3E%3Cpath d='M140 200H60l-40 40'/%3E%3Cpath d='M220 280h120l60-60h160'/%3E%3Cpath d='M400 220V120l60-60h100'/%3E%3Cpath d='M400 120l-60-60V-20'/%3E%3Cpath d='M220 380h120l60-40'/%3E%3Cpath d='M-20 320h80l60-60'/%3E%3Cpath d='M460 60V-20'/%3E%3Cpath d='M120 260v120h60'/%3E%3Cpath d='M560 340h-80v60'/%3E%3Cpath d='M300 440v-60'/%3E%3C/g%3E%3Cg fill='%237cffb2' fill-opacity='.2'%3E%3Ccircle cx='80' cy='60' r='2.5'/%3E%3Ccircle cx='140' cy='200' r='2.5'/%3E%3Ccircle cx='220' cy='280' r='2.5'/%3E%3Ccircle cx='400' cy='220' r='2.5'/%3E%3Ccircle cx='400' cy='120' r='2.5'/%3E%3Ccircle cx='120' cy='260' r='2.5'/%3E%3Ccircle cx='460' cy='60' r='2.5'/%3E%3Ccircle cx='340' cy='380' r='2.5'/%3E%3Ccircle cx='60' cy='320' r='2.5'/%3E%3Ccircle cx='220' cy='380' r='2.5'/%3E%3C/g%3E%3C/svg%3E");
  --focus-ring:  #ffb84d;
  --focus-halo:  rgba(255, 184, 77, 0.16);
  --hero-shadow:
    0 0 6px rgba(124, 255, 178, 0.7),
    0 0 18px rgba(62, 240, 122, 0.42),
    0 0 40px rgba(62, 240, 122, 0.26);

  /* --- screen surfaces: dark in every theme, like a real display --- */
  --slot-bg:       #060d09;
  --slot-rgb:      124, 255, 178;
  --slot-fg:       #7cffb2;
  --slot-dim:      #7d9683;
  --slot-sprocket: rgba(6, 13, 9, 0.85);
  --cart-label-grad: linear-gradient(90deg, #ffb84d, #c2811f);
  --cart-label-fg:   #2a1600;

  --lb-scrim:    rgba(2, 6, 4, 0.88);
  --lb-mat:      #161f1a;

  /* --- terminal: also stays dark in every theme --- */
  --term-bg:     #07100b;
  --term-bar:    #101f18;
  --term-border: #2c4636;
  --term-edge:   #3d6049;
  --term-text:   #e8f2e4;
  --term-out:    #7d9683;
  --term-prompt: #ffb84d;
  --term-ok:     #7cffb2;
  --term-flag:   #5ec8ff;
}

/* ---------------------------------------------------------------------
   2. RESET + ATMOSPHERE
   --------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--bg-void);
  overflow-x: hidden;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--head-h) + var(--s4));
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  min-height: 100vh;
  position: relative;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--text);
  background: transparent;
}

/* mycelium network + spore wash - above the canvas, behind content */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--bg-void);
  background-image:
    radial-gradient(1100px 620px at 84% -14%, rgba(var(--glow-rgb), var(--glow-mid)), transparent 61%),
    radial-gradient(760px 520px at -4% 4%, rgba(var(--lantern-rgb), 0.07), transparent 62%),
    var(--myco),
    repeating-linear-gradient(45deg, rgba(var(--glow-rgb), var(--glow-soft)) 0 2px, transparent 2px 8px);
  background-repeat: no-repeat, no-repeat, repeat, repeat;
  background-size: auto, auto, 540px 400px, 8px 8px;
  background-position: center top, left top, 0 0, 0 0;
}

/* faint CRT phosphor field over everything - pointer-events none */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, 1) 2px,
    rgba(0, 0, 0, 1) 4px
  );
  opacity: var(--scan);
  mix-blend-mode: multiply;
}

::selection { background: var(--spore-deep); color: var(--spore-on); }

img, svg { max-width: 100%; }
img { height: auto; }

/* The browser's default figure margin (1em 40px) inset every cartridge
   from its grid track, so the gallery never lined up with the text above
   it. The gallery owns its own gaps. */
figure { margin: 0; }

a { color: var(--spore); text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { color: var(--lantern-text); }

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--focus-halo);
}

.skip {
  position: absolute;
  left: var(--s4);
  top: -120px;
  z-index: 10000;
  padding: var(--s2) var(--s4);
  background: var(--lantern);
  color: var(--lantern-on);
  font-family: var(--font-mono);
  font-weight: 600;
  text-decoration: none;
  border: 3px solid var(--ink-900);
}
.skip:focus { top: var(--s4); color: var(--lantern-on); }

/* ---------------------------------------------------------------------
   3. TYPOGRAPHY
   --------------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: -0.4px;
  margin: 0 0 var(--s4);
  color: var(--text);
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: grayscale;
}

h1 { font-size: clamp(1.5rem, 5.6vw, 2.5rem); }
h2 { font-size: clamp(1.05rem, 3.1vw, 1.55rem); }
h3 { font-size: clamp(0.85rem, 2.1vw, 1.02rem); }
h4 { font-size: 0.8rem; }

p { margin: 0 0 var(--s4); }

.lede {
  font-size: clamp(1.05rem, 2.2vw, 1.25rem);
  line-height: 1.65;
  color: var(--text-2);
  /* No measure cap: a lede fills its column so its right edge matches the
     heading above it and the grid below. Only genuinely narrow columns
     (hero pitch, footer blurb, placeholder caption) keep a cap. */
  text-wrap: pretty;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  margin: 0 0 var(--s4);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lantern-text);
}
.eyebrow::before {
  content: "";
  width: 8px;
  height: 8px;
  background: var(--spore-deep);
  box-shadow: 0 0 0 3px rgba(var(--glow-rgb), var(--glow-ring));
}

.mono { font-family: var(--font-mono); }
.muted { color: var(--text-muted); }
.small { font-size: 0.86rem; }
.nowrap { white-space: nowrap; }

code, kbd, samp, pre { font-family: var(--font-mono); }

/* ---------------------------------------------------------------------
   4. LAYOUT
   --------------------------------------------------------------------- */
.wrap {
  width: min(100% - 32px, var(--page));
  margin-inline: auto;
}
.wrap--narrow { width: min(100% - 32px, 780px); }

.section { padding: var(--s9) 0; }
.section--tight { padding: var(--s7) 0; }
.section--alt {
  background: var(--alt-bg);
  border-block: 2px solid var(--border);
}

.section__head { margin-bottom: var(--s7); }
.section__head--center { margin-inline: auto; text-align: center; }
.section__head--center .lede { margin-inline: auto; }

.grid { display: grid; gap: var(--s5); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--auto { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--tight { grid-template-columns: repeat(auto-fit, minmax(198px, 1fr)); }

.divider-myco {
  height: 8px;
  border: 0;
  margin: 0;
  background: repeating-linear-gradient(90deg, var(--border-hi) 0 4px, transparent 4px 12px);
  opacity: 0.7;
}

/* ---------------------------------------------------------------------
   5. HEADER / NAV
   --------------------------------------------------------------------- */
.site-head {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--head-bg);
  border-bottom: 3px solid var(--border);
}
.site-head__inner {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--head-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  flex: none;
  margin-right: auto;
  text-decoration: none;
  color: var(--text);
}
.brand__logo {
  width: 40px;
  height: auto;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  filter: drop-shadow(0 0 6px rgba(var(--glow-rgb), var(--glow-strong)));
}
.brand__name {
  font-family: var(--font-display);
  font-size: 0.82rem;
  letter-spacing: -0.5px;
  -webkit-font-smoothing: none;
}
.brand:hover .brand__name { color: var(--spore); }
.brand:hover { color: var(--text); }

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--s1);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav__link {
  display: block;
  padding: var(--s2) var(--s3);
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--text-2);
  border: 2px solid transparent;
}
.nav__link:hover { color: var(--text); border-color: var(--border-hi); }
.nav__link[aria-current="page"] {
  color: var(--spore-on);
  background: var(--spore-deep);
  border-color: var(--spore-deep);
  box-shadow: 3px 3px 0 0 var(--ink-900);
}
.nav__link[aria-current="page"]:hover { color: var(--spore-on); }

.navtoggle {
  display: none;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  background: var(--surface);
  border: 3px solid var(--border-hi);
  box-shadow: 4px 4px 0 0 var(--ink-900);
  cursor: pointer;
}
.navtoggle:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 0 var(--ink-900); }
.navtoggle__bars { display: grid; gap: 3px; }
.navtoggle__bars i { display: block; width: 16px; height: 3px; background: var(--spore); }

/* ---------------------------------------------------------------------
   5b. THEME SWITCHER
   Three pixel swatches. The chips preview each theme on purpose, so
   they stay hard-coded while everything around them re-tints.
   --------------------------------------------------------------------- */
.theme {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: var(--s2);
  padding: 3px;
  background: var(--bg-dark);
  border: 2px solid var(--border);
}
.theme__label {
  padding: 0 var(--s2) 0 var(--s1);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.theme__btn {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: var(--surface);
  border: 2px solid var(--border-hi);
  cursor: pointer;
  transition: none;
}
.theme__btn:hover { border-color: var(--lantern-text); }
.theme__btn[aria-pressed="true"] {
  border-color: var(--focus-ring);
  box-shadow: 0 0 0 2px var(--focus-ring);
}
.theme__btn:active { transform: translate(1px, 1px); }

.theme__swatch { display: block; width: 100%; height: 100%; }
.theme__swatch--forest { background: linear-gradient(135deg, #3ef07a 0 50%, #0b1410 50% 100%); }
.theme__swatch--brown  { background: linear-gradient(135deg, #ffb84d 0 50%, #1c120b 50% 100%); }
.theme__swatch--light  { background: linear-gradient(135deg, #f0eade 0 50%, #12703a 50% 100%); }

/* Below 1000px the "Theme" word is dropped so the row stays roomy. */
@media (max-width: 999px) {
  .theme__label { display: none; }
}

/* Six nav items and a fixed-width row: brand 140.3 + nav ~586 + theme 110 +
   three 12px gaps fits the 968px wrap from about 900px up, so between 860 and
   999 the links tighten from 12px to 8px inline padding to buy the last 48px.
   Type size, tracking, gaps and the collapse point are unchanged. */
@media (min-width: 860px) and (max-width: 999px) {
  .nav__link { padding-inline: var(--s2); }
}

/* Below 860px six uppercase labels stop fitting beside the brand and the
   swatches, so the nav moves behind the hamburger instead; brand, theme and
   toggle share one row and the menu panel hangs beneath the bar. The panel is
   absolutely positioned on purpose: an in-flow panel would push the whole page
   down (259px at 360) every time the menu was tapped. */
@media (max-width: 859px) {
  .brand { order: 1; }
  .theme { order: 2; }
  .navtoggle { order: 3; display: inline-flex; min-width: 44px; min-height: 44px; }
  .site-head__inner { position: relative; flex-wrap: wrap; padding-block: var(--s3); row-gap: var(--s3); }
  .nav {
    display: none;
    position: absolute;
    top: calc(100% + 3px);   /* clears the bar's own 3px rule */
    left: 0;
    right: 0;
    z-index: 5;
    background: var(--bg-dark);
    border: 3px solid var(--border-hi);
    border-top: 0;
    box-shadow: 6px 6px 0 0 var(--ink-900);
  }
  .nav.is-open { display: block; }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__link { border-width: 0 0 2px 0; border-color: var(--border); padding: var(--s3); }
  .nav__link:last-child { border-bottom: 0; }
  .nav__link[aria-current="page"] { box-shadow: none; border-width: 0 0 2px 0; border-color: var(--spore-deep); }

  /* The swatches stay 28px so the header keeps its proportions, but the
     pressable area grows to 32x44 (centred on the swatch, into the gaps
     sideways) so a thumb can actually hit one. Neighbouring targets meet,
     never overlap. Sized from the centre because an inset resolves against
     the button's padding box, not its border box. */
  .theme__btn { position: relative; }
  .theme__btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 32px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}

/* 320-430px: the wordmark, the swatches and the hamburger have to share a
   single 296px row. Trim the gaps, keep the mark readable, and give the
   icon-only toggle a name that assistive tech can still read. */
@media (max-width: 430px) {
  .site-head__inner { gap: var(--s2); }
  .brand { gap: var(--s2); }
  .brand__name { font-size: 0.72rem; }
  .theme { gap: 4px; padding: 2px; }
  .theme__btn { width: 28px; height: 28px; }
  .navtoggle__text {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
}

/* ---------------------------------------------------------------------
   6. BUTTONS
   --------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--surface);
  --btn-fg: var(--text);
  --btn-edge: var(--border-hi);
  --px: 3px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: var(--s3) var(--s5);
  font-family: var(--font-body);
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: var(--px) solid var(--btn-edge);
  cursor: pointer;
  transition: none;
  box-shadow:
    5px 5px 0 0 var(--ink-900),
    inset -3px -3px 0 0 rgba(0, 0, 0, 0.35),
    inset 3px 3px 0 0 rgba(255, 255, 255, 0.13);
}
.btn:hover:not(:disabled) { filter: brightness(1.14); color: var(--btn-fg); }
.btn:active:not(:disabled) {
  transform: translate(3px, 3px);
  box-shadow:
    2px 2px 0 0 var(--ink-900),
    inset 3px 3px 0 0 rgba(0, 0, 0, 0.35),
    inset -3px -3px 0 0 rgba(255, 255, 255, 0.1);
}
.btn:disabled { cursor: not-allowed; filter: grayscale(1); opacity: 0.5; }

.btn--primary { --btn-bg: var(--spore-deep); --btn-fg: var(--spore-on); --btn-edge: var(--spore-edge); }
.btn--lantern { --btn-bg: var(--lantern); --btn-fg: var(--lantern-on); --btn-edge: var(--lantern-dim); }
.btn--ghost   { --btn-bg: transparent; --btn-fg: var(--spore); --btn-edge: var(--border-hi); }
.btn--danger  { --btn-bg: var(--rust); --btn-fg: var(--rust-on); --btn-edge: var(--rust-dim); }

/* --- support CTA: the warm tier ---------------------------------------
   Three tiers share one row. Download is the only filled button, See
   features is a neutral outline, and Support is the warm one: a lantern
   tint, an amber edge and a pixel heart. It is deliberately not a second
   solid fill - two saturated surfaces side by side would compete, and the
   download has to stay the loudest thing in the row.
   Ko-fi's brand red is not used: red is --rust here, already the colour of
   Redact and of destructive controls, so a red support button would read
   as a warning. Amber is the site's own "warmth" accent and is free. */
.btn--support {
  --btn-bg: rgba(var(--lantern-rgb), 0.18);
  --btn-fg: var(--support-fg);
  --btn-edge: var(--lantern-dim);
}
/* Hover deepens the tint and adds a 3px lantern halo outside the edge, so
   the state is visible on a cream page and on a near-black one alike. There
   is no third tint step on :active: the shared 3px press and collapsed
   shadow already read as a push, and a deeper amber dropped the label under
   4.5:1 in the forest theme. */
.btn--support:hover:not(:disabled) {
  --btn-bg: rgba(var(--lantern-rgb), 0.26);
  box-shadow:
    5px 5px 0 0 var(--ink-900),
    inset -3px -3px 0 0 rgba(0, 0, 0, 0.35),
    inset 3px 3px 0 0 rgba(255, 255, 255, 0.13),
    0 0 0 3px rgba(var(--lantern-rgb), 0.24);
}

/* The global ring is --focus-ring, which is this button's own amber: on
   Support it would read as a doubled border. --text is the one token that
   is dark on a light page and light on a dark one in every theme. */
.btn--support:focus-visible {
  outline-color: var(--text);
  outline-offset: 3px;
}

/* A 7x5 heart on a 4px module - 28x20, every edge on the pixel grid. */
.btn__glyph {
  flex: none;
  width: 28px;
  height: 20px;
  shape-rendering: crispEdges;
}

.btn--sm {
  --px: 2px;
  padding: var(--s2) var(--s3);
  font-size: 0.84rem;
  box-shadow:
    4px 4px 0 0 var(--ink-900),
    inset -2px -2px 0 0 rgba(0, 0, 0, 0.35),
    inset 2px 2px 0 0 rgba(255, 255, 255, 0.13);
}
.btn--sm:active:not(:disabled) { transform: translate(2px, 2px); box-shadow: 2px 2px 0 0 var(--ink-900); }
.btn--block { width: 100%; }

/* Placeholder for a download that is not published yet. Mono keeps the
   capital C of "COMING SOON" open at button size, and a gentler opacity
   keeps it readable while still reading as unavailable. */
.btn--soon {
  font-family: var(--font-mono);
  font-weight: 600;
  letter-spacing: 0.06em;
}
.btn--soon:disabled { opacity: 0.72; }

.btn__meta {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  opacity: 0.85;
}

/* The brand name, set in mono so the capital C stays open at button size.
   Pixelify Sans draws an uppercase C whose aperture closes up at 16px and
   reads as an O ("MYCOOAP"); Plex Mono keeps the gap at any size. */
.btn__name {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s4); align-items: center; }

/* ---------------------------------------------------------------------
   7. PANELS / CARDS
   --------------------------------------------------------------------- */
.panel {
  background: var(--surface);
  border: 3px solid var(--border);
  box-shadow: 6px 6px 0 0 var(--ink-900);
  padding: var(--s5);
}
.panel--dark { background: var(--bg-dark); }
.panel.panel--flush { padding: 0; }

.panel__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s2) var(--s3);
  background: var(--bar-grad);
  border-bottom: 3px solid var(--border);
}
.panel__bar-title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
}
.panel__bar-dots { display: flex; gap: 4px; }
.panel__bar-dots span { width: 10px; height: 10px; background: var(--ink-900); }
.panel__body { padding: var(--s5); }
.panel__body > :last-child { margin-bottom: 0; }

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s5);
  background: var(--bg-dark);
  border: 3px solid var(--border);
  box-shadow: 6px 6px 0 0 var(--ink-900);
  transition: border-color 0.12s steps(2), box-shadow 0.12s steps(2);
}
.card:hover {
  border-color: var(--spore-dim);
  box-shadow: 6px 6px 0 0 var(--ink-900), 0 0 0 3px rgba(var(--glow-rgb), var(--glow-ring));
}
.card__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  font-family: var(--font-mono);
  font-size: 1.25rem;
  line-height: 1;
  color: var(--spore-on);
  background: var(--spore-deep);
  border: 3px solid var(--spore-edge);
  box-shadow: 3px 3px 0 0 var(--ink-900);
}
.card--lantern .card__icon { background: var(--lantern); border-color: var(--lantern-dim); color: var(--lantern-on); }
.card--rust .card__icon { background: var(--rust); border-color: var(--rust-dim); color: var(--rust-on); }
.card--info .card__icon { background: var(--info); border-color: var(--info-dim); color: var(--info-on); }

.card__title { margin: 0; font-size: 0.86rem; }
.card__text { margin: 0; color: var(--text-2); font-size: 1rem; line-height: 1.65; }
.card__link { margin-top: auto; font-family: var(--font-mono); font-size: 0.82rem; }

.tags { display: flex; flex-wrap: wrap; gap: var(--s1); margin: 0; padding: 0; list-style: none; }
.tag {
  padding: 2px var(--s2);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--text-2);
  background: var(--surface);
  border: 2px solid var(--border);
}
.tag--spore { color: var(--spore); border-color: var(--spore-dim); }
.tag--lantern { color: var(--lantern-text); border-color: var(--lantern-dim); }
.tag--info { color: var(--info-text); border-color: var(--info-dim); }
.tag--rust { color: var(--rust-text); border-color: var(--rust-dim); }

/* ---------------------------------------------------------------------
   8. LISTS, KEYS, CODE
   --------------------------------------------------------------------- */
.list-px { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--s2); }
.list-px li {
  position: relative;
  padding-left: var(--s5);
  color: var(--text-2);
  line-height: 1.6;
}
.list-px li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.6em;
  width: 8px;
  height: 8px;
  background: var(--spore-deep);
}
.list-px--lantern li::before { background: var(--lantern); }
.list-px--info li::before { background: var(--info); }
.list-px--check li::before {
  content: "\2713";
  background: none;
  color: var(--spore);
  font-family: var(--font-mono);
  font-size: 1rem;
  width: auto;
  height: auto;
  top: 0;
  left: 0;
}
.list-px--cross li::before {
  content: "\00d7";
  background: none;
  color: var(--rust-text);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.1rem;
  width: auto;
  height: auto;
  top: 0;
  left: 2px;
}

kbd, .kbd {
  display: inline-block;
  padding: 2px 7px;
  font-size: 0.78em;
  color: var(--text);
  background: var(--surface-2);
  border: 2px solid var(--border-hi);
  box-shadow: 0 2px 0 0 var(--ink-900);
  white-space: nowrap;
}

pre { margin: 0; overflow-x: auto; font-size: 0.84rem; line-height: 1.75; }
code { font-size: 0.88em; color: var(--spore); }
p code, li code, td code { background: var(--surface-2); padding: 1px 5px; border: 1px solid var(--border); }

.term {
  background: var(--term-bg);
  border: 3px solid var(--term-border);
  box-shadow: 6px 6px 0 0 var(--ink-900);
  margin-block: var(--s4);
}
.term__bar {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  background: var(--term-bar);
  border-bottom: 2px solid var(--term-edge);
}
.term__dots { display: flex; gap: 4px; }
.term__dots span { width: 10px; height: 10px; border: 2px solid var(--term-edge); }
.term__dots span:nth-child(1) { background: var(--rust); }
.term__dots span:nth-child(2) { background: var(--lantern); }
.term__dots span:nth-child(3) { background: var(--spore-deep); }
.term__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--term-out);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.term__body { padding: var(--s4); color: var(--term-text); }
.term__body .prompt { color: var(--term-prompt); user-select: none; }
.term__body .out { color: var(--term-out); }
.term__body .ok { color: var(--term-ok); }
.term__body .flag { color: var(--term-flag); }
.term__body .verb { color: var(--term-prompt); }

.copy {
  flex: none;
  padding: 2px var(--s2);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--term-out);
  background: transparent;
  border: 2px solid var(--term-edge);
  cursor: pointer;
}
.copy:hover { color: var(--term-bg); background: var(--term-prompt); border-color: var(--term-prompt); }

/* ---------------------------------------------------------------------
   9. CALLOUTS
   --------------------------------------------------------------------- */
.callout {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s4) var(--s5);
  background: var(--bg-dark);
  border: 3px solid var(--border);
  border-left-width: 8px;
  box-shadow: 5px 5px 0 0 var(--ink-900);
}
.callout__icon { font-family: var(--font-mono); font-size: 1.15rem; line-height: 1.35; }
.callout__title { margin: 0 0 var(--s1); font-size: 0.82rem; }
.callout p { color: var(--text-2); }
.callout > div > :last-child { margin-bottom: 0; }

.callout--ok     { border-left-color: var(--spore-deep); }
.callout--ok     .callout__icon { color: var(--spore); }
.callout--info   { border-left-color: var(--info); }
.callout--info   .callout__icon { color: var(--info-text); }
.callout--warn   { border-left-color: var(--lantern); }
.callout--warn   .callout__icon { color: var(--lantern-text); }
.callout--danger { border-left-color: var(--rust); }
.callout--danger .callout__icon { color: var(--rust-text); }

/* ---------------------------------------------------------------------
   10. HERO
   --------------------------------------------------------------------- */
.hero { position: relative; padding: var(--s8) 0 var(--s9); overflow: hidden; }
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  gap: var(--s7);
  align-items: center;
}

.hero__title {
  margin: 0 0 var(--s4);
  font-size: clamp(2rem, 8vw, 3.6rem);
  letter-spacing: -1.5px;
  color: var(--spore);
  text-shadow: var(--hero-shadow);
}
.hero__pitch {
  font-size: clamp(1.05rem, 2.3vw, 1.28rem);
  line-height: 1.6;
  color: var(--text-2);
  max-width: 46ch;
  margin-bottom: var(--s5);
}
.tray-note {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s5);
  padding: var(--s2) var(--s3);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--text-2);
  background: var(--bg-dark);
  border: 2px solid var(--border);
}
.tray-note .dot { width: 8px; height: 8px; background: var(--spore-deep); box-shadow: 0 0 8px var(--spore-deep); }

/* --- the editor window mock ------------------------------------------
   Drawn the way the app draws itself: three strips on the top panel, then
   the annotation palette docked down the left edge of the canvas. The rail
   is part of the window, not a floating bar: flush to the canvas, square,
   no shadow. Everything scales off --rail-cell, so the mock shrinks as a
   whole instead of clipping or wrapping its icons. */
.stage {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--s4);
  --rail-cell: clamp(26px, 4.6vw, 32px);
  --dest-cell: clamp(16px, 3vw, 20px);
}

.stage__win {
  display: grid;
  width: 100%;
  max-width: 464px;
  min-width: 0;
  background: var(--surface);
  border: 2px solid var(--border-hi);
  box-shadow: 4px 4px 0 0 var(--ink-900);
}

/* --- top panel: menu (row 0), destinations (row 1), properties (row 2) --- */
.stage__top {
  display: grid;
  min-width: 0;
  background: var(--surface-2);
  border-bottom: 2px solid var(--border);
}
.stage__strip {
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
}
.stage__strip--menu {
  gap: 1px;
  padding: 1px var(--s1);
  background: var(--bar-grad);
  border-bottom: 2px solid var(--border);
}
.stage__menu {
  padding: 1px 5px;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  line-height: 1.7;
  color: var(--text-2);
  white-space: nowrap;
}
.stage__strip--dest { padding: 2px var(--s1); border-bottom: 2px solid var(--border); }
.stage__cell {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--dest-cell);
  height: var(--dest-cell);
  font-family: var(--font-mono);
  font-size: calc(var(--dest-cell) * 0.62);
  line-height: 1;
  color: var(--text-2);
  white-space: nowrap;
}
.stage__vsep {
  flex: none;
  width: 2px;
  height: calc(var(--dest-cell) * 0.66);
  margin: 0 3px;
  background: var(--border-hi);
}
.stage__strip--props { gap: var(--s1); padding: 3px var(--s2); }
.stage__sw {
  flex: none;
  width: 12px;
  height: 12px;
  border: 2px solid var(--border-hi);
}
.stage__sw--fill { background: var(--spore-deep); }
.stage__sw--line { background: var(--ink-900); }
.stage__sw--text { background: var(--lantern); }
.stage__thick {
  flex: none;
  width: 24px;
  height: 3px;
  margin-left: var(--s1);
  background: var(--text-2);
}
.stage__val {
  font-family: var(--font-mono);
  font-size: 0.56rem;
  line-height: 1;
  color: var(--text-muted);
}

/* --- body: the rail, then the canvas --- */
.stage__body {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: stretch;
  min-width: 0;
}

/* The palette: one column, flush against the canvas edge, square, no shadow. */
.stage__rail {
  display: grid;
  align-content: start;
  justify-items: center;
  width: calc(var(--rail-cell) + 10px);
  padding: var(--s1) 4px;
  background: var(--surface-2);
  border-right: 2px solid var(--border-hi);
}
.stage__tool {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--rail-cell);
  height: var(--rail-cell);
  font-family: var(--font-mono);
  font-size: calc(var(--rail-cell) * 0.48);
  line-height: 1;
  color: var(--text-2);
  white-space: nowrap;
  border: 2px solid transparent;
}
/* The select tool is the one the editor opens with. */
.stage__tool--on {
  color: var(--spore-on);
  background: var(--spore-deep);
  border-color: var(--spore-edge);
}
/* The solid Redact cell sits rust on purpose: opaque pixels, no peeking through. */
.stage__tool--rust {
  color: var(--rust-on);
  background: var(--rust);
  border-color: var(--rust-dim);
}
/* Crop is a split button in the app: the cell carries a drop-down caret. */
.stage__tool--split { padding: 0 3px 3px 0; }
.stage__caret {
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 0;
  height: 0;
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 3px solid currentColor;
}
.stage__sep {
  width: calc(var(--rail-cell) - 8px);
  height: 2px;
  margin: 4px 0;
  background: var(--border);
}

/* --- canvas: paper, a dotted pixel field, and one selected annotation --- */
.stage__canvas {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  padding: var(--s4);
  overflow: hidden;
  background-color: var(--surface);
  background-image: radial-gradient(var(--border) 1px, transparent 1px);
  background-size: 16px 16px;
}
.stage__art { position: relative; display: grid; place-items: center; }
.stage__logo {
  width: clamp(112px, 20vw, 168px);
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  filter: drop-shadow(0 0 12px rgba(var(--glow-rgb), var(--glow-strong)));
}
.stage__sel {
  position: absolute;
  inset: -10px;
  border: 2px dashed var(--spore-dim);
  pointer-events: none;
}
.stage__sel i {
  position: absolute;
  width: 8px;
  height: 8px;
  background: var(--spore-deep);
  border: 2px solid var(--ink-900);
}
.stage__sel i:nth-child(1) { top: -5px; left: -5px; }
.stage__sel i:nth-child(2) { top: -5px; right: -5px; }
.stage__sel i:nth-child(3) { bottom: -5px; left: -5px; }
.stage__sel i:nth-child(4) { bottom: -5px; right: -5px; }
.stage__step {
  position: absolute;
  right: -14px;
  bottom: -14px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  font-family: var(--font-display);
  font-size: 0.6rem;
  line-height: 1;
  color: var(--lantern-on);
  background: var(--lantern);
  border: 3px solid var(--ink-900);
}

/* The element-list caption belongs to the canvas, so it sits on the canvas. */
.stage__chip {
  position: absolute;
  right: var(--s2);
  bottom: var(--s2);
  align-items: flex-start;
  margin: 0;
  max-width: calc(100% - var(--s4));
  padding: 2px var(--s2);
  font-size: 0.68rem;
  line-height: 1.5;
}
.stage__chip .dot { flex: none; margin-top: 4px; }

.hero__spores { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.hero__spores i { position: absolute; width: 4px; height: 4px; background: var(--spore); opacity: 0.5; }
.hero__spores i:nth-child(1) { left: 12%; top: 72%; }
.hero__spores i:nth-child(2) { left: 28%; top: 34%; }
.hero__spores i:nth-child(3) { left: 46%; top: 84%; }
.hero__spores i:nth-child(4) { left: 64%; top: 22%; }
.hero__spores i:nth-child(5) { left: 78%; top: 62%; }
.hero__spores i:nth-child(6) { left: 90%; top: 40%; }

@media (prefers-reduced-motion: no-preference) {
  .hero__spores i { animation: spore-drift 9s steps(24) infinite; }
  .hero__spores i:nth-child(2n) { animation-duration: 12s; animation-delay: -3s; }
  .hero__spores i:nth-child(3n) { animation-duration: 15s; animation-delay: -6s; }
  @keyframes spore-drift {
    0%   { transform: translate(0, 0); opacity: 0; }
    15%  { opacity: 0.55; }
    85%  { opacity: 0.55; }
    100% { transform: translate(-18px, -70px); opacity: 0; }
  }
}

@media (max-width: 900px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
  .hero { padding-top: var(--s6); }
  .stage { order: -1; }
}

/* ---------------------------------------------------------------------
   11. SCREENSHOT CARTRIDGES
   --------------------------------------------------------------------- */
.gallery {
  display: grid;
  gap: var(--s5);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.cart {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-dark);
  border: 3px solid var(--border);
  box-shadow: 6px 6px 0 0 var(--ink-900);
}
.cart__label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  background: var(--cart-label-grad);
  border-bottom: 3px solid var(--border);
}
.cart__idx {
  font-family: var(--font-display);
  font-size: 0.66rem;
  color: var(--cart-label-fg);
  letter-spacing: -0.5px;
}
.cart__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--cart-label-fg);
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cart__slot {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--slot-bg);
  overflow: hidden;
}
/* A real screenshot is shown clean: the only thing over it is a 1px inner
   line, so the cartridge still reads as a framed screen. The CRT field and
   the filmstrip perforations belong to the empty placeholder, where they
   sell the "insert cartridge" idea instead of blurring real pixels. */
.cart__slot::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  border: 1px solid var(--border-hi);
}
.cart.is-empty .cart__slot::after {   /* per-slot CRT field, empty slots only */
  border: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0 2px,
    rgba(0, 0, 0, 0.32) 2px 4px
  );
}
.cart.is-empty .cart__slot::before {  /* filmstrip perforations, empty slots only */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom, var(--slot-sprocket) 0 8px, transparent 8px 20px) left/10px 100% no-repeat,
    repeating-linear-gradient(to bottom, var(--slot-sprocket) 0 8px, transparent 8px 20px) right/10px 100% no-repeat;
}
/* No image-rendering override here: UI screenshots are downscaled and must
   stay smooth. Only the placeholder logo is a pixel mark. */
.cart__img {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cart.is-empty .cart__img { display: none; }

.cart__ph {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--s2);
  padding: var(--s4);
  text-align: center;
  background:
    repeating-linear-gradient(45deg, rgba(var(--slot-rgb), 0.06) 0 4px, transparent 4px 10px),
    var(--slot-bg);
}
.cart__ph-icon {
  width: 44px;
  height: auto;
  opacity: 0.5;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.cart__ph-text {
  font-family: var(--font-display);
  font-size: 0.58rem;
  letter-spacing: -0.3px;
  line-height: 1.7;
  color: var(--slot-fg);
}
.cart__ph-text::after { content: "_"; color: var(--lantern); }
@media (prefers-reduced-motion: no-preference) {
  .cart__ph-text::after { animation: cursor-blink 1.1s steps(1) infinite; }
  @keyframes cursor-blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
}
.cart__ph-sub {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  line-height: 1.5;
  color: var(--slot-dim);
  max-width: 26ch;
}
/* Click-to-enlarge affordance. main.js adds .cart--zoom and the badge,
   so a browser without JS keeps the plain cartridge it has today. */
.cart--zoom {
  transition: border-color 0.12s steps(2), box-shadow 0.12s steps(2);
}
.cart--zoom:not(.is-empty):hover,
.cart--zoom:not(.is-empty):focus-within {
  border-color: var(--spore-dim);
  box-shadow: 6px 6px 0 0 var(--ink-900), 0 0 0 3px rgba(var(--glow-rgb), var(--glow-ring));
}
.cart--zoom .cart__slot,
.cart--zoom .cart__img { cursor: zoom-in; }
.cart--zoom:hover .cart__img { filter: brightness(1.05); }
/* The slot clips its overflow, so the ring is drawn just inside the frame. */
.cart--zoom .cart__img:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: -6px;
  box-shadow: none;
}
.cart__zoom {
  position: absolute;
  top: var(--s2);
  right: var(--s2);
  z-index: 6;
  padding: 1px 5px;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.6;
  color: var(--cart-label-fg);
  background: var(--cart-label-grad);
  border: 2px solid var(--ink-900);
  opacity: 0.9;
  pointer-events: none;
}
.cart--zoom:hover .cart__zoom,
.cart--zoom:focus-within .cart__zoom {
  background: var(--lantern);
  opacity: 1;
}
/* A missing PNG shows the placeholder; it should not advertise a lightbox. */
.cart.is-empty .cart__zoom { display: none; }

.filmstrip {
  border-block: 3px solid var(--border);
  background:
    repeating-linear-gradient(90deg, var(--border) 0 6px, transparent 6px 18px) top/100% 8px repeat-x,
    repeating-linear-gradient(90deg, var(--border) 0 6px, transparent 6px 18px) bottom/100% 8px repeat-x,
    var(--film-bg);
  padding: var(--s5) 0;
}

/* ---------------------------------------------------------------------
   11b. LIGHTBOX - click a cartridge, get the real PNG
   The <dialog> is injected by main.js, so a browser without JS keeps the
   plain gallery. The mat stays dark in every theme on purpose: these are
   light UI screenshots and they need a neutral surround to read well.
   --------------------------------------------------------------------- */

/* Scroll lock. --lb-sb is the scrollbar width main.js measured, so the
   page does not jump sideways when the bar disappears. */
html.lb-open { overflow: hidden; }
html.lb-open body { padding-right: var(--lb-sb, 0px); }

.lightbox {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(100vw - 32px, 1660px);
  max-width: none;
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 3px solid var(--border-hi);
  border-radius: 0;
  background: var(--bg-dark);
  color: var(--text);
  box-shadow: 8px 8px 0 0 var(--ink-900);
  overflow: hidden;
}
.lightbox::backdrop { background: var(--lb-scrim); }
/* The dialog box itself is not a control; its contents carry the focus. */
.lightbox:focus,
.lightbox:focus-visible {
  outline: none;
  box-shadow: 8px 8px 0 0 var(--ink-900);
}

.lightbox__frame { display: flex; flex-direction: column; min-width: 0; }
.lightbox[open] .lightbox__frame { animation: lb-rise 0.2s steps(4) both; }
@keyframes lb-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* top bar reuses the cartridge label strip */
.lightbox__bar {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) var(--s3);
  background: var(--cart-label-grad);
  border-bottom: 3px solid var(--border);
}
.lightbox__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cart-label-fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lightbox__close {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  flex: none;
  padding: 2px var(--s2);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  background: var(--surface);
  border: 2px solid var(--ink-900);
  border-radius: 0;
  box-shadow: 2px 2px 0 0 var(--ink-900);
  cursor: pointer;
}
.lightbox__close:hover { color: var(--rust-on); background: var(--rust); border-color: var(--rust-dim); }
.lightbox__close:active { transform: translate(1px, 1px); box-shadow: 1px 1px 0 0 var(--ink-900); }
.lightbox__close-x { font-size: 0.9rem; line-height: 1; }

.lightbox__mat {
  position: relative;
  display: grid;
  place-items: center;
  padding: var(--s4);
  background-color: var(--lb-mat);
  background-image:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 4px);
}
.lightbox__img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: calc(100vh - 176px);
  max-height: calc(100dvh - 176px);
  image-rendering: auto;          /* never pixelated: these are UI photos */
  border: 2px solid rgba(255, 255, 255, 0.22);
  box-shadow: 8px 8px 0 0 rgba(0, 0, 0, 0.45);
}

.lightbox__foot {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  background: var(--surface-2);
  border-top: 3px solid var(--border);
}
.lightbox__nav {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  height: 32px;
  padding: 0;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1;
  color: var(--spore);
  background: var(--surface);
  border: 2px solid var(--border-hi);
  border-radius: 0;
  box-shadow: 3px 3px 0 0 var(--ink-900);
  cursor: pointer;
}
.lightbox__nav:hover { color: var(--spore-on); background: var(--spore-deep); border-color: var(--spore-edge); }
.lightbox__nav:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 0 var(--ink-900); }
.lightbox__count {
  font-family: var(--font-display);
  font-size: 0.6rem;
  letter-spacing: -0.4px;
  color: var(--lantern-text);
  white-space: nowrap;
}
.lightbox__hint {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

/* Tablets are touch too: the lightbox controls get the same thumb-sized
   boxes as they do on a phone. */
@media (max-width: 859px) {
  .lightbox__nav { width: 44px; height: 44px; }
  .lightbox__close { min-width: 44px; min-height: 44px; justify-content: center; }
}

@media (max-width: 700px) {
  .lightbox {
    width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
    max-height: calc(100dvh - 16px);
  }
  .lightbox__bar,
  .lightbox__foot { padding: var(--s2); }
  .lightbox__mat { padding: var(--s2); }
  .lightbox__img {
    max-height: calc(100vh - 200px);
    max-height: calc(100dvh - 200px);
    box-shadow: 4px 4px 0 0 rgba(0, 0, 0, 0.45);
  }
  .lightbox__hint { display: none; }
}
@media (max-width: 480px) {
  .lightbox__close-text { display: none; }
  .lightbox__title { font-size: 0.7rem; letter-spacing: 0.03em; }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox[open] .lightbox__frame { animation: none; }
  .cart--zoom { transition: none; }
}

/* ---------------------------------------------------------------------
   12. DOWNLOAD
   --------------------------------------------------------------------- */
.dl-card {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s5);
  background: var(--bg-dark);
  border: 3px solid var(--border);
  box-shadow: 6px 6px 0 0 var(--ink-900);
}
.dl-card--feature {
  border-color: var(--spore-dim);
  box-shadow: 6px 6px 0 0 var(--ink-900), 0 0 0 3px rgba(var(--glow-rgb), var(--glow-ring));
}
.dl-card__top { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.dl-card__arch {
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: -0.5px;
  color: var(--spore);
  margin: 0;
}
.dl-card p { margin: 0; color: var(--text-2); font-size: 0.98rem; }
.dl-card .list-px { margin-top: var(--s1); }
.dl-card .btn { margin-top: auto; }
.dl-card__note {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  line-height: 1.5;
}
.dl-file {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  word-break: break-all;
  color: var(--text-muted);
  background: var(--bg-void);
  border: 2px solid var(--border);
  padding: var(--s2);
  display: block;
}

/* Compact variant: the three installer cards sit shoulder to shoulder in one
   row, so their inner rhythm is tightened here instead of in .dl-card - the
   portable and source cards keep the roomier default. */
.dl-card--compact {
  gap: var(--s2);
  padding: var(--s4);
}
.dl-card--compact .dl-file {
  padding: var(--s1) var(--s2);
  line-height: 1.4;
}
.dl-card--compact p,
.dl-card--compact .list-px li {
  line-height: 1.45;
}
.dl-card--compact .list-px {
  margin-top: 0;
}
/* the button carries a 5px hard shadow; keep that shadow off the card's
   bottom border without changing the shared .btn */
.dl-card--compact .btn {
  margin-bottom: var(--s1);
}

.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.spec-table caption {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lantern-text);
  padding-bottom: var(--s3);
}
.spec-table th, .spec-table td {
  text-align: left;
  padding: var(--s3);
  border-bottom: 2px solid var(--border);
  vertical-align: top;
}
.spec-table th {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
  width: 38%;
  font-weight: 600;
}
.spec-table td { color: var(--text); }
.spec-table tr:last-child th, .spec-table tr:last-child td { border-bottom: 0; }

/* ---------------------------------------------------------------------
   13. CTA BAND + FOOTER
   --------------------------------------------------------------------- */
.cta-band {
  position: relative;
  overflow: hidden;
  border-block: 3px solid var(--spore-dim);
  background:
    radial-gradient(760px 320px at 50% 120%, rgba(var(--glow-rgb), var(--glow-mid)), transparent 70%),
    var(--bg-dark);
  padding: var(--s9) 0;
  text-align: center;
}
.cta-band h2 { color: var(--spore); }
.cta-band .lede { margin-inline: auto; }
.cta-band .btn-row { justify-content: center; }

.site-foot {
  border-top: 3px solid var(--border);
  background: var(--bg-dark);
  padding-top: var(--s7);
}
.site-foot__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: var(--s6);
  padding-bottom: var(--s7);
}
.site-foot__brand p { color: var(--text-2); font-size: 0.96rem; max-width: 34ch; }
.site-foot__h {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lantern-text);
  margin: 0 0 var(--s3);
}
.site-foot__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.site-foot__list a { color: var(--text-2); text-decoration: none; font-size: 0.96rem; }
.site-foot__list a:hover { color: var(--spore); text-decoration: underline; }
.site-foot__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding-block: var(--s4);
  border-top: 2px solid var(--border);
}
.site-foot__base p { margin: 0; font-size: 0.82rem; color: var(--text-muted); }
.foot-mark { display: flex; align-items: center; gap: var(--s3); }
.foot-mark img { width: 32px; image-rendering: pixelated; image-rendering: crisp-edges; }

@media (max-width: 860px) {
  .site-foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 520px) {
  .site-foot__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
}

/* ---------------------------------------------------------------------
   14. PROSE / PAGE HEADER
   --------------------------------------------------------------------- */
.page-head {
  padding: var(--s8) 0 var(--s6);
  border-bottom: 2px solid var(--border);
}
.page-head h1 { color: var(--spore); margin-bottom: var(--s3); }
.page-head .lede { margin-bottom: 0; }

.prose { text-wrap: pretty; }
.prose h2 { margin-top: var(--s7); }
.prose h3 { margin-top: var(--s6); }
.prose > :last-child { margin-bottom: 0; }
.prose ul { color: var(--text-2); }

.anchor-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0 0 var(--s6);
  padding: 0;
  list-style: none;
}
.anchor-list a {
  display: block;
  padding: var(--s2) var(--s3);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  text-decoration: none;
  color: var(--text-2);
  background: var(--bg-dark);
  border: 2px solid var(--border);
}
.anchor-list a:hover { color: var(--lantern-on); background: var(--lantern); border-color: var(--lantern); }

.group { padding-top: var(--s7); }
.group:first-of-type { padding-top: 0; }
.group__head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin-bottom: var(--s5);
  padding-bottom: var(--s3);
  border-bottom: 2px solid var(--border);
}
.group__num {
  font-family: var(--font-display);
  font-size: 0.72rem;
  color: var(--spore-on);
  background: var(--spore-deep);
  padding: 4px 6px;
  flex: none;
}
.group__head h2 { margin: 0; }
.group__head p { margin: 0; color: var(--text-muted); font-family: var(--font-mono); font-size: 0.78rem; }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--s4); }
.stat {
  padding: var(--s4);
  background: var(--bg-dark);
  border: 3px solid var(--border);
  box-shadow: 4px 4px 0 0 var(--ink-900);
}
.stat__n {
  display: block;
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--spore);
  margin-bottom: var(--s2);
  letter-spacing: -1px;
}
.stat__l { font-family: var(--font-mono); font-size: 0.76rem; color: var(--text-muted); }

/* ---------------------------------------------------------------------
   15. MOTION: staggered reveal (JS adds .is-in)
   --------------------------------------------------------------------- */
.reveal { transition: opacity 0.5s steps(8), transform 0.5s steps(8); }
.has-js .reveal { opacity: 0; transform: translateY(14px); }
.has-js .reveal.is-in { opacity: 1; transform: none; }
.d1 { transition-delay: 0.04s; }
.d2 { transition-delay: 0.12s; }
.d3 { transition-delay: 0.2s; }
.d4 { transition-delay: 0.28s; }
.d5 { transition-delay: 0.36s; }
.d6 { transition-delay: 0.44s; }
.d7 { transition-delay: 0.52s; }
.d8 { transition-delay: 0.6s; }

@media (prefers-reduced-motion: reduce) {
  .has-js .reveal { opacity: 1; transform: none; }
  .reveal { transition: none; }
  .card { transition: none; }
}

/* ---------------------------------------------------------------------
   16. RESPONSIVE FALLBACKS
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .section { padding: var(--s8) 0; }
  .grid--2, .grid--3, .grid--4, .grid--auto { grid-template-columns: minmax(0, 1fr); }
  .gallery { grid-template-columns: minmax(0, 1fr); }

  /* A 38-42% label column leaves the value column ~150px at 320px, which
     stretched the five spec rows into a 1549px ribbon of three-word lines.
     Below 700px every row becomes a label above its value - the same
     information, read the way a spec sheet reads on paper. */
  .spec-table,
  .spec-table tbody,
  .spec-table tr,
  .spec-table th,
  .spec-table td { display: block; }
  .spec-table th {
    width: auto;
    padding: 0 0 var(--s1);
    border-bottom: 0;
  }
  .spec-table td { padding: 0; border-bottom: 0; }
  .spec-table tr { padding-block: var(--s3); border-bottom: 2px solid var(--border); }
  .spec-table tr:first-child { padding-top: 0; }
  .spec-table tr:last-child { padding-bottom: 0; border-bottom: 0; }
}
@media (max-width: 420px) {
  body { font-size: 1rem; }
  .wrap, .wrap--narrow { width: min(100% - 24px, var(--page)); }
  .btn { padding: var(--s3) var(--s4); font-size: 0.9rem; }
  .callout { padding: var(--s3) var(--s4); }
  .panel, .card, .dl-card { padding: var(--s4); }
  .term__body { padding: var(--s3); }
  .term__body pre { font-size: 0.78rem; }
}

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

/* ---------------------------------------------------------------------
   17. SMALL UTILITIES + TRAY MENU MOCK
   --------------------------------------------------------------------- */
.items-center { align-items: center; }
.mt-0 { margin-top: 0; }
.mt-4 { margin-top: var(--s4); }
.mt-5 { margin-top: var(--s5); }
.mt-6 { margin-top: var(--s6); }
.mb-0 { margin-bottom: 0; }
.mb-5 { margin-bottom: var(--s5); }
.stack { display: grid; gap: var(--s5); }
.stack--sm { display: grid; gap: var(--s3); }

/* --- tray menu mock: the menu panel, plus More as its own submenu panel ---
   Sizing is driven by the width this mock actually gets, not by the viewport:
   wide enough and the submenu sits to the right like Windows draws it; narrow
   and it becomes a second panel stacked under the first. Nothing is clipped
   either way, and a browser without container queries gets the stacked pair. */
.traymock { container-type: inline-size; }
.traymock__pair { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; }
.traymock__main { grid-column: 1; }
.traymock__rows { padding: var(--s1); }
.traymock__sub {
  position: relative;
  z-index: 2;
  grid-column: 1;
  margin: var(--s4) 0 0 var(--s4);
  padding: var(--s1);
  background: var(--surface);
  border: 3px solid var(--border-hi);
  box-shadow: 6px 6px 0 0 var(--ink-900);
}

@container (min-width: 480px) {
  .traymock__pair { grid-template-columns: minmax(0, 1fr) auto; }
  .traymock__sub {
    grid-column: 2;
    margin: calc(var(--s6) + var(--s2)) 0 0 calc(-1 * var(--s3));
  }
}

/* The submenu arrives one step after the panel it hangs off. */
@media (prefers-reduced-motion: no-preference) {
  .has-js .traymock__sub {
    opacity: 0;
    transform: translate(-6px, -4px);
    transition: opacity 0.28s steps(4), transform 0.28s steps(4);
    transition-delay: 0.34s;
  }
  .has-js .traymock.is-in .traymock__sub { opacity: 1; transform: none; }
}

.menumock {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.45;
}
.menumock__item {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  color: var(--text-2);
}
.menumock__item--active { color: var(--spore-on); background: var(--spore-deep); }
.menumock__item--active::before { content: "\25ba"; font-size: 0.72rem; }
/* Rows that open a submenu: label left, arrow hard against the right edge.
   The extra right padding keeps the arrow clear of the panel that overlaps. */
.menumock__item--parent { padding-right: var(--s4); }
.menumock__arrow {
  margin-left: auto;
  flex: none;
  width: 14px;
  font-size: 0.72rem;
  line-height: 1.2;
  text-align: right;
  color: var(--text-muted);
}
/* The row whose submenu is the open one. Quieter than the hovered row. */
.menumock__item--open { background: var(--surface-2); color: var(--text); }
.menumock__item--open .menumock__arrow { color: var(--spore); }
.menumock__sep { height: 2px; background: var(--border); margin: var(--s1) 0; }

.swatch {
  padding: var(--s4);
  background: var(--bg-dark);
  border: 3px solid var(--border);
  box-shadow: 4px 4px 0 0 var(--ink-900);
}
.swatch__chip { height: 56px; border: 2px solid var(--border-hi); margin-bottom: var(--s3); }
.swatch__name { font-family: var(--font-mono); font-size: 0.8rem; color: var(--text); margin: 0 0 2px; }
.swatch__desc { font-family: var(--font-mono); font-size: 0.72rem; color: var(--text-muted); margin: 0; }
.swatch--system .swatch__chip { background: linear-gradient(90deg, #e8f2e4 0 50%, #0b1410 50% 100%); }
.swatch--light  .swatch__chip { background: #f2f7f0; }
.swatch--dark   .swatch__chip { background: #0b1410; }
.swatch--green  .swatch__chip { background: linear-gradient(90deg, #3ef07a 0 50%, #0b1410 50% 100%); }

.flaglist { margin: 0; display: grid; gap: var(--s1); }
.flaglist dt { font-family: var(--font-mono); font-size: 0.84rem; color: var(--lantern-text); }
.flaglist dd { margin: 0 0 var(--s4); color: var(--text-2); font-size: 0.98rem; }
.flaglist dd:last-child { margin-bottom: 0; }

.toolgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--s2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.toolgrid li {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text-2);
  background: var(--bg-dark);
  border: 2px solid var(--border);
}
.toolgrid .g { color: var(--spore); font-size: 1rem; line-height: 1; }

/* ---------------------------------------------------------------------
   18. WRAPPING / OVERFLOW HARDENING
   Global guards so long strings, pixel headings and grid children can
   never push past their container. No copy or layout changes: every
   rule below only takes effect when content would otherwise overflow.
   --------------------------------------------------------------------- */

/* --- 18a. grid + flex children may shrink (kills column blowouts) --- */
.grid > *, .gallery > *, .stack > *, .stat-row > *,
.hero__grid > *, .site-head__inner > *, .site-foot__grid > *,
.group__head > *, .btn-row > *, .tags > *,
.toolgrid > *, .anchor-list > *,
.callout > div, .panel__body > *, .dl-card > *, .card > *,
.dl-card__top > *, .cart__label > *, .term__bar > *, .panel__bar > * {
  min-width: 0;
}

/* --- 18b. flex rows that must wrap instead of pushing wide --- */
.group__head, .tray-note, .eyebrow,
.dl-card__top, .term__bar, .panel__bar {
  flex-wrap: wrap;
}

/* --- 18c. prose + ledes always wrap inside their column --- */
p, li, dd, .lede, .hero__pitch, .card__text,
.swatch__desc, .dl-card__note, .menumock__item, a {
  overflow-wrap: break-word;
}

/* --- 18d. pixel-font headings: break long words, balance lines --- */
h1, h2, h3, h4 {
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* --- 18e. user-visible code / filenames / flags / hashes / URLs --- */
code, kbd, samp, .mono, .dl-file, .flaglist dt, .cart__ph-sub {
  overflow-wrap: anywhere;
}

/* --- 18f. terminal blocks wrap instead of clipping lines --- */
.term { min-width: 0; }
.term__body pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* --- 18g. buttons + tags never force their row wider --- */
.btn { max-width: 100%; }
.tag, .btn__meta { overflow-wrap: anywhere; }

/* --- 18g2. touch targets ------------------------------------------------
   Every control below is comfortable with a mouse at its design size, and
   every one of them measured 18-42px tall on a phone. Scoped to the touch
   range so the desktop rendering is untouched: the logo link (41.8px), the
   card CTA (22.3px), the terminal's copy button (22px), the features jump
   list (41.8px) and the footer links (18px) all grow to 26-50px here. */
@media (max-width: 859px) {
  .brand { min-height: 44px; }
  .card__link {
    align-self: flex-start;
    padding-block: var(--s2);
  }
  .copy { padding: var(--s1) var(--s2); }
  .anchor-list a { padding: var(--s3); }
  .site-foot__list a {
    display: inline-block;
    padding-block: var(--s1);
  }
}

/* --- 18h. wide ledes span both columns of a 2-col group --- */
/* A group lede that describes both columns should not sit inside one of them:
   at 505px it wraps to 5-6 lines with a 25% orphan. Hoisted to a grid child
   and spanned, it reads as 2 lines across the full 1034px. */
.lede--wide { grid-column: 1 / -1; text-wrap: balance; }

/* Prose everywhere avoids a one-word last line (the 3-8px "orphan" tails
   measured on every page). `pretty` is the targeted fix; `balance` is only
   for the wide group ledes, where it evens the lines out as well. */
p, li, dd, blockquote { text-wrap: pretty; }

/* ---------------------------------------------------------------------
   19. NOT FOUND (404)
   One panel, one job: say what happened, offer the way back. It reuses the
   editor window's title bar so the page reads as one more small window
   from the app's world, and the numeral carries the same hard pixel shadow
   every button and card on the site already uses.
   The section is exactly one viewport tall minus the header, so the panel
   and both actions are visible at 360x640 without scrolling.
   --------------------------------------------------------------------- */
.nf {
  display: grid;
  place-items: center;
  min-height: calc(100vh - var(--head-h) - 4px);
  min-height: calc(100svh - var(--head-h) - 4px);
  padding: var(--s6) 0;
}

/* A 600px measure keeps the panel from becoming a wide, empty bar. */
.nf__panel {
  width: min(100%, 600px);
  margin-inline: auto;
  text-align: center;
}

.nf__body { padding: var(--s7) var(--s5) var(--s5); }

.nf__title { margin: 0 0 var(--s4); }

.nf__code {
  display: block;
  margin: 0 0 var(--s3);
  font-family: var(--font-display);
  font-size: clamp(3.75rem, 20vw, 7.5rem);
  line-height: 1.05;
  letter-spacing: -2px;
  color: var(--spore);
  /* Display type gets the same theme glow as .hero__title. A hard offset
     shadow read as a muddy double-strike at 1x in the light theme, so the
     numeral stays crisp and lets the glow do the work. */
  text-shadow: var(--hero-shadow);
}

.nf__head {
  display: block;
  font-size: clamp(0.85rem, 2.3vw, 1.05rem);
  line-height: 1.6;
}

.nf__text {
  max-width: 42ch;
  margin: 0 auto var(--s5);
  color: var(--text-2);
}

.nf__actions { justify-content: center; }

.nf__more {
  margin: var(--s5) 0 0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
}

@media (max-width: 700px) {
  .nf { padding: var(--s5) 0; }
  .nf__body { padding: var(--s6) var(--s4) var(--s5); }
}

/* --- 18i. tablet stacking ----------------------------------------------
   Above 700px the "What it is" text and the tray-menu mock share two
   columns, but the mock needs ~480px before its own container query lays the
   two panels side by side. Below that it stacks, grows to ~880px beside
   ~700px of text, and leaves a visible hole under the copy. So this one
   section stacks until its column is wide enough; every other grid keeps the
   700px breakpoint. */
@media (max-width: 1059px) {
  #what .grid--2 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------------
   21. CONTACT
   Two routes, one checklist. The route cards are .dl-card - the same
   "one job, one button" shell the download page uses, so the action sits
   on the card floor and both cards line up whatever the body length - and
   the checklist is a flush .panel, which reads as one more small window
   from the app's world. Only the checklist columns are new: four short
   items pair up at desktop width instead of running the full 1064px, and
   they stack at the site's usual 700px point.
   --------------------------------------------------------------------- */
.contact-list {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s3) var(--s6);
}
@media (max-width: 700px) {
  .contact-list { grid-template-columns: minmax(0, 1fr); }
}
