/* ───────────────────────────────────────────────────────────────
   LINEAGE - five worlds.
   Variables are SEMANTIC: --ink = page bg, --cream = primary text,
   --cool = papers accent, --teal = impact, --amber = ideas.
   Light themes simply invert the values. Tints use color-mix so
   everything adapts automatically.
   ─────────────────────────────────────────────────────────────── */

:root {
  --maxw: 1180px;
  --spine-x: 168px;
  --radius: 5px;
}

/* ── 1 · TECHNICAL - dark, ink & steel ─────────────────────────── */
.theme-technical {
  --ink: #0e0f13; --glow-1: #1a1d28; --glow-2: #181a24;
  --ink-2: #14161c; --ink-3: #1b1e27;
  --cream: #ece6d8; --cream-dim: #a39d8f; --cream-faint: #6b675d;
  --paper-edge: #2a2d38;
  --cool: #7fb0c9; --cool-deep: #4a7d96;
  --teal: #84b8a4; --teal-deep: #4f7d6e;
  --amber: #e6a94b; --amber-glow: #f0c27a; --rose: #c97f8a;
  --on-accent: #07131a;
  --serif: "Bricolage Grotesque", system-ui, sans-serif;
  --read:  "IBM Plex Sans", system-ui, sans-serif;
  --mono:  "IBM Plex Mono", ui-monospace, monospace;
  --grain: 0.035;
}

/* ── 2 · MIDNIGHT - dark, neon ─────────────────────────────────── */
.theme-midnight {
  --ink: #0a0a14; --glow-1: #20123f; --glow-2: #06243a;
  --ink-2: #11122a; --ink-3: #181a38;
  --cream: #e9e7f7; --cream-dim: #9a96c4; --cream-faint: #635f8c;
  --paper-edge: #2b2850;
  --cool: #6ea8ff; --cool-deep: #4069c9;
  --teal: #4fe0c8; --teal-deep: #2a9d8a;
  --amber: #ff7ec0; --amber-glow: #ffa9d6; --rose: #ff6b6b;
  --on-accent: #06101f;
  --serif: "Bricolage Grotesque", system-ui, sans-serif;
  --read:  "Hanken Grotesk", system-ui, sans-serif;
  --mono:  "Spline Sans Mono", ui-monospace, monospace;
  --grain: 0.05;
}

/* ── 3 · EDITORIAL - light, warm paper ─────────────────────────── */
.theme-editorial {
  --ink: #f3ece0; --glow-1: #ece0cd; --glow-2: #efe7d6;
  --ink-2: #fbf6ec; --ink-3: #fffdf7;
  --cream: #211c15; --cream-dim: #6a6051; --cream-faint: #9a9080;
  --paper-edge: #ddd2bf;
  --cool: #2f6480; --cool-deep: #234e63;
  --teal: #3f7d6a; --teal-deep: #2f5e50;
  --amber: #b25a26; --amber-glow: #cf7330; --rose: #a8505c;
  --on-accent: #fbf6ec;
  --serif: "Gloock", Georgia, serif;
  --read:  "Hanken Grotesk", system-ui, sans-serif;
  --mono:  "Spline Sans Mono", ui-monospace, monospace;
  --grain: 0.02;
}

/* ── 4 · ARCHIVAL - light, sepia index ─────────────────────────── */
.theme-archival {
  --ink: #e7dfcf; --glow-1: #ddd2bd; --glow-2: #ded4c0;
  --ink-2: #efe7d6; --ink-3: #f5eedd;
  --cream: #2a241a; --cream-dim: #6e6553; --cream-faint: #9b8f78;
  --paper-edge: #cbbfa5;
  --cool: #4b6669; --cool-deep: #3a5053;   /* AA as text on paper and on its own tint */
  --teal: #8a6f3c; --teal-deep: #6a5530;
  --amber: #9c3b2e; --amber-glow: #b9492f; --rose: #934338;
  --on-accent: #f3ece0;
  --serif: "Space Mono", ui-monospace, monospace;
  --read:  "Archivo", system-ui, sans-serif;
  --mono:  "Space Mono", ui-monospace, monospace;
  --grain: 0.04;
}

/* ── 4b · ARCHIVAL HC - same sepia paper, much darker ink for readability.
   Applied alongside .theme-archival (so it inherits all the archival type/layout);
   declared AFTER it so these darker colour vars win. ─────────────── */
.theme-archival-hc {
  --cream: #110e07; --cream-dim: #3c3527; --cream-faint: #645941;
  --paper-edge: #bcb093;
  --cool: #3a5457; --cool-deep: #294043;
  --teal: #64501f; --teal-deep: #4c3c1c;
  --amber: #842b20; --amber-glow: #9a3624; --rose: #763229;
}

/* ── 5 · SOFT CLUB - faded denim / analog, worn-photograph ─────── */
.theme-softclub {
  --ink: #e6e0d2; --glow-1: #bfccd7; --glow-2: #e1d4c0;   /* denim mist + warm sand */
  --ink-2: #f0ebdd; --ink-3: #f6f1e5;
  --cream: #323a42; --cream-dim: #6e7780; --cream-faint: #9aa0a2;  /* washed indigo ink */
  --paper-edge: #d0cab8;
  --cool: #4c667b; --cool-deep: #354b5e;          /* faded denim blue, AA as text */
  --teal: #7e9580; --teal-deep: #5d7560;          /* dusty sage */
  --amber: #b76a45; --amber-glow: #cd855f; --rose: #a8707e;  /* soft rust */
  --on-accent: #f6f1e5;
  --radius: 14px;
  --serif: "Fraunces", Georgia, serif;
  --read:  "Hanken Grotesk", system-ui, sans-serif;
  --mono:  "Spline Sans Mono", ui-monospace, monospace;
  --grain: 0.05;
}

/* ── 6 · NEURONS - deep space, neon synapses. The neurons.fun house look.
   Semantics stay identical to every other theme, so the whole app inherits
   it for free; --cool carries the cyan "neuron activity" signal, --teal the
   violet "pathway" signal, and --neon-green is the CTA-only accent. ───── */
.theme-neurons {
  --ink: #0B0F19; --glow-1: #14103a; --glow-2: #062231;
  --ink-2: #111726; --ink-3: #172033;
  --cream: #FFFFFF; --cream-dim: #A1A1AA; --cream-faint: #64647a;
  --paper-edge: #232c44;
  --cool: #00F2FE; --cool-deep: #00D2FF;
  --teal: #8A2BE2; --teal-deep: #7928CA;
  --amber: #00F2FE; --amber-glow: #7df9ff; --rose: #ff5ea8;
  --on-accent: #04070F;
  /* CTA-only neon green - deliberately outside the semantic ramp so it stays rare */
  --neon-green: #39FF88; --neon-green-deep: #0fd96a;
  --radius: 10px;
  --serif: "Bricolage Grotesque", system-ui, sans-serif;
  --read:  "Hanken Grotesk", system-ui, sans-serif;
  --mono:  "Spline Sans Mono", ui-monospace, monospace;
  --grain: 0.055;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  background:
    radial-gradient(1100px 700px at 78% -8%, var(--glow-1) 0%, transparent 60%),
    radial-gradient(900px 600px at -10% 12%, var(--glow-2) 0%, transparent 55%),
    var(--ink);
  color: var(--cream);
  font-family: var(--read);
  line-height: 1.55; -webkit-font-smoothing: antialiased;
  min-height: 100vh; overflow-x: hidden;
  transition: background-color .4s ease, color .4s ease;
}

/* ── Page-wide circuit backdrop ─────────────────────────────────
   The same generator as the hero, run sparse and dropped to a whisper. Fixed
   rather than scrolled, so it reads as something the page sits on instead of
   as content; negative z-index so it is behind every view without needing a
   stacking rule on any of them, and pointer-events off so nothing on the page
   loses a click to it.

   The opacity is the whole safeguard. Text sits directly over this, and at a
   fifth it registers as texture rather than as lines - visible if you look
   for it, invisible while you are reading. The landing hides it outright:
   .hero-circuit is already there at full strength and two boards stacked
   would just read as noise. */
.site-circuit {
  position: fixed; inset: 0; z-index: -1;
  width: 100vw; height: 100vh; height: 100svh;
  display: block; pointer-events: none;
  opacity: 0.2;
}
body.on-landing .site-circuit { opacity: 0; }
/* the light themes need it fainter still - dark traces on pale paper carry
   much further than the same lines do on ink */
.theme-editorial .site-circuit, .theme-archival .site-circuit,
.theme-softclub .site-circuit { opacity: 0.1; }

.grain {
  position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  opacity: var(--grain); mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── Masthead ──────────────────────────────────────────────────── */
.masthead {
  position: sticky; top: 0; z-index: 50; padding: 22px 28px 0;
  background: linear-gradient(var(--ink) 60%, transparent);
  backdrop-filter: blur(3px);
}
.masthead-inner {
  max-width: var(--maxw); margin: 0 auto;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap;
}
.brand { display: flex; align-items: baseline; gap: 13px; flex-wrap: wrap; }
/* the emblem lifted out of the neurons.fun lockup (replaced the old SVG mark) */
.brand-glyph { width: 26px; height: 26px; align-self: center; flex-shrink: 0; object-fit: contain; }
@keyframes nodepulse { 0%,100%{opacity:.82;} 50%{opacity:1;} }
.brand h1 { font-family: var(--serif); font-weight: 700; font-size: 2.3rem; letter-spacing: -0.02em; line-height: 0.9; }
.theme-editorial .brand h1, .theme-softclub .brand h1 { font-weight: 400; letter-spacing: -0.01em; }
.theme-archival .brand h1 { font-weight: 700; font-size: 2rem; letter-spacing: -0.04em; }
.tagline { font-family: var(--read); font-style: italic; color: var(--cream-dim); font-size: 0.95rem; flex-basis: 100%; }
.theme-archival .tagline { font-style: normal; }
.masthead-right { display: flex; flex-direction: row; align-items: center; gap: 8px; }
.brand { cursor: pointer; }

/* ── Condense-on-scroll ────────────────────────────────────────────
   The full filters live in normal page flow and just scroll up out of view
   (sliding under the sticky masthead). Once they're gone, the masthead shows
   the compact "filters (N)" pill. Nothing collapses in place. */
.filter-sentinel { height: 1px; pointer-events: none; }
.masthead { transition: padding .25s ease; }
/* condensed: tighter top gap, and a real bottom gap (the .filters margin scrolls away when
   minimized, so the masthead has to provide the separation itself) + solid bg so the
   scrolling content doesn't bleed through the gap */
.scrolled .masthead { padding-top: 6px; padding-bottom: 11px; }
/* condensed: the eyebrow hides, so right-align the lone picker group (desktop + mobile) */
.scrolled .masthead-inner { align-items: center; justify-content: flex-end; }
.scrolled .tagline { display: none; }
.scrolled .brand h1 { font-size: 1.55rem; }
.scrolled .brand-glyph { width: 22px; height: 22px; }
/* the "filters (N)" pill on the condensed line */
.scroll-peek {
  display: none; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.03em; text-transform: lowercase;
  color: var(--cream); background: linear-gradient(160deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: 8px; padding: 6px 11px; cursor: pointer;
  transition: border-color .2s;
}
.scroll-peek:hover { border-color: var(--cool-deep); }
.scroll-peek .peek-chev { color: var(--cream-faint); }
.scroll-peek .peek-count {
  font-size: 0.6rem; color: var(--on-accent); background: var(--amber);
  border-radius: 100px; padding: 1px 6px; min-width: 16px; text-align: center;
}
.scroll-peek .peek-count:empty { display: none; }
.scrolled .scroll-peek { display: inline-flex; }

/* ── Custom dropdown ───────────────────────────────────────────── */
.dropdown { position: relative; }
.dd-trigger {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 0.72rem; color: var(--cream);
  background: linear-gradient(160deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: 8px;
  padding: 7px 12px; cursor: pointer; transition: border-color .2s, box-shadow .2s;
}
.dd-trigger:hover { border-color: var(--cool-deep); }
.dropdown.open .dd-trigger { border-color: var(--cool-deep); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool-deep) 18%, transparent); }
.dd-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); box-shadow: 0 0 8px var(--amber); flex-shrink: 0; }
.dd-chev { color: var(--cream-faint); transition: transform .25s ease; }
.dropdown.open .dd-chev { transform: rotate(180deg); }
.dd-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 226px; list-style: none; padding: 6px;
  background: linear-gradient(170deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: 11px;
  box-shadow: 0 18px 50px rgba(0,0,0,.4), 0 0 0 1px rgba(0,0,0,.05);
  opacity: 0; transform: translateY(-6px) scale(.98); transform-origin: top right;
  pointer-events: none; transition: opacity .2s ease, transform .2s cubic-bezier(.2,.8,.2,1);
}
.dropdown.open .dd-menu { opacity: 1; transform: none; pointer-events: auto; }
.dd-item {
  display: flex; align-items: center; gap: 11px; padding: 8px 10px;
  border-radius: 8px; cursor: pointer; transition: background .15s ease; position: relative;
}
.dd-item:hover { background: color-mix(in srgb, var(--cool) 12%, transparent); }
.dd-text { display: flex; flex-direction: column; gap: 1px; }
.dd-name { font-family: var(--read); font-size: 0.92rem; color: var(--cream); }
.dd-meta { font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); letter-spacing: 0.02em; }
.dd-item.selected { background: color-mix(in srgb, var(--amber) 13%, transparent); }
.dd-item.selected::after { content: "✓"; position: absolute; right: 11px; color: var(--amber); font-size: 0.8rem; }
/* swatches show each theme's own palette regardless of active theme */
.dd-sw { width: 30px; height: 30px; border-radius: 7px; flex-shrink: 0; border: 1px solid rgba(0,0,0,.25); }
.sw-neurons   { background: linear-gradient(135deg, #0B0F19 34%, #00F2FE 34% 56%, #7928CA 56% 78%, #39FF88 78%); }
.sw-technical { background: linear-gradient(135deg, #14161c 38%, #7fb0c9 38% 64%, #e6a94b 64%); }
.sw-midnight  { background: linear-gradient(135deg, #11122a 38%, #6ea8ff 38% 58%, #4fe0c8 58% 78%, #ff7ec0 78%); }
.sw-editorial { background: linear-gradient(135deg, #f3ece0 40%, #2f6480 40% 70%, #b25a26 70%); }
.sw-archival  { background: linear-gradient(135deg, #e7dfcf 40%, #4f6b6e 40% 68%, #9c3b2e 68%); }
.sw-archival-hc { background: linear-gradient(135deg, #e7dfcf 38%, #110e07 38% 60%, #842b20 60%); }
.sw-softclub  { background: linear-gradient(135deg, #e6e0d2 32%, #5d7c96 32% 55%, #7e9580 55% 77%, #b76a45 77%); }

/* ── Filters ───────────────────────────────────────────────────── */
.filters {
  max-width: var(--maxw); margin: 4px auto 22px; padding: 0 28px 18px;
  border-bottom: 1px solid var(--paper-edge);
  display: flex; flex-direction: column; gap: 6px;
}
.filter-head { display: flex; align-items: center; gap: 10px; }
.active-count {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.04em; color: var(--amber);
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent); border-radius: 100px; padding: 2px 9px;
}
.sort-toggle, .filter-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.04em; color: var(--cream-dim);
  background: transparent; border: 1px solid var(--paper-edge); border-radius: 100px;
  padding: 5px 12px; cursor: pointer; transition: all .18s ease; text-transform: lowercase;
}
/* .sort-view is what pushes this group to the right edge, and it keeps the
   sort button and the view switch on one line in that order - loose in a
   wrapping flex row they came apart on a phone and the switch ended up above
   and to the left of the button it is meant to sit beside. */
.sort-view { display: inline-flex; align-items: center; gap: 9px; margin-left: auto; flex: none; }
.sort-toggle { margin-left: 0; }
.filter-head .view-switch { flex: none; }
.filter-toggle { margin-left: 0; }
.sort-toggle:hover, .filter-toggle:hover { color: var(--cream); border-color: var(--cool-deep); }
.sort-toggle #sortLabel { font-variant-numeric: tabular-nums; }
.filter-toggle svg { color: var(--cream-faint); }
.filters.expanded .filter-toggle { color: var(--on-accent); background: var(--cream); border-color: var(--cream); }
.filters.expanded .filter-toggle svg { color: var(--on-accent); }

.filter-rows { display: contents; }   /* dropdowns sit inline in the filter-head, next to search */
.filter-row { display: grid; grid-template-columns: 50px 1fr; align-items: center; gap: 10px; }
.filter-label {
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--cream-faint); text-align: right; align-self: center;
}
.chip-wrap { display: flex; gap: 6px; }
.filters.compact .chip-wrap {
  flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding: 2px 18px 2px 0;
  -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent 100%);
          mask-image: linear-gradient(90deg, #000 88%, transparent 100%);
}
.filters.compact .chip-wrap::-webkit-scrollbar { display: none; }
.filters.expanded { max-height: 70vh; overflow-y: auto; padding-bottom: 16px; }
.filters.expanded .chip-wrap { flex-wrap: wrap; }
.filters.expanded .filter-row { align-items: start; }
.filters.expanded .filter-label { padding-top: 5px; }
.filters.expanded { background: var(--ink); border-radius: 0 0 12px 12px; box-shadow: 0 22px 44px rgba(0,0,0,.3); }
.filters.expanded .filter-head { position: sticky; top: 0; z-index: 2; background: var(--ink); padding: 2px 0 6px; }

.filter-scrim {
  position: fixed; inset: 0; z-index: 45; background: color-mix(in srgb, var(--ink) 60%, transparent);
  backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity .25s ease;
}
.filter-scrim.open { opacity: 1; pointer-events: auto; }

.chip {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.02em;
  color: var(--cream-dim); background: transparent; flex-shrink: 0;
  border: 1px solid var(--paper-edge); border-radius: 100px;
  padding: 4px 11px; cursor: pointer; transition: all .16s ease; text-transform: lowercase; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
}
.chip:hover { color: var(--cream); border-color: var(--cool-deep); }
.chip.active { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 500; }
.chip-focus.active  { background: var(--cool); border-color: var(--cool); color: var(--on-accent); }
.chip-impact.active { background: var(--teal); border-color: var(--teal); color: var(--on-accent); }
.chip-idea.active   { background: var(--amber); border-color: var(--amber); color: var(--on-accent); }
.chip-reset { letter-spacing: 0.1em; text-transform: uppercase; font-size: 0.6rem; flex-shrink: 0; }

/* org chip logo */
.chip-logo { width: 14px; height: 14px; border-radius: 3px; object-fit: contain; background: #fff; }
.chip-org .chip-logo-fallback {
  width: 14px; height: 14px; border-radius: 3px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.5rem; font-weight: 700; background: var(--cool-deep); color: #fff;
}

/* ── Faceted filter dropdowns (org / focus / impact) ───────────── */
.filter-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.type-chips { -webkit-mask-image: none; mask-image: none; overflow: visible; padding: 0; }
/* dropdowns replace the "all filters" expand affordance */
.filter-toggle { display: none; }
.fdd { position: relative; }
.fdd-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.04em; text-transform: lowercase;
  color: var(--cream-dim); background: transparent;
  border: 1px solid var(--paper-edge); border-radius: 100px;
  padding: 5px 12px; cursor: pointer; transition: all .16s ease;
}
.fdd-btn:hover, .fdd-btn.on { color: var(--cream); border-color: var(--cool-deep); }
.fdd.open .fdd-btn { border-color: var(--cool-deep); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool-deep) 18%, transparent); }
.fdd-badge {
  font-family: var(--mono); font-size: 0.56rem; line-height: 1; font-weight: 600;
  min-width: 15px; height: 15px; padding: 0 4px; border-radius: 100px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--amber); color: var(--on-accent);
}
.fdd-badge[hidden] { display: none; }
.fdd-chev { color: var(--cream-faint); transition: transform .2s ease; }
.fdd.open .fdd-chev { transform: rotate(180deg); }
.fdd-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  background: linear-gradient(170deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: 12px;
  box-shadow: 0 22px 50px -16px rgba(0,0,0,.55);
  padding: 9px; min-width: 200px; max-width: 340px;
}
.fdd:last-child .fdd-panel { left: auto; right: 0; }
.fdd-list { display: flex; flex-wrap: wrap; gap: 6px; max-height: 320px; overflow-y: auto; }
.fdd-list .chip { white-space: normal; }

/* ── View switch (Timeline / Tree) ─────────────────────────────── */
.view-switch { display: inline-flex; border: 1px solid var(--paper-edge); border-radius: 100px; overflow: hidden; background: var(--ink-2); }
/* sized to the sort/filter pills it now shares a line with, and rounded to
   match them - it used to sit on the masthead among taller controls */
.view-btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 25px; background: transparent; border: none; color: var(--cream-faint); cursor: pointer; transition: background .15s, color .15s; }
.view-btn svg { width: 15px; height: 15px; }
.view-btn:not(.active):hover { color: var(--cream); }
.view-btn.active { background: var(--cream); color: var(--on-accent); }

/* ── Graph view (force-directed node-link network) ─────────────── */
.graph { position: relative; max-width: var(--maxw); margin: 0 auto; padding: 24px 28px 50px; }
.g-tip {
  position: absolute; z-index: 30; pointer-events: none; left: 0; top: 0;
  width: 264px; max-width: 76vw;
  background: linear-gradient(165deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: 11px;
  box-shadow: 0 16px 44px -14px rgba(0,0,0,.6);
  padding: 12px 13px 13px; font-family: var(--read);
  animation: gtipIn .13s ease;
}
.g-tip[hidden] { display: none; }
@keyframes gtipIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.gt-head { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.gt-logo { width: 17px; height: 17px; border-radius: 4px; object-fit: contain; background: #fff; padding: 1px; flex-shrink: 0; }
.gt-head .org-fallback { width: 17px; height: 17px; font-size: 0.5rem; border-radius: 4px; flex-shrink: 0; }
.gt-org { font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--cool); }
.gt-year { margin-left: auto; font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); }
.gt-title { font-family: var(--serif); font-weight: 600; font-size: 0.98rem; line-height: 1.18; letter-spacing: -0.01em; color: var(--cream); margin-bottom: 5px; }
.gt-sum { font-size: 0.76rem; line-height: 1.42; color: var(--cream-dim); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.gt-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 9px; }
.graph-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.graph-head-label { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cream-faint); }
.graph-reset { font-family: var(--mono); font-size: 0.64rem; color: var(--cream-dim); background: transparent; border: 1px solid var(--paper-edge); border-radius: 100px; padding: 4px 12px; cursor: pointer; transition: all .18s; text-transform: lowercase; }
.graph-reset:hover { color: var(--cream); border-color: var(--cool-deep); }
#graphSvg {
  width: 100%; height: 76vh; min-height: 440px; display: block;
  border: 1px solid var(--paper-edge); border-radius: 14px;
  background: radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--cool) 7%, transparent), transparent 68%), var(--ink-2);
  touch-action: none; cursor: grab;
}
#graphSvg.panning { cursor: grabbing; }
.gyear-line { stroke: var(--paper-edge); stroke-width: 1; opacity: 0.4; }
.gyear-label { font-family: var(--mono); font-size: 15px; fill: var(--cream-faint); opacity: 0.7; letter-spacing: 0.05em; }
.gedge { stroke-width: 1; opacity: 0.28; vector-effect: non-scaling-stroke; transition: opacity .2s, stroke-width .2s; }
.gedge.cool  { stroke: var(--cool-deep); }
.gedge.teal  { stroke: var(--teal-deep); }
.gedge.rose  { stroke: var(--rose); stroke-dasharray: 4 4; }
.gedge.amber { stroke: var(--amber); }
.gedge.hl    { opacity: 0.95; stroke-width: 2; }
.gedge.faded { opacity: 0.05; }
.gedge.gfiltered { opacity: 0.03; }
.gnode { cursor: pointer; }
.gnode circle { fill: var(--cool); stroke: var(--ink); stroke-width: 1.5; transition: fill .2s, stroke .2s; }
.gnode.idea circle { fill: var(--amber); }
.gnode text {
  font-family: var(--mono); font-size: 12.5px; fill: var(--cream-dim); pointer-events: none;
  paint-order: stroke; stroke: var(--ink); stroke-width: 3px; stroke-linejoin: round;
}
.gnode.idea text { fill: var(--amber-glow); }
.gnode.hl circle { stroke: var(--cream); stroke-width: 2.5; }
.gnode.hl text { fill: var(--cream); font-size: 15px; }
.gnode.faded { opacity: 0.2; }
.gnode.gfiltered { opacity: 0.06; pointer-events: none; }

/* ── Timeline ──────────────────────────────────────────────────── */
.timeline { position: relative; max-width: var(--maxw); margin: 0 auto; padding: 50px 28px 140px; }
.connections { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; overflow: visible; }
.spine {
  position: absolute; top: 50px; bottom: 140px; left: calc(var(--spine-x) + 28px); width: 2px;
  background: linear-gradient(var(--paper-edge), var(--cool-deep) 40%, var(--paper-edge)); opacity: 0.6; z-index: 0;
}
.nodes { position: relative; z-index: 2; }

.era { position: relative; margin: 36px 0 20px; padding-left: calc(var(--spine-x) + 60px); }
.era:first-child { margin-top: 0; }
.era-label { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--cream-faint); }

.row {
  position: relative; display: grid; grid-template-columns: var(--spine-x) 1fr; margin: 14px 0; align-items: start;
  opacity: 0; transform: translateY(14px); animation: rise .6s cubic-bezier(.2,.7,.2,1) forwards;
}
@keyframes rise { to { opacity: 1; transform: none; } }
.row-date { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); text-align: right; padding: 18px 30px 0 0; white-space: nowrap; letter-spacing: 0.02em; }

/* ── Spine node: a clean dot on the line (idea = sparkle) ───────── */
.bead {
  position: absolute; left: calc(var(--spine-x) + 23px); top: 21px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--cool); border: 2px solid var(--ink);
  display: flex; align-items: center; justify-content: center; z-index: 3;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool) 18%, transparent), 0 0 10px color-mix(in srgb, var(--cool-deep) 65%, transparent);
  transition: transform .2s ease;
}
.row:hover .bead { transform: scale(1.3); }
.row-idea .bead {
  width: 22px; height: 22px; top: 16px; left: calc(var(--spine-x) + 18px);
  background: transparent; border: none; box-shadow: none;
}
.row-idea .bead .idea-spark { width: 22px; height: 22px; color: var(--amber); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--amber) 70%, transparent)); }

/* ── Card ──────────────────────────────────────────────────────── */
.card {
  position: relative; margin-left: 30px;
  display: flex; gap: 15px; align-items: flex-start;
  background: linear-gradient(155deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: var(--radius);
  padding: 15px 20px 16px; cursor: pointer; max-width: 720px;
  transition: transform .2s cubic-bezier(.2,.7,.2,1), border-color .2s, box-shadow .25s;
}
.card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--cool-deep); border-radius: var(--radius) 0 0 var(--radius); opacity: .8; }
.card:hover { transform: translateX(5px); border-color: var(--cool-deep); box-shadow: -2px 8px 30px rgba(0,0,0,.18); }

/* org logo lives on the card now (off the line) */
.card-logo {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 11px;
  background: #fff; border: 1px solid var(--paper-edge); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 5px rgba(0,0,0,.15);
}
.card-logo-img { width: 27px; height: 27px; object-fit: contain; }
.card-logo-fallback { font-family: var(--mono); font-weight: 700; font-size: 0.82rem; color: var(--cool-deep); }
.row-idea .card-logo { background: color-mix(in srgb, var(--amber) 16%, var(--ink-3)); border-color: color-mix(in srgb, var(--amber) 45%, transparent); }
.row-idea .card-logo .idea-spark { width: 26px; height: 26px; color: var(--amber); filter: drop-shadow(0 0 5px color-mix(in srgb, var(--amber) 60%, transparent)); }
.card-main { min-width: 0; flex: 1; }

.card-title { font-family: var(--serif); font-weight: 600; font-size: 1.16rem; letter-spacing: -0.01em; line-height: 1.2; color: var(--cream); }
.theme-editorial .card-title, .theme-softclub .card-title { font-weight: 400; font-size: 1.3rem; line-height: 1.16; }
.theme-archival .card-title { font-size: 0.98rem; letter-spacing: -0.02em; line-height: 1.3; }

.card-byline { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.org-name { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.03em; color: var(--cream); }
.org-name::after { content: "·"; margin-left: 8px; color: var(--cream-faint); }
.card-authors { font-family: var(--read); font-style: italic; font-size: 0.86rem; color: var(--cream-dim); }
.theme-archival .card-authors { font-style: normal; }
.card-contrib { font-size: 0.95rem; color: var(--cream-dim); margin-top: 9px; line-height: 1.5; }
.card-meta { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 12px; align-items: center; }

.tag { font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.03em; border-radius: 3px; padding: 2px 7px; white-space: nowrap; }
.tag-focus  { color: var(--cool); background: color-mix(in srgb, var(--cool) 12%, transparent); border: 1px solid color-mix(in srgb, var(--cool) 28%, transparent); }
.tag-impact { color: var(--teal); background: color-mix(in srgb, var(--teal) 12%, transparent); border: 1px solid color-mix(in srgb, var(--teal) 28%, transparent); }
.venue { font-family: var(--mono); font-size: 0.62rem; color: var(--cream-faint); margin-left: auto; }
.conn-count { font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); }

/* ── Idea variant ──────────────────────────────────────────────── */
.row-idea .card { background: linear-gradient(155deg, color-mix(in srgb, var(--amber) 12%, var(--ink-3)), color-mix(in srgb, var(--amber) 6%, var(--ink-2))); border-color: color-mix(in srgb, var(--amber) 35%, transparent); }
.row-idea .card::before { background: var(--amber); box-shadow: 0 0 12px var(--amber); }
.row-idea .card:hover { border-color: var(--amber); box-shadow: -2px 8px 34px color-mix(in srgb, var(--amber) 18%, transparent); }
.row-idea .card-title { color: color-mix(in srgb, var(--amber) 60%, var(--cream)); }
.row-idea .card-title::before { content: "idea"; font-family: var(--mono); font-size: 0.56rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--amber); display: block; margin-bottom: 4px; opacity: .85; }
.status { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.06em; text-transform: uppercase; padding: 2px 7px; border-radius: 3px; color: var(--amber); border: 1px solid color-mix(in srgb, var(--amber) 35%, transparent); }
.row.hidden { display: none; }

/* ── Detail panel ──────────────────────────────────────────────── */
.scrim { position: fixed; inset: 0; z-index: 80; background: color-mix(in srgb, var(--ink) 62%, transparent); backdrop-filter: blur(3px); opacity: 0; pointer-events: none; transition: opacity .3s ease; }
.scrim.open { opacity: 1; pointer-events: auto; }
/* centered modal (paper or person) */
.panel {
  position: fixed; z-index: 90;
  top: 50%; left: 50%;
  width: min(680px, calc(100vw - 36px)); max-height: min(86vh, 860px);
  background:
    radial-gradient(900px 600px at 80% -5%, var(--glow-1) 0%, transparent 60%),
    linear-gradient(170deg, var(--ink-3), var(--ink));
  border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px);
  box-shadow: 0 32px 90px -20px rgba(0,0,0,.6), 0 8px 30px -10px rgba(0,0,0,.45);
  transform: translate(-50%, calc(-50% + 18px)) scale(.98); opacity: 0; pointer-events: none;
  transition: transform .34s cubic-bezier(.3,.8,.2,1), opacity .26s ease; overflow-y: auto;
}
.panel.open { transform: translate(-50%, -50%); opacity: 1; pointer-events: auto; }
.panel-body { max-width: none; margin: 0; padding: 46px 40px 48px; }
@media (max-width: 560px) {
  .panel { width: calc(100vw - 20px); max-height: 90vh; }
  .panel-body { padding: 44px 22px 36px; }
}
.panel-close {
  position: sticky; top: 14px; float: right; margin: 14px 14px -38px 0; z-index: 3;
  width: 38px; height: 38px; border-radius: 50%;
  background: color-mix(in srgb, var(--cream) 8%, transparent); border: 1px solid var(--paper-edge);
  color: var(--cream-dim); font-size: 0.95rem; cursor: pointer; font-family: var(--mono);
  display: flex; align-items: center; justify-content: center; transition: color .2s, border-color .2s, background .2s;
}
.panel-close:hover { color: var(--cream); border-color: var(--cool-deep); background: color-mix(in srgb, var(--cream) 14%, transparent); }
.p-kicker { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cool); margin-bottom: 10px; }
.p-kicker.idea { color: var(--amber); }
.p-title { font-family: var(--serif); font-weight: 600; font-size: 1.62rem; line-height: 1.14; letter-spacing: -0.015em; margin-bottom: 8px; }
.theme-editorial .p-title, .theme-softclub .p-title { font-weight: 400; font-size: 1.8rem; }
.theme-archival .p-title { font-size: 1.25rem; letter-spacing: -0.03em; }
.p-authors { font-style: italic; color: var(--cream-dim); margin-bottom: 4px; }
.p-date { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); margin-bottom: 20px; }
.p-section { margin: 18px 0; }
.p-section h4 { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cream-faint); margin-bottom: 8px; font-weight: 500; }
.p-section p { font-size: 1.0rem; color: var(--cream); line-height: 1.6; }
.p-org { display: inline-flex; align-items: center; gap: 9px; font-family: var(--mono); font-size: 0.9rem; color: var(--cream); background: color-mix(in srgb, var(--cream) 7%, transparent); border: 1px solid color-mix(in srgb, var(--cream) 18%, transparent); border-radius: 6px; padding: 6px 13px 6px 8px; }
.p-org img { width: 22px; height: 22px; object-fit: contain; border-radius: 4px; background: #fff; }
.p-org .org-fallback { width: 22px; height: 22px; border-radius: 4px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.66rem; font-weight: 700; background: var(--cool-deep); color: #fff; }
.p-contrib { background: color-mix(in srgb, var(--cool) 8%, transparent); border-left: 2px solid var(--cool-deep); padding: 11px 15px; border-radius: 0 4px 4px 0; font-style: italic; }
.p-contrib.idea { background: color-mix(in srgb, var(--amber) 10%, transparent); border-color: var(--amber); }
.p-conn { display: flex; align-items: center; gap: 8px; padding: 9px 0; border-bottom: 1px solid var(--paper-edge); cursor: pointer; transition: padding-left .18s ease; }
.p-conn:hover { padding-left: 6px; }
.p-conn:last-child { border-bottom: none; }
.p-rel { font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); white-space: nowrap; min-width: 92px; text-transform: lowercase; }
.p-conn-title { font-size: 0.92rem; color: var(--cool); }
.idea-card .p-conn-title { color: var(--amber); }
.p-link { display: inline-flex; align-items: center; gap: 7px; margin-top: 8px; font-family: var(--mono); font-size: 0.72rem; color: var(--cool); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color .2s; }
.p-link:hover { border-color: var(--cool); }
.p-tags { display: flex; gap: 7px; flex-wrap: wrap; }

/* ── Footer ────────────────────────────────────────────────────── */
.foot {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
  display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 12px 28px; flex-wrap: wrap;
  background: linear-gradient(transparent, var(--ink) 40%);
  font-family: var(--mono); font-size: 0.64rem; color: var(--cream-faint); letter-spacing: 0.02em;
}
.foot-count { color: var(--cream-dim); }

/* ── Connection paths ──────────────────────────────────────────── */
.conn-path { fill: none; stroke-width: 1.4; opacity: 0.32; transition: opacity .25s, stroke-width .25s; }
.conn-path.cool  { stroke: var(--cool-deep); }
.conn-path.rose  { stroke: var(--rose); stroke-dasharray: 4 4; }
.conn-path.amber { stroke: var(--amber); opacity: 0.45; }
.conn-path.lit   { opacity: 0.95; stroke-width: 2.2; }
.conn-path.faded { opacity: 0.07; }

/* ── Responsive ────────────────────────────────────────────────── */
@media (max-width: 720px) {
  :root { --spine-x: 50px; }
  .masthead { padding: 7px 16px 0; }   /* close the gap under the navbar */
  .masthead-inner { align-items: center; }
  .masthead-right { align-items: flex-end; }
  .brand h1 { font-size: 1.7rem; }
  .tagline { display: none; }
  .dd-trigger { padding: 6px 10px; font-size: 0.68rem; }
  .dd-menu { right: 0; min-width: 210px; }

  .filters { margin-top: 10px; }
  /* condensed → keep it to ONE line on mobile */
  .scrolled .masthead { padding-top: 4px; }   /* no extra gap under the navbar when minimized */
  .scrolled .masthead-inner { flex-wrap: nowrap; gap: 8px; }
  .scrolled .brand h1 { font-size: 1.3rem; }
  .scrolled .scroll-peek { padding: 6px 9px; }
  .scrolled .scroll-peek .peek-word { display: none; }
  .filter-label { font-size: 0.55rem; }
  .filter-row { grid-template-columns: 42px 1fr; gap: 8px; }
  .filters.expanded { max-height: 64vh; }

  .row-date { position: absolute; top: -4px; left: 0; text-align: left; padding: 0; font-size: 0.64rem; grid-column: 1 / -1; }
  .row { grid-template-columns: 1fr; margin-top: 30px; }
  .card { margin-left: calc(var(--spine-x) + 42px); padding: 13px 15px; gap: 12px; }
  .card-logo { width: 36px; height: 36px; border-radius: 9px; }
  .card-logo-img { width: 23px; height: 23px; }
  .era { padding-left: 0; }
  .connections { display: none; }
  .timeline { padding: 26px 16px 150px; }
  .view-btn { width: 30px; height: 28px; }
  .graph { padding: 16px 14px 30px; }
  #graphSvg { height: 72vh; border-radius: 12px; }
  .gnode text { font-size: 15px; }
}

/* ═══════════════════════════════════════════════════════════════
   NAVBAR · LANDING · SEARCH · LINK ICONS  (front door + extras)
   ═══════════════════════════════════════════════════════════════ */
:root { --nav-h: 66px; }   /* sized off the lockup: the bar has to give it room, not crop it */

/* ── Navbar ────────────────────────────────────────────────────── */
.navbar {
  position: sticky; top: 0; z-index: 70; height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 0 24px;
  background: color-mix(in srgb, var(--ink) 86%, transparent);
  backdrop-filter: blur(9px);
  border-bottom: 1px solid var(--paper-edge);
}
.nav-brand { display: inline-flex; align-items: center; text-decoration: none; color: var(--cream); }
/* The full lockup rather than a mark plus a typeset wordmark. Sized off the
   navbar's own height so it keeps its ratio to the bar at both breakpoints;
   the asset is cropped tight to the artwork, so this height is all logo. */
.nav-lockup {
  height: calc(var(--nav-h) - 12px); width: auto; display: block;
  filter: saturate(0.9) drop-shadow(0 0 9px color-mix(in srgb, #6FD8FF 40%, transparent));
}
/* no plate here either - see .brand-logo on the paper themes */
.theme-editorial .nav-lockup, .theme-archival .nav-lockup, .theme-softclub .nav-lockup {
  background: none;
  padding: 0;
  filter: saturate(0.92) drop-shadow(0 1px 3px color-mix(in srgb, var(--ink) 30%, transparent));
}
.nav-links { display: flex; align-items: center; gap: 6px; }
.nav-link { font-family: var(--mono); font-size: 0.74rem; color: var(--cream-dim); text-decoration: none; padding: 7px 13px; border-radius: 100px; transition: color .18s, background .18s, border-color .18s; border: 1px solid transparent; white-space: nowrap; }
.nav-link:hover { color: var(--cream); }
.nav-cta { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 500; }
.nav-cta:hover { color: var(--on-accent); opacity: 0.88; }

/* ── Landing / hero ────────────────────────────────────────────── */
/* The section is the frame the board is drawn to, so it has to be the whole
   screen: .hero-circuit and .hero-veil are both sized to 100% of this box, and
   when it was content-height the backdrop stopped mid-page and left a bare
   strip of background under it. svh, not vh - on mobile vh is the *expanded*
   viewport, which would push the CTA under the browser chrome on first paint.
   Centring the column rather than padding it down keeps the composition put
   as the topic word types in and out. */
.landing {
  max-width: 960px; margin: 0 auto; position: relative;
  padding: 0 28px;
  min-height: calc(100vh - var(--nav-h));
  min-height: calc(100svh - var(--nav-h));
  display: flex; flex-direction: column; justify-content: center;
}
/* showView() swaps views by toggling the hidden attribute and nothing else, so
   it leans on the UA's [hidden] { display: none }. The display above outranks
   that, which left #home on screen and stacked every other view underneath it.
   Same guard the rest of the sheet uses on any view it gives a display to. */
.landing[hidden] { display: none; }

/* Explicit z-index: the stack is board → veil → copy. DOM order would give
   the same result today, but the board is generated and the veil is tuned
   against it, so saying the order out loud is worth the two declarations. */
.hero { padding: 4vh 0 7vh; text-align: center; position: relative; z-index: 3; }

/* ── Background animation: the free "AI lab" ────────────────────
   Canvas is painted by app.js; it bleeds past .landing's max-width to fill
   the viewport, sits under the hero text, and is softly blurred + masked so
   it never competes with reading. ───────────────────────────────────── */
/* ── The board ──────────────────────────────────────────────────
   Generated by circuit.js, which sizes its bitmap from this element's box, so
   everything about the geometry follows from the CSS here. Bleeds past
   .landing's 960px max-width - that cap is for the copy column, not for the
   backdrop. ─────────────────────────────────────────────────────────── */
.hero-circuit {
  position: absolute; z-index: 0; pointer-events: none;
  top: 0; left: 50%; transform: translateX(-50%);
  width: 100vw; height: 100%;
  display: block;
}
/* the light themes pull the board back a little - circuit.js already redraws
   it in darker tokens there, this just keeps it behind the type */
.theme-editorial .hero-circuit, .theme-archival .hero-circuit,
.theme-softclub .hero-circuit { opacity: 0.82; }

/* ── The veil ────────────────────────────────────────────────────
   The board is drawn dark and sparse and already opens a hole where the copy
   sits, so this is not doing the heavy lifting the old scrim did. What is
   left is a floor: a wide, soft pool under the copy so a packet running a
   trace just outside the hole cannot pull the eye off a line of text, and a
   little weight at the very top where the board runs under the navbar. ── */
.hero-veil {
  position: absolute; z-index: 1; pointer-events: none;
  top: 0; left: 50%; transform: translateX(-50%);
  width: 100vw; height: 100%;
  background:
    radial-gradient(ellipse 46% 42% at 50% 52%,
      color-mix(in srgb, var(--ink) 62%, transparent) 0%,
      color-mix(in srgb, var(--ink) 30%, transparent) 58%,
      transparent 100%),
    linear-gradient(to bottom,
      color-mix(in srgb, var(--ink) 46%, transparent) 0%,
      transparent 14%);
}

/* ── The neurons.fun lockup ─────────────────────────────────────
   Artwork is neon-on-black converted to luminance alpha, so it drops
   straight onto the deep-space background with its halo intact. ── */
.brand-logo {
  /* The asset is cropped tight to the mark now - it carries no padding of its
     own, so this margin is the whole gap to the kicker. */
  margin: 0 auto 26px;
  line-height: 0;
  /* A rise and fall, so the lockup hangs in the board rather than sitting on
     it. 6s was the original and it was too slow to read as float at all - at
     3px a second you only see it if you stare. Half that period and a little
     more travel, which is enough to look afloat and still well short of a bob. */
  animation: brand-float 3.4s ease-in-out infinite;
}
@keyframes brand-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-11px); }
}
.brand-logo img {
  display: block; margin: 0 auto;
  /* Deliberately smaller than the artwork wants to be. At full width the
     lockup was the entire hero and the sentence under it read as a caption;
     at this size the logo introduces the page and the headline carries it.
     Percentage, not vw - the column is the reference, not the viewport.
     Smaller number than it looks: the asset is cropped to the mark, so none
     of this width is spent on empty margin the way it used to be. */
  width: min(500px, 88%); height: auto;
  /* The halo the artwork used to carry was dropped with the cutout - it was
     clipped square by the source's own frame. These put one back, and because
     drop-shadow reads the alpha channel it follows the letterforms instead of
     a bounding box. Two passes: a tight cyan one for the edge, a wide violet
     one for the ambient lift. Slightly desaturated so it lifts the mark off
     the board without going back to reading as a sticker. */
  filter: saturate(0.9)
          drop-shadow(0 0 14px color-mix(in srgb, #6FD8FF 55%, transparent))
          drop-shadow(0 0 40px color-mix(in srgb, #8A5CFF 40%, transparent));
}
/* No blend mode. The lockup used to be screened onto the page because its
   alpha came from luminance - every dark pixel in the artwork was see-through,
   so the letterforms' own black outlines let the backdrop straight through
   and the whole mark read as a half-transparent smudge. The asset now carries a
   real cutout: a filled silhouette at full opacity, with only the outer glow
   falling off. Screening that would erase the black outlines it depends on. */
/* The light themes have nothing dark for the neon to sit on, so the lockup
   gets its own plate. A rounded card with a hard edge, not the soft radial
   blob this used to be: the blob read as a smudge on the paper, whereas a
   plate reads as the deliberate thing it is - a logo supplied on dark. */
/*  The paper themes used to put the lockup on a black plate, on the theory
    that neon needs something dark under it. On cream it read as a sticker
    pasted onto the page - a hard black slab in the middle of warm paper, and
    a second little one up in the navbar. The artwork does not need it: it is
    RGBA with its own dark outlines around every letterform, so it holds on
    paper by itself. A soft ink shadow in place of the plate gives the glow
    something to sit against without drawing a box around it. */
.theme-editorial .brand-logo, .theme-archival .brand-logo, .theme-softclub .brand-logo {
  background: none;
  padding: 0;
  box-shadow: none;
}
.theme-editorial .brand-logo img, .theme-archival .brand-logo img, .theme-softclub .brand-logo img {
  filter: drop-shadow(0 2px 5px color-mix(in srgb, var(--ink) 26%, transparent))
          drop-shadow(0 10px 30px color-mix(in srgb, var(--ink) 16%, transparent));
}

/* ── Dynamic header: Explore… <rotating topic> ─────────────────── */
/* ── Copy column ────────────────────────────────────
   Measure and rhythm only - no ground of its own. The copy used to sit on a
   frosted card, which solved contrast but read as a widget parked on a
   backdrop rather than a title sequence. The scrim above does that work now,
   and the type sits directly on the board.
   Narrower than the old panel on purpose: with no frame drawn around it, the
   line length is the only thing holding the column together. */
.hero-copy {
  position: relative;
  max-width: 620px; margin: 0 auto;
}

/* Centring a phrase and typing it look like a contradiction - typing grows
   the line letter by letter, so a centred phrase slides on every keystroke -
   but the conflict is really between typing and a CHANGING width, not
   between typing and centring. So the width does not change while typing:
   the topic's box is set to that topic's finished width before its first
   character lands. "Explore…" cannot move, because nothing to its right is
   growing. The line only has to re-centre when the topic itself changes, and
   that happens while the box is empty - there is nothing on screen to see
   shift, and the box glides to its new width instead of jumping. */
.hero-explore {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.5rem, 5vw, 2.6rem); line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0 0 30px;
  white-space: nowrap;
  min-height: 1.3em;
}
.ex-right { padding-left: 0.3em; }
.ex-verb { color: var(--cream); }
.ex-dots { color: var(--cream-faint); }

/* the rotating word is a real button - clicking it jumps to that topic.
   landing.js reserves min-width for the longest topic, so swapping a word
   never re-flows the line; the word centres inside that reserved box. */
.ex-word {
  font: inherit;
  background: none; border: none; padding: 0;
  color: var(--cool);
  /* its shadow is set with the rest of the hero type, further down */
  /* the box is sized by landing.js to the finished topic, and the text is
     left-aligned inside it so characters land rightward from a fixed point */
  display: inline-block;
  text-align: left;
  white-space: pre;
  transition: color .2s, width .42s cubic-bezier(.22, .9, .3, 1);
  cursor: default;
}
/* The caret as a pseudo-element rather than its own span: inside a
   fixed-width box a sibling would sit at the box's right edge, half a word
   away from the last character typed. This one trails the text. */
.ex-word::after {
  content: "";
  display: inline-block;
  width: 0.06em; height: 0.92em;
  vertical-align: -0.12em; margin-left: 0.05em;
  background: var(--cool);
  box-shadow: 0 0 10px color-mix(in srgb, var(--cool) 70%, transparent);
  animation: ex-caret-blink 1.05s step-end infinite;
}
@keyframes ex-caret-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
/* only offer the click once the topic is fully typed */
.hero-explore.typed .ex-word { cursor: pointer; }
.hero-explore.typed .ex-word:hover { color: var(--neon-green, var(--amber)); }
.ex-word:focus-visible { outline: 2px solid var(--cool); outline-offset: 4px; border-radius: 3px; }

/* ── Jump In - the one neon-green control on the page ──────────── */
.btn-jump {
  font-family: var(--mono); font-size: 0.92rem; font-weight: 600;
  letter-spacing: 0.01em;
  padding: 14px 34px;
  color: var(--on-accent);
  background: linear-gradient(135deg, var(--neon-green, var(--teal)), var(--neon-green-deep, var(--teal-deep)));
  border: 1px solid var(--neon-green, var(--teal));
  border-radius: 100px; cursor: pointer;
  box-shadow: 0 0 0 color-mix(in srgb, var(--neon-green, var(--teal)) 60%, transparent);
  transition: transform .2s ease, box-shadow .3s ease, filter .2s ease;
  animation: jump-pulse 2.8s ease-in-out infinite;
}
.btn-jump:hover {
  transform: translateY(-2px) scale(1.03);
  filter: brightness(1.1);
  box-shadow: 0 10px 34px color-mix(in srgb, var(--neon-green, var(--teal)) 55%, transparent),
              0 0 22px color-mix(in srgb, var(--neon-green, var(--teal)) 45%, transparent);
  animation-play-state: paused;
}
.btn-jump:focus-visible { outline: 2px solid var(--cream); outline-offset: 4px; }

/*  The CTA on the paper themes ─────────────────────────────────
    .btn-jump paints --on-accent on the accent fill. On the dark themes that
    is near-black on neon and clears AA many times over, but on the paper
    themes --on-accent is a cream and their accents are not deep enough to
    carry it: softclub measured 2.87:1, under even the 3:1 large-text floor,
    with editorial at 4.48 and archival at 4.05 just short of the 4.5:1 this
    text size needs (0.92rem/600 is below the 18.66px bold that would let it
    count as large).

    Deepened for this one control rather than by moving --teal, which chips,
    the nav CTA and the filter toggle all paint --on-accent on as well at
    quite different sizes. Derived from each theme's own --teal-deep so the
    hue stays theirs; the pair below puts softclub, the worst case, at
    5.44:1 at rest and 5.30:1 under the hover brightness, and the others
    above 7:1. */
.theme-editorial .btn-jump, .theme-archival .btn-jump, .theme-softclub .btn-jump {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--teal-deep) 88%, #000),
    color-mix(in srgb, var(--teal-deep) 74%, #000));
  border-color: color-mix(in srgb, var(--teal-deep) 88%, #000);
}
@keyframes jump-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--neon-green, var(--teal)) 45%, transparent); }
  60%      { box-shadow: 0 0 0 16px transparent; }
}

/* respect a stated preference for less motion - kill the loops, keep the look */
@media (prefers-reduced-motion: reduce) {
  .brand-logo { animation: none; }
  .btn-jump { animation: none; }
  .ex-word { transition: none; }
  .ex-word::after { animation: none; opacity: 0; }
  /* the board is not listed here: circuit.js paints it once, packets and all,
     and simply never starts its loop - a still circuit rather than a dead one */
}
.hero-kicker { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.26em; text-transform: uppercase; color: var(--cream-faint); margin-bottom: 30px; }
/* ── Hero type on the board ──────────────────────────────────────
   No panel under the copy, so the type has to carry its own ground. Two
   devices, both drawn in --hero-shade:

     the ring  eight offsets at a sub-pixel radius, which reads as a drawn
               outline around each glyph. text-stroke would be the obvious
               tool and is the wrong one - it paints *over* the glyph edge
               and thins the letterform; offsets paint behind it.
     the fog   three widening hazes that darken the patch of board the word
               is standing on, so a lit trace or a packet running behind a
               line cannot walk off with its contrast.

   The radii are in em so both scale with whatever size the element is set
   at - the same declaration serves the 2.6rem headline and the 0.68rem
   kicker without either looking over- or under-drawn. */
:root { --hero-shade: var(--ink); }
/* The dark themes go to true black rather than their own ground: --ink is a
   navy and reads as a coloured smudge at this weight, where black just reads
   as shadow. The light themes keep --ink - there the halo is what lifts dark
   type off pale paper, and black would ring it like a sticker. */
.theme-neurons, .theme-technical, .theme-midnight { --hero-shade: #000; }

.hero-kicker, .hero-stats, .hero-lede, .hero-explore, .ex-word {
  --ring: 0.042em;
  --ring-n: calc(var(--ring) * -1);
  text-shadow:
    var(--ring)   var(--ring)   0 var(--hero-shade),
    var(--ring-n) var(--ring)   0 var(--hero-shade),
    var(--ring)   var(--ring-n) 0 var(--hero-shade),
    var(--ring-n) var(--ring-n) 0 var(--hero-shade),
    0             var(--ring)   0 var(--hero-shade),
    0             var(--ring-n) 0 var(--hero-shade),
    var(--ring)   0             0 var(--hero-shade),
    var(--ring-n) 0             0 var(--hero-shade),
    0 0.05em 0.18em var(--hero-shade),
    0 0.09em 0.55em var(--hero-shade),
    0 0.13em 1.30em var(--hero-shade);
}
/* the topic word keeps its cyan bloom, stacked in front of the shared ring so
   the glow sits between the glyph and the black rather than outside it */
.ex-word {
  text-shadow:
    0 0 0.5em color-mix(in srgb, var(--cool) 65%, transparent),
    var(--ring)   var(--ring)   0 var(--hero-shade),
    var(--ring-n) var(--ring)   0 var(--hero-shade),
    var(--ring)   var(--ring-n) 0 var(--hero-shade),
    var(--ring-n) var(--ring-n) 0 var(--hero-shade),
    0             var(--ring)   0 var(--hero-shade),
    0             var(--ring-n) 0 var(--hero-shade),
    var(--ring)   0             0 var(--hero-shade),
    var(--ring-n) 0             0 var(--hero-shade),
    0 0.09em 0.55em var(--hero-shade),
    0 0.13em 1.30em var(--hero-shade);
}

/* With a black ground behind every glyph the copy can carry its full weight -
   these tiers were pulled down when the only thing holding them was a blur. */
.theme-neurons .hero-kicker, .theme-neurons .hero-stats {
  color: color-mix(in srgb, var(--cream) 80%, var(--cream-dim));
}
.hero-title { font-family: var(--serif); font-weight: 700; font-size: clamp(3rem, 11vw, 6rem); line-height: 0.9; letter-spacing: -0.035em; margin-bottom: 16px; }
.theme-editorial .hero-title, .theme-softclub .hero-title { font-weight: 400; }
.theme-archival .hero-title { letter-spacing: -0.05em; }
.hero-tagline { font-family: var(--read); font-style: italic; font-size: clamp(1.1rem, 3.2vw, 1.5rem); color: var(--cream-dim); margin-bottom: 30px; }
.theme-archival .hero-tagline { font-style: normal; }
.hero-lede { max-width: 560px; margin: 0 auto 36px; font-size: 1.04rem; line-height: 1.72; color: var(--cream); }
.hero-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 34px; }
.btn { font-family: var(--mono); font-size: 0.82rem; text-decoration: none; padding: 11px 20px; border-radius: 100px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--paper-edge); transition: transform .18s, box-shadow .25s, color .18s, border-color .18s; }
.btn-primary { background: var(--cream); color: var(--on-accent); border-color: var(--cream); font-weight: 500; }
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 7px 20px color-mix(in srgb, var(--cool) 28%, transparent); }
.btn-ghost { background: transparent; color: var(--cream-dim); }
.btn-ghost:hover { color: var(--cream); border-color: var(--cool-deep); }
.hero-stats { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); letter-spacing: 0.04em; }

.about { padding: 5vh 0 7vh; border-top: 1px solid var(--paper-edge); }
.about-h { font-family: var(--serif); font-weight: 600; font-size: 1.65rem; text-align: center; margin-bottom: 32px; letter-spacing: -0.01em; }
.theme-editorial .about-h, .theme-softclub .about-h { font-weight: 400; }
.feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.feature { background: linear-gradient(155deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; padding: 22px 22px 24px; transition: border-color .2s, transform .2s; }
.feature:hover { border-color: var(--cool-deep); transform: translateY(-2px); }
.feature-ico { font-size: 1.35rem; color: var(--amber); display: block; margin-bottom: 10px; line-height: 1; }
.feature h3 { font-family: var(--serif); font-weight: 600; font-size: 1.12rem; margin-bottom: 8px; }
.theme-editorial .feature h3, .theme-softclub .feature h3 { font-weight: 500; }
.feature p { font-size: 0.96rem; color: var(--cream-dim); line-height: 1.55; }
.about-cta { text-align: center; margin-top: 34px; }
.landing-foot { text-align: center; padding: 26px 0 56px; font-family: var(--mono); font-size: 0.68rem; color: var(--cream-faint); }

/* ── App shell tweaks (masthead sits under navbar; brand now in navbar) ── */
.masthead { top: var(--nav-h); }
.masthead-eyebrow { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--cream-faint); align-self: center; }
.scrolled .masthead-eyebrow { display: none; }

/* ── Search box (in the filter head) ───────────────────────────── */
.filter-head { flex-wrap: wrap; row-gap: 8px; }
.search-box { display: inline-flex; align-items: center; gap: 6px; background: var(--ink-3); border: 1px solid var(--paper-edge); border-radius: 100px; padding: 3px 9px; flex: 1 1 130px; min-width: 96px; max-width: 240px; transition: border-color .18s; }
.search-box:focus-within { border-color: var(--cool-deep); }
.search-ico { color: var(--cream-faint); flex-shrink: 0; }
.search-input { flex: 1; min-width: 0; background: transparent; border: none; outline: none; color: var(--cream); font-family: var(--mono); font-size: 0.7rem; padding: 3px 0; }
.search-input::placeholder { color: var(--cream-faint); }
.search-input::-webkit-search-cancel-button { display: none; }
.search-clear { background: none; border: none; color: var(--cream-faint); cursor: pointer; font-size: 0.66rem; font-family: var(--mono); padding: 0 2px; }
.search-clear:hover { color: var(--cream); }

/* ── Link icons on card + panel ────────────────────────────────── */
.card-titlerow .card-title { flex: 1; min-width: 0; }
/* all three actions share one centered row, aligned to the title's first line */
.card-acts { flex-shrink: 0; display: inline-flex; align-items: center; gap: 7px; height: 1.25em; }
.card-link, .p-link-ico { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; color: var(--cream-faint); text-decoration: none; transition: color .18s, transform .18s; }
.card-link:hover, .p-link-ico:hover { color: var(--cool); transform: translate(1px, -1px); }
.link-ico { width: 14px; height: 14px; }
/* arXiv logo mark (shown instead of the link glyph when the source is on arXiv) */
.arxiv-ico { width: 14px; height: 14px; display: block; }
.arxiv-link { opacity: 0.82; transition: opacity .18s; }
.card-link.arxiv-link:hover, .p-link-ico.arxiv-link:hover { opacity: 1; transform: none; }
.p-titlerow { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 8px; }
.p-titlerow .p-title { flex: 1; min-width: 0; margin-bottom: 0; }
.p-link-ico { margin-top: 5px; }
.p-link-ico .link-ico { width: 17px; height: 17px; }
.p-link-ico .arxiv-ico { width: 16px; height: 16px; }

/* ── Mobile ────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  :root { --nav-h: 56px; }   /* match the shorter mobile navbar so the masthead pins flush (no gap when minimized) */
  .navbar { padding: 0 14px; height: var(--nav-h); }
  .nav-link { padding: 6px 10px; font-size: 0.7rem; }

  .hero { padding: 3vh 0 5vh; }
  .hero-lede { font-size: 1rem; }
  .landing { padding: 0 18px; }
  /* the headline is a single nowrap row, so it has to shrink to fit rather
     than push the card past the viewport */
  .hero-explore { font-size: clamp(1.02rem, 4.6vw, 1.6rem); }
  .hero-copy .brand-logo { margin-bottom: 18px; }
  /* the scrim has less height to work with on a phone - carry more of the
     contrast in the type's own shadow instead */
  .hero-kicker, .hero-stats, .hero-lede, .hero-explore {
    text-shadow: 0 1px 2px var(--ink), 0 2px 12px var(--ink), 0 4px 34px var(--ink);
  }
  .feature-grid { grid-template-columns: 1fr; }
  .masthead-eyebrow { display: none; }
  /* mobile 2-line controls:
     line 1 (masthead) = search + timeline/graph toggle + theme picker
     line 2 (filters)  = ALL + org/focus/impact + newest sort  */
  .masthead-inner { justify-content: flex-start; gap: 8px; align-items: center; flex-wrap: nowrap; }
  /* search shrinks to share the masthead line with the pickers (don't let grow wrap them) */
  .masthead-inner > .search-box { order: -1; flex: 1 1 80px; min-width: 0; max-width: none; }
  /* minimized/condensed: drop the search (pickers right-align via the global .scrolled rule) */
  .scrolled .masthead-inner > .search-box { display: none; }
  /* lead the picker group with the 'filters' pill, not the graph/timeline toggle */
  .scrolled .masthead-right .scroll-peek { order: -1; }
  .filters { padding: 0 14px 12px; }   /* was 28px sides — too tight for one pickers row */
  .filter-head { row-gap: 8px; column-gap: 5px; }
  .filter-head .sort-view { margin-left: 0; }   /* pack right after the pickers, same line */
  .filter-head .fdd-btn, .filter-head .sort-toggle, .filter-head .chip-reset { padding: 4px 8px; font-size: 0.6rem; }
  .filter-head .fdd-chev, .filter-head .sort-toggle svg { width: 8px; }
  .filter-bar { gap: 5px; }
}

/* ── People directory ──────────────────────────────────────────── */
.people { max-width: var(--maxw); margin: 0 auto; padding: 40px 28px 80px; }
.people-head { text-align: center; margin-bottom: 34px; }
.people-h { font-family: var(--serif); font-weight: 700; font-size: clamp(2rem, 6vw, 3rem); letter-spacing: -0.03em; }
.theme-editorial .people-h, .theme-softclub .people-h { font-weight: 400; }
.people-sub { font-family: var(--read); font-style: italic; color: var(--cream-dim); margin-top: 8px; font-size: 1rem; }
.theme-archival .people-sub { font-style: normal; }
.people-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
/* person card = a clean photo tile with a transparent (scrim-only) name label */
.person {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden; cursor: pointer;
  border-radius: 14px; border: 1px solid var(--paper-edge);
  background: linear-gradient(150deg, color-mix(in srgb, var(--cool) 30%, var(--ink-3)), var(--ink-2));
  display: flex; align-items: center; justify-content: center;
  transition: transform .25s, box-shadow .25s, border-color .2s;
}
.person:hover { transform: translateY(-3px); border-color: var(--cool); box-shadow: 0 18px 40px -18px rgba(0,0,0,.5); }
.person-mono { font-family: var(--serif); font-weight: 700; font-size: 2.7rem; letter-spacing: -0.02em;
  color: color-mix(in srgb, var(--cream) 78%, transparent); }
.person-cover-id { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 30px 15px 12px; display: flex; flex-direction: column; gap: 1px;
  background: linear-gradient(180deg, transparent 0%, rgba(8,9,12,.32) 46%, rgba(8,9,12,.8) 100%); }
.person-name { font-family: var(--serif); font-weight: 600; font-size: 1.16rem; line-height: 1.12; color: #fff; display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap; text-shadow: 0 1px 9px rgba(0,0,0,.55); }
.theme-editorial .person-name, .theme-softclub .person-name { font-weight: 600; }
.person-link { color: rgba(255,255,255,.72); display: inline-flex; transition: color .18s, transform .18s; }
.person-link:hover { color: #fff; transform: translate(1px, -1px); }
/* X / Twitter link-out (curated researchers) */
.x-ico { width: 13px; height: 13px; }
.p-link .x-ico { width: 12px; height: 12px; margin-right: 1px; }
.pp-links { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; }
.p-xlink { color: var(--cream-dim); }
.p-xlink:hover { color: var(--ink); }
.theme-technical .p-xlink:hover, .theme-midnight .p-xlink:hover { color: var(--cream); }
.person-affil { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.03em; color: rgba(255,255,255,.82); display: block; margin-top: 2px; text-shadow: 0 1px 6px rgba(0,0,0,.55); }
.person-bio { font-size: 0.92rem; line-height: 1.5; color: var(--cream-dim); }
.person-papers { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.person-paper {
  font-family: var(--mono); font-size: 0.62rem; color: var(--cool);
  background: color-mix(in srgb, var(--cool) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--cool) 26%, transparent);
  border-radius: 100px; padding: 3px 9px; cursor: pointer; transition: all .15s; white-space: nowrap;
}
.person-paper:hover { background: var(--cool); color: var(--on-accent); border-color: var(--cool); }
.person-nopapers { font-family: var(--mono); font-size: 0.62rem; color: var(--cream-faint); font-style: italic; }

/* active nav link */
.nav-link.active { color: var(--cream); background: color-mix(in srgb, var(--cream) 10%, transparent); }

@media (max-width: 720px) {
  .people { padding: 22px 14px 60px; }
  .people-grid { grid-template-columns: 1fr; }
}

/* researcher photo fills the tile; monogram shows behind when absent */
.person-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 26%; z-index: 1;
  transition: transform .5s cubic-bezier(.2,.7,.2,1); }
.person:hover .person-photo { transform: scale(1.05); }

/* ── People pagination + person panel + clickable authors ──────── */
.people-pager { display: flex; justify-content: center; align-items: center; gap: 14px; margin-top: 28px; }
.pg-btn { font-family: var(--mono); font-size: 0.7rem; color: var(--cream-dim); background: transparent; border: 1px solid var(--paper-edge); border-radius: 100px; padding: 7px 16px; cursor: pointer; transition: color .18s, border-color .18s; }
.pg-btn:hover:not(:disabled) { color: var(--cream); border-color: var(--cool-deep); }
.pg-btn:disabled { opacity: 0.35; cursor: default; }
.pg-info { font-family: var(--mono); font-size: 0.7rem; color: var(--cream-faint); }
.person { cursor: pointer; }
.p-author { font-family: inherit; font-style: italic; font-size: inherit; color: var(--cool); background: none; border: none; padding: 0; cursor: pointer; }
.p-author:hover { text-decoration: underline; }
.p-etal { color: var(--cream-dim); font-style: italic; }
.person-panel .pp-head { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
.pp-avatar { position: relative; overflow: hidden; flex-shrink: 0; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(150deg, color-mix(in srgb, var(--cool) 35%, var(--ink-3)), var(--ink-3)); border: 1px solid var(--paper-edge); display: flex; align-items: center; justify-content: center; font-family: var(--serif); font-weight: 700; font-size: 1.3rem; color: var(--cream); }
.pp-name { font-family: var(--serif); font-weight: 600; font-size: 1.5rem; line-height: 1.1; }
.theme-editorial .pp-name, .theme-softclub .pp-name { font-weight: 400; }
.pp-affil { font-family: var(--mono); font-size: 0.66rem; color: var(--cream-faint); margin-top: 4px; }
.pp-bio { font-size: 1rem; line-height: 1.55; color: var(--cream); margin: 16px 0 10px; }
.pp-papers { display: flex; flex-direction: column; }
.pp-paper { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--paper-edge); cursor: pointer; transition: padding-left .18s; }
.pp-paper:hover { padding-left: 6px; }
.pp-paper:last-child { border-bottom: none; }
.pp-paper-t { font-size: 0.92rem; color: var(--cool); }
.pp-paper-y { font-family: var(--mono); font-size: 0.62rem; color: var(--cream-faint); flex-shrink: 0; }

/* desktop drag-to-scroll on compact filter rows */
.filters.compact .chip-wrap { cursor: grab; }
.filters.compact .chip-wrap.dragging { cursor: grabbing; }

/* person-view paper list: keep short + truncate */
.pp-paper-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* people search + nicer pager */
.people-search { display: inline-flex; align-items: center; gap: 7px; margin: 16px auto 0; background: var(--ink-3); border: 1px solid var(--paper-edge); border-radius: 100px; padding: 6px 13px; max-width: 320px; }
.people-search:focus-within { border-color: var(--cool-deep); }
.people-search svg { color: var(--cream-faint); flex-shrink: 0; }
.people-search input { background: transparent; border: none; outline: none; color: var(--cream); font-family: var(--mono); font-size: 0.74rem; width: 200px; }
.people-search input::placeholder { color: var(--cream-faint); }
.people-search button { background: none; border: none; color: var(--cream-faint); cursor: pointer; font-family: var(--mono); }
.people-search button:hover { color: var(--cream); }
.pg-btn[data-pg] { min-width: 30px; padding: 6px 10px; font-size: 0.85rem; }
.people-empty { grid-column: 1 / -1; text-align: center; color: var(--cream-faint); font-family: var(--mono); font-size: 0.8rem; padding: 40px 0; }
#peoplePagerTop { margin-top: 22px; margin-bottom: 18px; }
/* defensive: no chip/card can exceed its container (prevents mobile horizontal overflow) */
.person-paper { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.person, .person-bio, .person-affil, .person-name { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.person-papers { min-width: 0; }
@media (max-width: 720px) { .people { padding: 22px 14px 60px; } .people-grid { grid-template-columns: 1fr; } }

/* ─── Learn / tutorials ─────────────────────────────────────────────────── */
.learn { max-width: var(--maxw); margin: 0 auto; padding: 40px 28px 80px; }
.learn-head { margin-bottom: 26px; }
.learn-kicker { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--cool); }
.learn-h { font-family: var(--serif); font-weight: 700; font-size: 2.3rem; letter-spacing: -0.02em; line-height: 1; margin: 6px 0 8px; }
.theme-editorial .learn-h, .theme-softclub .learn-h { font-weight: 400; }
.learn-sub { color: var(--cream-dim); max-width: 60ch; }
.learn-body { margin-bottom: 30px; }
@keyframes paneIn { to { opacity: 1; transform: none; } }

/* ── Level 1: animated vertical subject cover panes ─────────────── */
.subject-panes { display: flex; gap: 10px; height: clamp(360px, 56vh, 540px); }
.subject-pane {
  position: relative; flex: 1 1 0; min-width: 0; overflow: hidden; cursor: pointer;
  border-radius: calc(var(--radius) + 6px); border: 1px solid var(--paper-edge);
  background: var(--ink-2); color: #fff; text-align: left;
  transition: flex-grow .55s cubic-bezier(.4,0,.2,1), box-shadow .4s, border-color .3s;
  opacity: 0; transform: translateY(16px); animation: paneIn .6s cubic-bezier(.2,.7,.2,1) forwards;
  animation-delay: calc(var(--i) * 80ms);
}
.sp-media { position: absolute; inset: 0; background-size: cover; background-position: center;
  transform: scale(1.06); transition: transform .7s ease, filter .5s; filter: saturate(.92); }
.sp-shade { position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,9,12,.1) 0%, rgba(8,9,12,.4) 46%, rgba(8,9,12,.9) 100%); transition: background .4s; }
.subject-pane:hover, .subject-pane:focus-visible { outline: none; flex-grow: 3.2; border-color: var(--cool); box-shadow: 0 26px 60px -24px rgba(0,0,0,.7); }
.subject-pane:hover .sp-media, .subject-pane:focus-visible .sp-media { transform: scale(1); filter: saturate(1.12) brightness(1.14); }
.sp-index { position: absolute; top: 14px; left: 16px; z-index: 2; font-family: var(--mono); font-size: 0.7rem; letter-spacing: .12em; color: rgba(255,255,255,.7); }
.sp-soon { position: absolute; top: 13px; right: 14px; z-index: 2; font-family: var(--mono); font-size: 0.54rem; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: #06120a; background: #4cd07e; border: 1px solid #3fb960; border-radius: 100px; padding: 3px 10px; box-shadow: 0 2px 10px -2px rgba(63,185,96,.6); }
.subject-pane.soon { cursor: default; }
.subject-pane.soon .sp-media { filter: grayscale(.5) saturate(.7) brightness(.84); }
/* soon panes expand on hover just like the live ones (and brighten) */
.subject-pane.soon:hover, .subject-pane.soon:focus-visible { flex-grow: 3.2; border-color: #3fb960; box-shadow: 0 26px 60px -24px rgba(0,0,0,.7); }
.subject-pane.soon:hover .sp-media, .subject-pane.soon:focus-visible .sp-media { filter: grayscale(.12) saturate(1.02) brightness(1.04); }
.sp-body { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 18px 18px 20px; display: flex; flex-direction: column; gap: 5px; }
.sp-name { font-family: var(--serif); font-weight: 700; font-size: 1.35rem; line-height: 1.04; letter-spacing: -.01em; }
.theme-editorial .sp-name, .theme-softclub .sp-name { font-weight: 600; }
.sp-tagline, .sp-meta, .sp-enter { opacity: 0; transform: translateY(8px); transition: opacity .35s ease .04s, transform .35s ease .04s; }
.subject-pane:hover .sp-tagline, .subject-pane:hover .sp-meta, .subject-pane:hover .sp-enter,
.subject-pane:focus-visible .sp-tagline, .subject-pane:focus-visible .sp-meta, .subject-pane:focus-visible .sp-enter { opacity: 1; transform: none; }
/* no cursor on a phone - the copy would never be reachable at all */
@media (hover: none) {
  .sp-tagline, .sp-meta, .sp-enter { opacity: 1; transform: none; }
}
.sp-tagline { font-family: var(--read); font-size: 0.92rem; color: rgba(255,255,255,.9); max-width: 34ch; }
.sp-meta { font-family: var(--mono); font-size: 0.62rem; letter-spacing: .06em; color: rgba(255,255,255,.72); text-transform: uppercase; }
.subject-pane.soon .sp-meta { opacity: 1; transform: none; }
.sp-enter { display: inline-flex; align-items: center; gap: 6px; margin-top: 5px; font-family: var(--mono); font-size: 0.72rem; color: #fff; }
.sp-enter .lc-chev { stroke: currentColor; }

/* breadcrumb */
.learn-crumb { display: inline-flex; align-items: center; gap: 6px; background: none; border: none; cursor: pointer; padding: 0 0 9px; color: var(--cool); font-family: var(--mono); font-size: 0.72rem; letter-spacing: .03em; transition: color .18s, gap .18s; }
.learn-crumb:hover { color: var(--cream); gap: 9px; }
.learn-crumb .lc-chev { stroke: currentColor; transform: scaleX(-1); }

/* ── Level 2 & 3: course / lesson cards with cover banners ───────── */
.course-grid, .lesson-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.course-card, .lesson-card {
  position: relative; display: flex; flex-direction: column; overflow: hidden; cursor: pointer; text-align: left;
  border-radius: calc(var(--radius) + 5px); border: 1px solid var(--paper-edge); color: var(--cream);
  background: linear-gradient(165deg, var(--ink-3), var(--ink-2));
  transition: border-color .2s, transform .18s, box-shadow .25s;
  opacity: 0; transform: translateY(14px); animation: paneIn .5s ease forwards; animation-delay: calc(var(--i) * 60ms);
}
.course-card:hover, .lesson-card:hover { transform: translateY(-3px); border-color: var(--cool-deep); box-shadow: 0 16px 36px -18px rgba(0,0,0,.55); }
.cc-cover, .lc-cover { height: 130px; background-size: cover; background-position: center; background-color: var(--ink); position: relative; }
.cc-cover::after, .lc-cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 52%, var(--ink-3) 100%); }
.cc-body, .lc-body { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px 16px; }
.cc-meta, .lc-tag { font-family: var(--mono); font-size: 0.6rem; letter-spacing: .08em; text-transform: uppercase; color: var(--cool); }
.cc-title, .lc-title { font-family: var(--serif); font-weight: 600; font-size: 1.1rem; line-height: 1.14; }
.cc-blurb, .lc-blurb { font-size: 0.82rem; color: var(--cream-dim); line-height: 1.4; }
.cc-go, .lc-go { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 0.66rem; color: var(--cool); margin-top: 2px; opacity: 0; transform: translateX(-3px); transition: opacity .2s, transform .2s; }
.course-card:hover .cc-go, .lesson-card:hover .lc-go { opacity: 1; transform: none; }
.cc-go .lc-chev, .lc-go .lc-chev { stroke: currentColor; }
/* progress pips on lesson cards: lesson done / quiz finished / exercise complete */
.lc-status { position: absolute; top: 9px; left: 9px; z-index: 2; display: flex; gap: 5px; }
.lc-pip { height: 24px; border-radius: 100px; display: inline-flex; align-items: center; overflow: hidden;
  background: rgba(10,12,16,.52); color: rgba(255,255,255,.66);
  border: 1px solid rgba(255,255,255,.18); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  transition: background .18s, color .18s, border-color .18s; }
.lc-pip-ic { width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.lc-pip-ic .ic { width: 13px; height: 13px; }
.lc-pip-lab { max-width: 0; overflow: hidden; white-space: nowrap;
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.02em; opacity: 0;
  transition: max-width .26s ease, opacity .18s ease, padding .26s ease; }
.lc-pip:hover { background: rgba(10,12,16,.78); }
.lc-pip:hover .lc-pip-lab { max-width: 130px; opacity: 1; padding-right: 10px; }
.lc-pip.on { background: #3fb960; color: #fff; border-color: #3fb960; }
.lc-pip.on:hover { background: #37a957; }
a.lc-pip-link { cursor: pointer; text-decoration: none; }
a.lc-pip-link:hover { border-color: var(--cool); }
a.lc-pip-link.on:hover { border-color: #37a957; }
.lesson-card.is-done { border-color: color-mix(in srgb, #3fb960 38%, var(--paper-edge)); }

/* coming-soon panel */
.learn-soon { text-align: center; padding: 56px 20px; display: flex; flex-direction: column; align-items: center; gap: 9px; }
.learn-soon h3 { font-family: var(--serif); font-weight: 600; font-size: 1.4rem; }
.learn-soon p { color: var(--cream-dim); max-width: 44ch; }
.learn-soon .learn-back { margin-top: 12px; }
.ls-orb { width: 54px; height: 54px; border-radius: 50%; margin-bottom: 6px;
  background: radial-gradient(circle at 35% 30%, var(--cool), var(--ink-2));
  box-shadow: 0 0 30px -4px var(--cool-deep); animation: orbPulse 2.6s ease-in-out infinite; }
@keyframes orbPulse { 0%,100% { transform: scale(1); opacity: .9; } 50% { transform: scale(1.12); opacity: 1; } }

/* ── Lesson footer + completion (done / quiz / exercise) ────────── */
.lesson-foot[hidden], .lesson-extra[hidden], .lesson-stage[hidden] { display: none !important; }
.lesson-extra { max-width: 760px; margin: 0 auto; }
.lesson-foot { max-width: 760px; margin: 26px auto 0; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  border-top: 1px solid var(--paper-edge); padding-top: 16px; }
.lf-hint { font-family: var(--read); font-size: 0.9rem; color: var(--cream-dim); }
.lf-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.lf-btn { display: inline-flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 0.72rem; letter-spacing: .02em; color: var(--cream-dim); background: var(--ink-2);
  border: 1px solid var(--paper-edge); border-radius: 100px; padding: 8px 15px; cursor: pointer; transition: all .16s; }
.lf-ico { display: inline-flex; }
.lf-ico .ic { width: 14px; height: 14px; }
.lf-btn:hover { color: var(--cream); border-color: var(--cool-deep); }
.lf-primary { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 600; }
.lf-primary:hover { color: var(--on-accent); opacity: .9; }
.lf-next { color: #06120a; background: #4cd07e; border-color: #3fb960; font-weight: 600; padding: 9px 20px; font-size: 0.78rem; }
.lf-next:hover { color: #06120a; background: #3fb960; border-color: #3fb960; }
.lf-next .ic { width: 15px; height: 15px; }
.lf-locked { color: var(--amber); font-style: italic; }
/* gated stepper: locked Next button + locked-ahead dots */
.pc-btn.pc-locked, .pc-btn:disabled { opacity: .32; cursor: not-allowed; }
.pc-dot.pc-locked { opacity: .3; pointer-events: none; }
/* "read a line" calc challenge */
.cq { display: flex; flex-direction: column; gap: 9px; max-width: 340px; margin: 14px auto 0; }
.cq-row { display: grid; grid-template-columns: 1fr 74px 22px; align-items: center; gap: 10px; }
.cq-q { font-family: var(--read); font-size: 0.9rem; color: var(--cream-dim); text-align: right; }
.cq-in { width: 100%; padding: 7px 9px; font-family: var(--mono); font-size: 0.9rem; background: var(--ink); border: 1.5px solid var(--paper-edge); border-radius: 8px; color: var(--cream); text-align: center; box-sizing: border-box; }
.cq-in:focus { outline: none; border-color: var(--cool); }
.cq-mark { display: inline-flex; align-items: center; justify-content: center; }
.cq-mark .ic { width: 16px; height: 16px; }
.cq-mark.ok { color: #3fb960; } .cq-mark.bad { color: #e0524d; }
.cq-row:has(.cq-mark.ok) .cq-in { border-color: #3fb960; }
.cq-row:has(.cq-mark.bad) .cq-in { border-color: #e0524d; }

.lesson-done { text-align: center; padding: 38px 20px 26px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.ld-check svg { width: 82px; height: 82px; }
.ld-ring { fill: none; stroke: #3fb960; stroke-width: 3; stroke-dasharray: 146; stroke-dashoffset: 146; animation: ldRing .5s ease forwards; }
.ld-tick { fill: none; stroke: #3fb960; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 40; stroke-dashoffset: 40; animation: ldTick .34s .44s ease forwards; }
@keyframes ldRing { to { stroke-dashoffset: 0; } }
@keyframes ldTick { to { stroke-dashoffset: 0; } }
.ld-h { font-family: var(--serif); font-weight: 700; font-size: 1.8rem; margin-top: 4px; }
.ld-sub { color: var(--cream-dim); }
.ld-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 16px; }
.ld-btn { font-family: var(--mono); font-size: 0.78rem; text-decoration: none; color: var(--cream-dim); background: var(--ink-2);
  border: 1px solid var(--paper-edge); border-radius: 10px; padding: 11px 18px; cursor: pointer; transition: all .16s; display: inline-flex; align-items: center; }
.ld-btn:hover { color: var(--cream); border-color: var(--cool-deep); transform: translateY(-1px); }
.ld-primary { color: var(--on-accent); background: var(--cool); border-color: var(--cool); font-weight: 600; }
.ld-next { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 600; }
.ld-link { background: none; border: none; color: var(--cream-faint); font-family: var(--mono); font-size: 0.72rem; cursor: pointer; margin-top: 18px; }
.ld-link:hover { color: var(--cream); }

.quiz { padding: 6px 0 18px; }
.qz-head { margin-bottom: 18px; }
.qz-kicker { font-family: var(--mono); font-size: 0.62rem; letter-spacing: .16em; text-transform: uppercase; color: var(--cool); }
.qz-h { font-family: var(--serif); font-weight: 700; font-size: 1.55rem; margin: 4px 0; }
.qz-sub { color: var(--cream-dim); font-size: 0.9rem; }
.qz-q { border: 1px solid var(--paper-edge); border-radius: 12px; padding: 15px 18px; margin: 0 0 13px; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); }
.qz-q.ok { border-color: color-mix(in srgb, #3fb960 55%, transparent); }
.qz-q.bad { border-color: color-mix(in srgb, #d9544d 55%, transparent); }
.qz-qtext { font-family: var(--read); font-weight: 600; font-size: 1rem; color: var(--cream); padding: 0; margin-bottom: 9px; }
.qz-mark { display: none; }
.qz-opt { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border-radius: 9px; cursor: pointer; transition: background .14s; font-size: 0.92rem; color: var(--cream-dim); }
.qz-opt:hover { background: color-mix(in srgb, var(--cool) 8%, transparent); }
.qz-opt input { accent-color: var(--cool); width: 15px; height: 15px; flex-shrink: 0; margin: 0; }
.qz-q.ok .qz-opt.correct, .qz-q.bad .qz-opt.correct { background: color-mix(in srgb, #3fb960 17%, transparent); color: var(--cream); }
.qz-opt.chosen-bad { background: color-mix(in srgb, #d9544d 17%, transparent); }
.qz-why { font-size: 0.86rem; color: var(--cream-dim); margin-top: 9px; padding-top: 8px; border-top: 1px dashed var(--paper-edge); line-height: 1.45; }
.qz-foot { display: flex; align-items: center; gap: 16px; margin-top: 4px; flex-wrap: wrap; }
.qz-score { font-family: var(--mono); font-size: 0.84rem; color: var(--cream); }
.qz-nextlink { color: var(--cool); text-decoration: none; font-weight: 600; }
.qz-nextlink:hover { text-decoration: underline; }

/* ── Quiz v2: one question at a time, shuffled, animated ────────────── */
.quiz2 { padding: 6px 0 20px; max-width: 640px; }
.qz2-head { margin-bottom: 20px; }
.qz2-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.qz2-count { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.qz2-dots { display: flex; gap: 6px; }
.qz2-dot { flex: 1; height: 4px; border-radius: 100px; background: var(--paper-edge); border: none; padding: 0; cursor: default; transition: background .2s; }
.qz2-dot.cur { background: var(--cool); }
.qz2-dot.ok { background: #3fb960; cursor: pointer; }
.qz2-dot.bad { background: #d9544d; cursor: pointer; }

.qz2-card { animation: qz2In .3s cubic-bezier(.2,.7,.3,1); }
@keyframes qz2In { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.qz2-q { font-family: var(--serif); font-weight: 700; font-size: 1.4rem; line-height: 1.25; letter-spacing: -0.01em; margin-bottom: 18px; color: var(--cream); }
.theme-editorial .qz2-q, .theme-softclub .qz2-q { font-weight: 400; }

.qz2-opts { display: flex; flex-direction: column; gap: 10px; }
.qz2-opt { display: flex; align-items: center; gap: 13px; width: 100%; text-align: left; cursor: pointer;
  font-family: var(--read); font-size: 0.98rem; color: var(--cream);
  background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1.5px solid var(--paper-edge);
  border-radius: 13px; padding: 14px 15px; transition: border-color .16s, background .16s, transform .12s; }
.qz2-opt:hover:not(:disabled) { border-color: var(--cool-deep); transform: translateX(3px); }
.qz2-opt:disabled { cursor: default; }
.qz2-badge { flex-shrink: 0; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 0.82rem; font-weight: 600; color: var(--cream-dim);
  background: color-mix(in srgb, var(--cream) 7%, transparent); border: 1px solid var(--paper-edge); transition: all .16s; }
.qz2-otext { flex: 1; line-height: 1.4; }
.qz2-mark { flex-shrink: 0; display: inline-flex; }
.qz2-mark .ic { width: 18px; height: 18px; }
.qz2-opt.sel { border-color: var(--cool); background: linear-gradient(165deg, color-mix(in srgb, var(--cool) 14%, var(--ink-3)), var(--ink-2)); }
.qz2-opt.sel .qz2-badge { background: var(--cool); color: var(--on-accent); border-color: var(--cool); }
.qz2-opt.correct { border-color: #3fb960; background: linear-gradient(165deg, color-mix(in srgb, #3fb960 16%, var(--ink-3)), var(--ink-2)); }
.qz2-opt.correct .qz2-badge { background: #3fb960; color: #fff; border-color: #3fb960; }
.qz2-opt.correct .qz2-mark { color: #3fb960; }
.qz2-opt.wrong { border-color: #d9544d; background: linear-gradient(165deg, color-mix(in srgb, #d9544d 14%, var(--ink-3)), var(--ink-2)); }
.qz2-opt.wrong .qz2-badge { background: #d9544d; color: #fff; border-color: #d9544d; }
.qz2-opt.wrong .qz2-mark { color: #d9544d; }

.qz2-why { display: flex; gap: 11px; margin-top: 16px; padding: 14px 15px; border-radius: 12px;
  background: color-mix(in srgb, var(--cool) 8%, transparent); border: 1px solid color-mix(in srgb, var(--cool) 24%, transparent);
  font-size: 0.9rem; line-height: 1.5; color: var(--cream-dim); animation: qz2In .3s; }
.qz2-why-ic { flex-shrink: 0; color: var(--cool); display: inline-flex; margin-top: 1px; }
.qz2-why-ic .ic { width: 17px; height: 17px; }

.qz2-foot { display: flex; align-items: center; gap: 14px; margin-top: 22px; flex-wrap: wrap; }
.qz2-btn { display: inline-flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 0.78rem; letter-spacing: .02em;
  color: var(--cream-dim); background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 100px;
  padding: 10px 20px; cursor: pointer; transition: all .16s; text-decoration: none; }
.qz2-btn:hover { color: var(--cream); border-color: var(--cool-deep); }
.qz2-primary { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 600; }
.qz2-primary:hover { color: var(--on-accent); opacity: .9; border-color: var(--cream); }
.qz2-primary:disabled { opacity: .4; cursor: not-allowed; }
.qz2-bico { display: inline-flex; }
.qz2-bico .ic { width: 16px; height: 16px; }

.qz2-score { display: flex; align-items: center; gap: 20px; margin-bottom: 22px; animation: qz2In .35s; }
.qz2-ring { position: relative; width: 96px; height: 96px; flex-shrink: 0; }
.qz2-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.qz2-ring-bg { fill: none; stroke: var(--paper-edge); stroke-width: 8; }
.qz2-ring-fg { fill: none; stroke: var(--cool); stroke-width: 8; stroke-linecap: round;
  stroke-dasharray: 327; stroke-dashoffset: calc(327 - 327 * var(--pct) / 100); animation: qz2Ring .9s ease; }
@keyframes qz2Ring { from { stroke-dashoffset: 327; } }
.qz2-ring-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-weight: 700; font-size: 1.7rem; color: var(--cream); }
.qz2-ring-num small { font-size: 0.9rem; color: var(--cream-faint); font-weight: 400; }
.qz2-h { font-family: var(--serif); font-weight: 700; font-size: 1.5rem; margin: 3px 0; }
.qz2-sub { color: var(--cream-dim); font-size: 0.88rem; }
.qz2-recaps { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.qz2-recap { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; cursor: pointer;
  background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 11px 13px; transition: all .15s;
  font-family: var(--read); font-size: 0.9rem; color: var(--cream-dim); }
.qz2-recap:hover { border-color: var(--cool-deep); color: var(--cream); transform: translateX(3px); }
.qz2-recap-ic { flex-shrink: 0; display: inline-flex; }
.qz2-recap-ic .ic { width: 16px; height: 16px; }
.qz2-recap.ok .qz2-recap-ic { color: #3fb960; }
.qz2-recap.bad .qz2-recap-ic { color: #d9544d; }
.qz2-recap-q { flex: 1; line-height: 1.35; }
@media (max-width: 560px) {
  .qz2-q { font-size: 1.2rem; }
  .qz2-score { gap: 15px; }
  .qz2-ring { width: 80px; height: 80px; }
  .qz2-foot .qz2-btn { flex: 1 1 auto; justify-content: center; }
}

/* ── Math foundations lessons ──────────────────────────────────── */
.mx { max-width: 720px; margin: 0 auto; counter-reset: mxsec; }
.mx-top { margin-bottom: 10px; }
.mx-kicker { font-family: var(--mono); font-size: 0.62rem; letter-spacing: .16em; text-transform: uppercase; color: var(--cool); }
.mx-title { font-family: var(--serif); font-weight: 700; font-size: clamp(1.6rem, 4.5vw, 2.2rem); letter-spacing: -.02em; margin-top: 4px; }
.mx-sec { margin: 0; padding: 24px 0 26px; border-top: 1px solid var(--paper-edge); counter-increment: mxsec; }
.mx-sec:first-of-type { border-top: none; padding-top: 8px; }
.mx-h { font-family: var(--serif); font-weight: 600; font-size: 1.22rem; margin-bottom: 11px; color: var(--cream); display: flex; align-items: center; gap: 10px; }
.mx-h::before { content: counter(mxsec); font-family: var(--mono); font-size: 0.78rem; font-weight: 500; color: var(--on-accent); background: var(--cool); width: 23px; height: 23px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.mx-p { font-family: var(--read); font-size: 1rem; line-height: 1.6; color: var(--cream-dim); margin-bottom: 10px; }
.mx-p b, .mx-def b { color: var(--cream); }
.mx-block { margin: 14px 0; padding: 10px 4px; overflow-x: auto; overflow-y: hidden; color: var(--cream); }
.mx-note { background: color-mix(in srgb, var(--cool) 10%, transparent); border-left: 3px solid var(--cool); border-radius: 0 8px 8px 0; padding: 11px 14px; font-size: 0.92rem; color: var(--cream-dim); line-height: 1.5; margin-top: 12px; }
.mx-note b { color: var(--cream); }
.mx-try { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; padding: 16px; margin-top: 10px; }
.mx-vec { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.mx-vec.col { flex-direction: column; gap: 5px; align-items: stretch; }
.mx-vlab, .mx-mlab, .mx-deflab { color: var(--cream); }
.mx-num { width: 60px; padding: 6px 8px; font-family: var(--mono); font-size: 0.85rem; background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 7px; color: var(--cream); }
.mx-num:focus { outline: none; border-color: var(--cool); }
.mx-out { margin-top: 10px; color: var(--cream); }
.mx-out .mx-mono { display: block; margin: 2px 0; }

/* Markov-chain interactive widget */
.mk-wrap { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; padding: 16px; margin-top: 12px; }
.mk-states { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.mk-state { display: inline-flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 0.78rem; color: var(--cream-dim); background: var(--ink); border: 1.5px solid var(--paper-edge); border-radius: 100px; padding: 7px 14px; transition: all .18s; }
.mk-state .mk-dot { width: 11px; height: 11px; border-radius: 50%; opacity: .55; transition: opacity .18s, box-shadow .18s; }
.mk-state.on { color: var(--cream); border-color: var(--cool); background: color-mix(in srgb, var(--cool) 14%, var(--ink)); transform: translateY(-2px); }
.mk-state.on .mk-dot { opacity: 1; box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 22%, transparent); }
.mk-bars { display: flex; flex-direction: column; gap: 8px; max-width: 420px; margin: 0 auto; }
.mk-bar-row { display: grid; grid-template-columns: 56px 1fr 40px; align-items: center; gap: 10px; }
.mk-bar-lab { font-family: var(--mono); font-size: 0.7rem; color: var(--cream-dim); text-align: right; }
.mk-bar-track { height: 14px; background: var(--ink); border-radius: 100px; overflow: hidden; border: 1px solid var(--paper-edge); }
.mk-bar-fill { height: 100%; width: 0; border-radius: 100px; transition: width .25s ease; }
.mk-bar-pct { font-family: var(--mono); font-size: 0.7rem; color: var(--cream); font-variant-numeric: tabular-nums; }
.mk-ctrls { display: flex; align-items: center; justify-content: center; gap: 9px; flex-wrap: wrap; margin-top: 16px; }
.mk-count { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); margin-left: 2px; }

/* Bayes medical-test interactive */
.bs-wrap { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; padding: 16px; margin-top: 12px; display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: center; }
@media (max-width: 640px) { .bs-wrap { grid-template-columns: 1fr; } }
.bs-wrap .mx-ctrls { max-width: none; margin: 0; }
.bs-wrap .mx-ctrl { gap: 6px; }
.bs-wrap .mx-ctrlname { font-size: 0.72rem; }
.bs-v { font-family: var(--mono); font-size: 0.74rem; color: var(--cool); font-variant-numeric: tabular-nums; }
.bs-result { text-align: center; }
.bs-big { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.bs-num { font-family: var(--serif); font-weight: 700; font-size: 2.8rem; line-height: 1; color: var(--cool); }
.bs-lab { font-family: var(--read); font-size: 0.8rem; color: var(--cream-dim); line-height: 1.35; }
.bs-bar-track { height: 12px; background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 100px; overflow: hidden; margin: 14px 0 10px; }
.bs-bar-fill { height: 100%; width: 9%; background: var(--cool); border-radius: 100px; transition: width .25s ease; }
.bs-break { font-family: var(--read); font-size: 0.82rem; color: var(--cream-dim); line-height: 1.5; }
.bs-break b { color: var(--cream); }
.mx-mono { font-family: var(--mono); font-size: 0.82rem; line-height: 1.5; }
.mx-tag { font-family: var(--mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: .08em; padding: 2px 8px; border-radius: 100px; border: 1px solid var(--paper-edge); color: var(--cream-faint); }
.mx-tag.pos { color: #3fb960; border-color: #3fb96066; }
.mx-tag.neg { color: #d9544d; border-color: #d9544d66; }
.mx-mat { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.mx-grid { display: grid; grid-template-columns: repeat(2, 60px); gap: 6px; }
.mx-times { color: var(--cream-faint); font-size: 1.1rem; }
.mx-defs { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.mx-def { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 12px 14px; }
.mx-deflab { font-family: var(--mono); font-size: 0.72rem; color: var(--cool); margin-bottom: 6px; }
.mx-def p { font-size: 0.84rem; color: var(--cream-dim); line-height: 1.45; margin-top: 6px; }
.mx-plot { width: 100%; max-width: 360px; display: block; margin: 0 auto; }
.mx-axis { stroke: var(--paper-edge); stroke-width: 1; }
.mx-curve { fill: none; stroke-width: 2.2; }
.mx-curve.sig { stroke: var(--cool); } .mx-curve.th { stroke: var(--amber); } .mx-curve.relu { stroke: var(--teal); }
.mx-zline { stroke: var(--cream-faint); stroke-width: 1.4; stroke-dasharray: 4 4; }
.mx-leg { display: flex; gap: 14px; justify-content: center; margin: 8px 0; font-family: var(--mono); font-size: 0.66rem; }
.mx-key::before { content: ""; display: inline-block; width: 14px; height: 3px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
.mx-key.sig::before { background: var(--cool); } .mx-key.th::before { background: var(--amber); } .mx-key.relu::before { background: var(--teal); }
.mx-key.sig { color: var(--cool); } .mx-key.th { color: var(--amber); } .mx-key.relu { color: var(--teal); }
.mx-range { width: 100%; max-width: 360px; display: block; margin: 6px auto; accent-color: var(--cool); }
.mx-dot { fill: var(--amber); stroke: var(--ink); stroke-width: 1.5; }
.mx-gridline { stroke: var(--paper-edge); stroke-width: 0.6; opacity: .4; }
.mx-run { stroke: var(--teal); stroke-width: 2.4; stroke-linecap: round; }
.mx-rise { stroke: var(--amber); stroke-width: 2.4; stroke-linecap: round; }
.mx-guide { stroke: var(--cream-faint); stroke-width: 1.2; stroke-dasharray: 3 3; }
.mx-tag { fill: var(--cream-dim); font-family: var(--mono); font-size: 11px; }
.mx-tick { fill: var(--cream-faint); font-family: var(--mono); font-size: 9px; }
.mx-axlbl { fill: var(--cream-dim); font-family: var(--mono); font-size: 12px; font-style: italic; }
.mx-coord { fill: var(--cream); font-family: var(--mono); font-size: 10px; paint-order: stroke; stroke: var(--ink); stroke-width: 3px; stroke-linejoin: round; }
.mx-region { stroke: none; }
.mx-region-a { fill: #e0a23a; opacity: .1; }
.mx-region-b { fill: #5b8fb0; opacity: .1; }
.mx-out.solved .mx-mono { color: #3fb960; font-weight: 600; }

/* fox-walking scene (step 1 of the lines lesson) */
.mx-solve { margin: 12px 0; display: flex; flex-direction: column; gap: 9px; }
.mx-solve-row { display: flex; gap: 11px; align-items: flex-start; background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 10px 13px; }
.mx-solve-n { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; background: var(--cool); color: var(--ink); font-weight: 700; font-size: 0.76rem; display: grid; place-items: center; font-family: var(--mono); margin-top: 1px; }
.mx-solve-row > div { font-size: 0.85rem; line-height: 1.55; color: var(--cream); }
.mx-solve-eq { margin-top: 4px; }
.mx-solve-eq.mx-block { margin: 6px 0 2px; padding: 2px 2px; }
.ev-row { display: flex; gap: 12px; margin: 12px 0 10px; }
.ev-card { flex: 1 1 0; min-width: 0; margin: 0; }
.ev-svg { width: 100%; height: auto; display: block; border: 1px solid var(--paper-edge); border-radius: 12px; background: var(--ink-2); overflow: hidden; }
.ev-cap { margin-top: 7px; font-size: 0.74rem; line-height: 1.35; color: var(--cream-dim); text-align: center; }
.ev-cap b { color: var(--cream); font-weight: 600; }
.ev-line { stroke: var(--cool); stroke-width: 3.2; stroke-linecap: round; fill: none; }
.ev-sky { fill: #cfe6ef; }
.ev-sea { fill: #5a86b0; }
.ev-sun { fill: #f6d66b; }
.ev-boat path { fill: #7a5230; }
.ev-sail { fill: #efe7d6 !important; }
.ev-mast { stroke: #5e3f24; stroke-width: 1.6; }
.ev-peg { fill: var(--cream-faint); }
.ev-slack { stroke: var(--cream-faint); stroke-width: 2; stroke-dasharray: 3 3; opacity: .75; }
.ev-ground { stroke: var(--cream-faint); stroke-width: 1.5; }
.ev-ramp { fill: var(--cool); opacity: .14; }
.ev-ball { fill: var(--amber); }
@media (max-width: 640px) { .ev-row { flex-direction: column; } }
.fox-row { display: flex; gap: 12px; align-items: stretch; margin: 10px 0 6px; }
.fox-pane { flex: 1 1 0; min-width: 0; display: flex; }
.fox-pane > svg { width: 100%; max-width: none; height: auto; display: block; border: 1px solid var(--paper-edge); border-radius: 12px; overflow: hidden; }
.fox-scene { max-width: none; margin: 0; }
.fox-svg { background: #cfe6ef; }
.fox-chart { background: var(--paper, #f6f1e7); }
@media (max-width: 640px) { .fox-row { flex-direction: column; } }
.grass-sky { fill: #cfe6ef; }
.grass-ground { fill: #4e7d36; }
.grass-blades .gb { fill: none; stroke-width: 1.7; stroke-linecap: round; opacity: .92; }
.gb0 { stroke: #386627; }
.gb1 { stroke: #4c7d35; }
.gb2 { stroke: #639646; }
.sun { fill: #f6d66b; }
.sun-ray { stroke: #f1cb55; stroke-width: 2; stroke-linecap: round; }
.cloud circle { fill: #f3f8fb; }
.fox-axis { stroke: #eef4e6; stroke-width: 1.4; opacity: .92; fill: none; }
.fox-tick { stroke: #eef4e6; stroke-width: 1.2; opacity: .92; }
.fox-mtxt { fill: #f0f6e9; font-family: var(--mono); font-size: 9px; font-weight: 600; }
.fox-cap { fill: #d9e8ca; font-family: var(--mono); font-size: 9px; letter-spacing: .04em; }
.clk-face { fill: #fbf6e9; stroke: #9a8a6a; stroke-width: 1.4; }
.clk-tick { stroke: #9a8a6a; stroke-width: 1.2; }
.clk-hand { stroke: #c0392b; stroke-width: 2; stroke-linecap: round; }
.clk-pivot { fill: #3a2e1c; }
.clk-txt { fill: #2e3b2e; font-family: var(--mono); font-size: 10px; font-weight: 600; }
.fox-body, .fox-snout, .fox-tail { fill: #db7e3a; }
.fox-ear { fill: #b9601f; }
.fox-tip { fill: #f3e8d6; }
.fox-nose, .fox-eye { fill: #2a1c12; }
.fox-leg { stroke: #9a531f; stroke-width: 3; stroke-linecap: round; }
.mx-ctrls { display: flex; flex-direction: column; gap: 9px; margin-top: 12px; max-width: 360px; margin-left: auto; margin-right: auto; }
.mx-ctrl { display: flex; align-items: center; gap: 9px; font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); }
.mx-ctrlname { width: 64px; flex-shrink: 0; }
.mx-ctrl .mx-range { flex: 1; margin: 0; max-width: none; width: auto; }
/* stepped math lessons (same nav as the other lessons) */
.mxs { max-width: 680px; margin: 0 auto; }
.mxs-box { min-height: 270px; }
.mxs-num { font-family: var(--mono); font-size: 0.6rem; letter-spacing: .14em; text-transform: uppercase; color: var(--cream-faint); margin-bottom: 9px; }
.mxs-h { font-family: var(--serif); font-weight: 600; font-size: 1.32rem; margin-bottom: 13px; color: var(--cream); letter-spacing: -.01em; }
.mxs .pc-nav { margin-top: 18px; }

/* ── Coding sandbox ────────────────────────────────────────────── */
.sandbox { padding: 6px 0 18px; }
.sb-task { font-family: var(--read); font-size: 0.96rem; line-height: 1.55; color: var(--cream-dim); background: color-mix(in srgb, var(--cool) 8%, transparent); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 13px 16px; margin-bottom: 14px; }
.sb-task code, .sb-err code { font-family: var(--mono); font-size: 0.84em; background: var(--ink); padding: 1px 6px; border-radius: 5px; color: var(--cream); }
.sb-code { width: 100%; min-height: 210px; resize: vertical; display: block; font-family: var(--mono); font-size: 0.86rem; line-height: 1.55; tab-size: 2;
  background: var(--ink); color: var(--cream); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 14px 16px; }
.sb-code:focus { outline: none; border-color: var(--cool); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool) 16%, transparent); }
.sb-bar { display: flex; gap: 8px; margin: 12px 0; flex-wrap: wrap; align-items: center; }
.sb-saved { margin-left: auto; font-family: var(--mono); font-size: 0.7rem; color: var(--cream-faint); display: inline-flex; align-items: center; gap: 5px; transition: color .2s; }
.sb-saved[data-state="saved"] { color: #3fb960; }
.sb-saved-ic { display: inline-flex; }
.sb-saved-ic .ic { width: 13px; height: 13px; }
/* ── Code editor (line numbers + JS syntax highlighting + font picker) ───────
   A self-contained dark code panel (stays readable in every theme). The
   transparent textarea overlays a highlighted <pre> with identical metrics. */
.ce-wrap { --ce-bg:#1b1e24; --ce-panel:#23272f; --ce-fg:#d8dee9; --ce-gut:rgba(255,255,255,.3);
  --ce-bord:rgba(255,255,255,.09); --ce-caret:#61afef; --ce-sel:rgba(97,175,239,.3);
  --ce-com:#6b7385; --ce-str:#98c379; --ce-num:#d19a66; --ce-kw:#c678dd; --ce-lit:#56b6c2; --ce-fn:#61afef; --ce-cls:#e5c07b; --ce-pun:#abb2bf;
  margin: 0 0 12px; border: 1px solid var(--ce-bord); border-radius: 12px; overflow: hidden;
  background: var(--ce-bg); box-shadow: 0 10px 30px -18px rgba(0,0,0,.5); }
.ce-bar { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--ce-panel);
  border-bottom: 1px solid var(--ce-bord); font-family: var(--mono); font-size: 0.66rem; color: var(--ce-gut); }
.ce-dots { display: inline-flex; gap: 5px; }
.ce-dots i { width: 9px; height: 9px; border-radius: 50%; background: rgba(128,128,128,.3); }
.ce-dots i:nth-child(1){ background:#e0726b88 } .ce-dots i:nth-child(2){ background:#e0b35088 } .ce-dots i:nth-child(3){ background:#4cc87388 }
.ce-lang { letter-spacing: .04em; }
.ce-spacer { flex: 1; }
.ce-ctl { display: inline-flex; align-items: center; gap: 4px; letter-spacing: .02em; }
.ce-ctl select { font-family: var(--mono); font-size: 0.66rem; color: var(--ce-fg); background: var(--ce-bg);
  border: 1px solid var(--ce-bord); border-radius: 6px; padding: 2px 5px; cursor: pointer; }
.ce-body { position: relative; height: 280px; min-height: 140px; resize: vertical; overflow: hidden; }
.ce-gutter, .ce-pre, .ce-ta { position: absolute; top: 0; bottom: 0; margin: 0; line-height: 1.6;
  font-size: 14px; tab-size: 2; -moz-tab-size: 2; box-sizing: border-box; font-variant-ligatures: none; }
.ce-gutter { left: 0; width: 46px; padding: 13px 9px 13px 0; text-align: right; overflow: hidden; white-space: pre;
  color: var(--ce-gut); user-select: none; background: rgba(0,0,0,.15); border-right: 1px solid var(--ce-bord); }
.ce-wrap.ce-light .ce-gutter { background: rgba(0,0,0,.04); }
.ce-pre, .ce-ta { left: 46px; right: 0; padding: 13px 15px; white-space: pre; overflow: auto; border: 0; min-height: 0; }
.ce-pre { pointer-events: none; color: var(--ce-fg); background: none; }
.ce-pre code { font: inherit; color: inherit; }
.ce-ta { color: transparent; -webkit-text-fill-color: transparent; background: transparent; caret-color: var(--ce-caret);
  resize: none; outline: none; min-width: 0; max-width: none; }
.ce-ta::selection { background: var(--ce-sel); }
.ce-ta::-webkit-scrollbar, .ce-pre::-webkit-scrollbar { width: 9px; height: 9px; }
.ce-ta::-webkit-scrollbar-thumb, .ce-pre::-webkit-scrollbar-thumb { background: rgba(128,128,128,.35); border-radius: 8px; }
.tk-com { color: var(--ce-com); font-style: italic; }
.tk-str { color: var(--ce-str); }
.tk-num { color: var(--ce-num); }
.tk-kw  { color: var(--ce-kw); }
.tk-lit { color: var(--ce-lit); }
.tk-fn  { color: var(--ce-fn); }
.tk-cls { color: var(--ce-cls); }
.tk-pun { color: var(--ce-pun); }

.sb-out { border-radius: 10px; padding: 12px 14px; border: 1px solid var(--paper-edge); background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); }
.sb-out.pass { border-color: color-mix(in srgb, #3fb960 55%, transparent); }
.sb-out.err, .sb-out.partial { border-color: color-mix(in srgb, #d9544d 45%, transparent); }
.sb-log { font-family: var(--mono); font-size: 0.78rem; color: var(--cream-dim); background: var(--ink); border-radius: 8px; padding: 8px 10px; margin: 0 0 8px; white-space: pre-wrap; overflow-x: auto; }
.sb-test { font-family: var(--mono); font-size: 0.8rem; padding: 4px 0; color: var(--cream-dim); }
.sb-test.ok { color: #4cc873; } .sb-test.bad { color: #e0726b; }
.sb-test code, .sb-test b { color: var(--cream); }
.sb-exp { color: var(--cream-faint); }
.sb-err { font-family: var(--mono); font-size: 0.82rem; color: #e0726b; display: flex; align-items: flex-start; gap: 7px; }
.sb-err-ic { display: inline-flex; flex-shrink: 0; margin-top: 1px; }
.sb-err-ic .ic { width: 15px; height: 15px; }
.sb-summary { margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--paper-edge); font-family: var(--mono); font-size: 0.82rem; color: var(--cream); }

/* ── TensorFlow.js trainer ─────────────────────────────────────── */
.tf { max-width: 900px; margin: 0 auto; }
.tf-grid { display: grid; grid-template-columns: 1fr 280px; gap: 18px; align-items: start; margin-top: 8px; }
.tf-code { min-height: 290px; }
.tf-viz { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.tf-canvas { width: 260px; height: 260px; border-radius: 12px; border: 1px solid var(--paper-edge); background: #14161c; }
.tf-stats { font-family: var(--mono); font-size: 0.78rem; color: var(--cream-dim); text-align: center; line-height: 1.5; }
.tf-stats b { color: var(--cream); }
@media (max-width: 720px) { .tf-grid { grid-template-columns: 1fr; } .tf-viz { order: -1; } }

@media (max-width: 720px) {
  .subject-panes { flex-direction: column; height: auto; gap: 10px; }
  .subject-pane { flex: 0 0 120px; height: 120px; animation-delay: calc(var(--i) * 55ms); }
  .subject-pane:hover, .subject-pane:focus-visible { flex: 0 0 120px; box-shadow: none; }
  .subject-pane .sp-media { transform: scale(1); }
  .sp-body { padding: 14px 16px; gap: 3px; justify-content: center; }
  .sp-meta { opacity: 1; transform: none; }
  .sp-tagline, .sp-enter { display: none; }
  .sp-shade { background: linear-gradient(90deg, rgba(8,9,12,.86), rgba(8,9,12,.5) 70%, rgba(8,9,12,.26)); }
}

/* perceptron lesson layout */
.pc { display: grid; grid-template-columns: minmax(0,1fr) 340px; gap: 26px; align-items: start; }
.pc-canvas { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.pc-svg {
  width: 100%; height: auto; background:
    radial-gradient(700px 380px at 30% -10%, var(--glow-1) 0%, transparent 62%),
    linear-gradient(165deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px);
}
.pc-svg [data-grp] { transition: opacity .4s ease; }
.pc-svg [data-grp].dim { opacity: 0.18; }
.pc-node { fill: var(--ink-2); stroke-width: 2; transition: stroke .3s, fill .3s; }
.pc-input { stroke: var(--cool); }
.pc-bias  { stroke: var(--cream-faint); }
.pc-sum   { stroke: var(--teal); }
.pc-out   { stroke: var(--cool-deep); }
.pc-out.fired { fill: color-mix(in srgb, var(--teal) 26%, var(--ink-2)); stroke: var(--teal); }
.lit .pc-node { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--cool) 55%, transparent)); }
.pc-nval, .pc-nlabel { fill: var(--cream); font-family: var(--mono); font-size: 17px; font-weight: 600; text-anchor: middle; dominant-baseline: central; }
.pc-outval { font-size: 20px; }
.pc-sigma { fill: var(--teal); font-family: var(--serif); font-size: 30px; text-anchor: middle; dominant-baseline: central; }
.pc-cap { fill: var(--cream-faint); font-family: var(--mono); font-size: 12px; text-anchor: middle; dominant-baseline: central; }
.pc-wlabel { fill: var(--cream-dim); font-family: var(--mono); font-size: 13px; text-anchor: middle; dominant-baseline: central; }
.pc-zval { fill: var(--teal); font-family: var(--mono); font-size: 14px; text-anchor: middle; dominant-baseline: central; }
.pc-edge { stroke: var(--cream-faint); stroke-width: 2; fill: none; }
.lit .pc-edge { stroke: var(--cool); stroke-dasharray: 7 6; animation: pcflow 0.9s linear infinite; }
@keyframes pcflow { to { stroke-dashoffset: -13; } }
.pc-actbox { fill: color-mix(in srgb, var(--amber) 10%, var(--ink-2)); stroke: var(--amber); stroke-width: 2; }
.pc-stepfn { stroke: var(--amber); stroke-width: 2.5; fill: none; stroke-linejoin: round; stroke-linecap: round; }

/* decision plot */
.pc-plotwrap { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.pc-plot { width: 224px; height: 224px; flex-shrink: 0; overflow: visible; }
.pc-plotbg { fill: color-mix(in srgb, var(--cream) 4%, var(--ink-2)); }
.pc-region { fill: color-mix(in srgb, var(--teal) 22%, transparent); transition: opacity .3s; }
.pc-axis { stroke: var(--paper-edge); stroke-width: 1; }
.pc-boundary { stroke: var(--cool); stroke-width: 2.5; }
.pc-point { fill: var(--cream-faint); stroke: var(--ink); stroke-width: 2; transition: cx .25s ease, cy .25s ease, fill .25s; }
.pc-point.on { fill: var(--teal); }
.pc-legend { display: flex; flex-direction: column; gap: 7px; font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); }
.pc-legend .sw { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 7px; vertical-align: -1px; }
.sw-fire { background: color-mix(in srgb, var(--teal) 40%, transparent); border: 1px solid var(--teal); }
.sw-off { background: var(--ink-2); border: 1px solid var(--paper-edge); }
.pc-plotcap { color: var(--cream-faint); margin-top: 2px; }

/* side panel: step text + controls */
.pc-side { display: flex; flex-direction: column; gap: 16px; position: sticky; top: 84px; }
.pc-stepbox { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 4px); padding: 18px 18px 20px; min-height: 190px; }
.pc-title { font-family: var(--serif); font-weight: 600; font-size: 1.18rem; margin-bottom: 8px; }
.pc-body { font-size: 0.9rem; line-height: 1.5; color: var(--cream-dim); }
.pc-body b { color: var(--cream); font-weight: 600; }
.pc-math { margin-top: 14px; padding: 11px 13px; border-radius: var(--radius); background: color-mix(in srgb, var(--cool) 9%, var(--ink)); border: 1px solid var(--paper-edge); font-family: var(--mono); font-size: 0.86rem; color: var(--cream); overflow-x: auto; }
.pc-math b { color: var(--teal); }
.pc-muted { color: var(--cream-faint); }
/* KaTeX-rendered lesson equations */
.pc-math .katex { font-size: 1.18em; color: var(--cream); }
.pc-math .katex-display { margin: 0; }
.kex-term { cursor: pointer; padding-bottom: 1px; border-bottom: 1px dotted color-mix(in srgb, var(--cream-faint) 70%, transparent); transition: color .15s, border-color .15s; }
.kex-term:hover, .kex-term:hover .mord, .kex-term:hover .mbin, .kex-term:hover .mrel, .kex-term:hover .mopen, .kex-term:hover .mclose, .kex-term:hover .mop { color: var(--cool); }
.kex-term:hover { border-bottom-color: var(--cool); }
.pc-in { animation: pcfade .35s ease; }
@keyframes pcfade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.pc-nav { display: flex; align-items: center; gap: 10px; }
.pc-btn { width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream); font-size: 1.1rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: border-color .2s, color .2s, background .2s; }
.pc-btn:hover { border-color: var(--cool); color: var(--cool); }
.pc-play { display: none; }   /* autoplay removed */
.pc-play.on { border-color: var(--amber); color: var(--amber); }
.pc-dots { display: flex; gap: 7px; flex: 1; justify-content: center; }
.pc-dot { width: 9px; height: 9px; border-radius: 50%; border: none; padding: 0; background: var(--paper-edge); cursor: pointer; transition: background .2s, transform .2s; }
@media (hover: hover) { .pc-dot:hover { transform: scale(1.25); } }
.pc-dot.on { background: var(--cool); transform: scale(1.45); }
.pc-controls { display: flex; flex-direction: column; gap: 9px; padding: 15px 16px; border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 4px); background: var(--ink-2); }
.pc-ctl { display: grid; grid-template-columns: 26px 1fr 38px; align-items: center; gap: 10px; }
.pc-ctl-k { font-family: var(--mono); font-size: 0.78rem; color: var(--cream-dim); }
.pc-ctl-v { font-family: var(--mono); font-size: 0.78rem; color: var(--teal); text-align: right; }
.pc-ctl input[type=range] { -webkit-appearance: none; appearance: none; height: 4px; border-radius: 4px; background: var(--paper-edge); outline: none; }
.pc-ctl input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 15px; height: 15px; border-radius: 50%; background: var(--cool); cursor: pointer; border: 2px solid var(--ink-2); }
.pc-ctl input[type=range]::-moz-range-thumb { width: 15px; height: 15px; border-radius: 50%; background: var(--cool); cursor: pointer; border: 2px solid var(--ink-2); }

@media (max-width: 860px) {
  /* flatten into one ordered stack: dots → explanation → diagram → controls → paper */
  .pc { display: flex; flex-direction: column; gap: 16px; align-items: stretch; }
  .pc-canvas, .pc-side { display: contents; }
  .pc-side { position: static; }
  /* step dots on top, centered; no arrows on mobile (swipe / tap a dot) */
  .pc-nav { order: 0; display: flex; justify-content: center; }
  .pc-nav .pc-btn { display: none; }
  .pc-nav .pc-dots { flex: none; }
  .pc-stepbox { order: 1; }
  .pc-svg, .pc-plotwrap, .gd-plot, .gd-readout, .we-plot, .sq-plot, .at-svg, .tok-stage, .tok-vocab, .sm-bars, .cv-svg, .df-svg, .df-timeline { order: 2; }
  .pc-controls, .pc-train { order: 3; }
  .pc-source { order: 4; margin-top: 4px; }
}
@media (max-width: 720px) { .learn { padding: 26px 14px 64px; } }

/* perceptron training demo (step 7) */
.pc-boundary { transition: x1 .35s ease, y1 .35s ease, x2 .35s ease, y2 .35s ease; }
.pc-region { transition: opacity .3s; }
.pc-dp { stroke: var(--ink); stroke-width: 1.5; transition: cx .2s, cy .2s; }
.pc-dp.c1 { fill: var(--teal); }
.pc-dp.c0 { fill: var(--ink-2); stroke: var(--cream-dim); stroke-width: 2; }
.pc-dp.wrong { stroke: var(--rose); stroke-width: 3; }
.pc-cur { fill: none; stroke: var(--amber); stroke-width: 2.5; }
.pc-train { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 4px); background: var(--ink-2); }
.pc-controls[hidden], .pc-train[hidden] { display: none; }   /* attribute beats the display:flex above */
.pc-gate { display: flex; gap: 6px; }
.pc-gate button { flex: 1; padding: 7px 0; border-radius: var(--radius); border: 1px solid var(--paper-edge); background: var(--ink-3); color: var(--cream-dim); font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.04em; cursor: pointer; transition: border-color .2s, color .2s, background .2s; }
.pc-gate button.on { border-color: var(--cool); color: var(--cream); background: color-mix(in srgb, var(--cool) 14%, var(--ink-2)); }
.pc-trainrow { display: flex; gap: 8px; }
.pc-tbtn { flex: 1; padding: 9px 0; border-radius: var(--radius); border: 1px solid var(--paper-edge); background: var(--ink-3); color: var(--cream); font-family: var(--mono); font-size: 0.8rem; cursor: pointer; transition: border-color .2s, background .2s; }
.pc-tbtn:hover { border-color: var(--cool); }
.pc-tbtn.primary { background: color-mix(in srgb, var(--cool) 18%, var(--ink-2)); border-color: var(--cool-deep); }
.pc-status { font-family: var(--mono); font-size: 0.78rem; color: var(--teal); min-height: 1.2em; text-align: center; }

/* learning-rate control + cross-links */
.pc-eta { display: grid; grid-template-columns: 1fr auto; grid-template-areas: "cap val" "sld sld"; align-items: center; gap: 4px 8px; }
.pc-eta-cap { grid-area: cap; font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); letter-spacing: 0.02em; }
.pc-eta-k { font-family: var(--mono); font-size: 0.82rem; color: var(--cream-dim); }
.pc-eta-v { grid-area: val; font-family: var(--mono); font-size: 0.76rem; color: var(--teal); text-align: right; }
.pc-eta input[type=range] { grid-area: sld; width: 100%; }
.pc-eta input[type=range] { -webkit-appearance: none; appearance: none; height: 4px; border-radius: 4px; background: var(--paper-edge); outline: none; }
.pc-eta input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 15px; height: 15px; border-radius: 50%; background: var(--amber); cursor: pointer; border: 2px solid var(--ink-2); }
.pc-eta input[type=range]::-moz-range-thumb { width: 15px; height: 15px; border-radius: 50%; background: var(--amber); cursor: pointer; border: 2px solid var(--ink-2); }
.pc-source { align-self: flex-start; background: none; border: none; cursor: pointer; padding: 4px 0; font-family: var(--mono); font-size: 0.74rem; color: var(--cool); letter-spacing: 0.02em; transition: color .2s; }
.pc-source:hover { color: var(--cool-deep); text-decoration: underline; }
.p-lesson { background: color-mix(in srgb, var(--cool) 14%, transparent); border-color: var(--cool-deep); }

/* backprop lesson: backward gradient flow + prediction-map points */
.bp .lit.back .pc-edge { stroke: var(--amber); animation-direction: reverse; }
.bp .pc-nval { font-size: 14px; }

.bp-dp { stroke-width: 2.5; }
.bp-dp.c1 { fill: var(--teal); stroke: var(--ink); }
.bp-dp.c0 { fill: var(--ink-2); stroke: var(--cream); }

/* gradient-descent lesson: loss landscape */
.gd-plot { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); cursor: crosshair; }
.gd-axis { stroke: var(--paper-edge); stroke-width: 1; }
.gd-curve { fill: none; stroke: var(--cool); stroke-width: 2.5; }
.gd-tan { stroke: var(--amber); stroke-width: 2; stroke-dasharray: 4 3; }
.gd-trail { fill: color-mix(in srgb, var(--teal) 45%, transparent); }
.gd-ball { fill: var(--teal); stroke: var(--ink); stroke-width: 2; transition: cx .22s ease, cy .22s ease; }
.gd-readout { display: flex; flex-wrap: wrap; gap: 16px; font-family: var(--mono); font-size: 0.8rem; color: var(--cream-dim); padding: 2px 4px; }
.gd-readout b { color: var(--teal); }
.gd-state { color: var(--cream-faint); margin-left: auto; }

/* word-embeddings lesson: vector space + analogy machine */
.we-plot { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); }
.we-word circle { stroke: var(--ink); stroke-width: 1.5; transition: opacity .25s; }
.we-word.ppl circle { fill: var(--cool); }
.we-word.ani circle { fill: var(--teal); }
.we-word.geo circle { fill: var(--amber); }
.we-word text { font-family: var(--mono); font-size: 12px; fill: var(--cream); transition: opacity .25s; }
.we-word.dim { opacity: 0.2; }
.we-word.ans circle { r: 7; stroke: var(--teal); stroke-width: 2.5; }
.we-word.ans text { fill: var(--teal); font-weight: 600; }
.we-link { stroke: var(--cream-faint); stroke-width: 1; stroke-dasharray: 3 3; }
.we-arr { stroke-width: 2; } .we-arr.rel { stroke: var(--cool); } .we-arr.cap { stroke: var(--amber); } .we-arr.app { stroke: var(--teal); stroke-dasharray: 5 4; }
.we-arrh.rel { fill: var(--cool); } .we-arrh.cap { fill: var(--amber); } .we-arrh.app { fill: var(--teal); }
.we-target { fill: none; stroke: var(--teal); stroke-width: 1.5; stroke-dasharray: 3 3; }
.we-analogy { display: flex; align-items: center; gap: 6px; font-family: var(--mono); color: var(--cream-dim); }
.we-analogy select { flex: 1; min-width: 0; background: var(--ink-3); color: var(--cream); border: 1px solid var(--paper-edge); border-radius: var(--radius); padding: 5px 4px; font-family: var(--mono); font-size: 0.78rem; }
.we-result { font-family: var(--mono); font-size: 0.84rem; color: var(--cream-dim); text-align: center; margin-top: 2px; }
.we-result b, .we-ans { color: var(--teal); }
.we-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.we-presets button { flex: 1; padding: 6px 4px; border-radius: var(--radius); border: 1px solid var(--paper-edge); background: var(--ink-3); color: var(--cream-dim); font-family: var(--mono); font-size: 0.68rem; cursor: pointer; transition: border-color .2s, color .2s; }
.we-presets button:hover { border-color: var(--cool); color: var(--cream); }

/* sequences / RNN lesson */
.sq-plot { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); }
.sq-base { stroke: var(--paper-edge); stroke-width: 1; }
.sq-bar { stroke: var(--ink); stroke-width: 1; transition: y .3s ease, height .3s ease, opacity .3s, fill .3s; }
.sq-bar.off { opacity: 0.12; }
.sq-bar.cur { stroke: var(--amber); stroke-width: 2; }
.sq-link { stroke: var(--cool); stroke-width: 1.5; opacity: 0.5; transition: opacity .3s; }
.sq-link.cur { stroke: var(--amber); opacity: 1; }
.sq-chip { font-family: var(--mono); font-size: 12px; fill: var(--cream-dim); text-anchor: middle; transition: fill .3s, opacity .3s; }
.sq-chip.key { fill: var(--amber); font-weight: 600; }
.sq-chip.off { opacity: 0.3; }
.sq-chip.cur { fill: var(--cream); }

/* self-attention / transformer lesson */
.at-svg { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); }
.at-cap { font-family: var(--mono); font-size: 12px; fill: var(--cream-dim); }
.at-cap2 { font-family: var(--mono); font-size: 10.5px; fill: var(--cream-faint); }
.at-arc { fill: none; stroke: var(--cool); stroke-linecap: round; transition: stroke-width .25s, opacity .25s; }
.at-tok rect { fill: var(--ink-3); stroke: var(--paper-edge); stroke-width: 1.5; transition: stroke .2s, fill .2s; }
.at-tok text { font-family: var(--mono); font-size: 13px; fill: var(--cream-dim); text-anchor: middle; dominant-baseline: central; transition: fill .2s; }
.at-tok { cursor: pointer; }
.at-tok:hover rect { stroke: var(--cool); }
.at-tok.q rect { fill: color-mix(in srgb, var(--cool) 22%, var(--ink-2)); stroke: var(--cool); stroke-width: 2.5; }
.at-tok.q text { fill: var(--cream); font-weight: 600; }
.at-bar { stroke: var(--ink); stroke-width: 1; transition: height .25s, fill .25s; }
.at-bar.q { stroke: var(--cool); stroke-width: 1.5; }
.at-bw { font-family: var(--mono); font-size: 10px; fill: var(--cream-faint); text-anchor: middle; }
.at-heat { width: auto; max-width: 320px; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); padding: 6px; box-sizing: border-box; }
.at-cell { stroke: var(--ink); stroke-width: 0.5; cursor: pointer; transition: fill .25s; }
.at-cell.rowon { stroke: var(--cool); stroke-width: 1.5; }
.at-hl { font-family: var(--mono); font-size: 11px; fill: var(--cream-faint); }
.at-hl[data-q] { cursor: pointer; }
.at-hl.on { fill: var(--cool); font-weight: 600; }
.at-qrow { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.at-qlab { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); }
.at-qrow button { padding: 4px 8px; border-radius: var(--radius); border: 1px solid var(--paper-edge); background: var(--ink-3); color: var(--cream-dim); font-family: var(--mono); font-size: 0.72rem; cursor: pointer; transition: border-color .2s, color .2s, background .2s; }
.at-qrow button:hover { border-color: var(--cool); color: var(--cream); }
.at-qrow button.on { background: color-mix(in srgb, var(--cool) 20%, var(--ink-2)); border-color: var(--cool); color: var(--cream); }
.pc.at-matrix .at-svg { opacity: 0.55; }
.at-svg [data-explain], .at-heat [data-explain] { transition: filter .15s ease; }
.at-svg [data-explain]:hover, .at-heat [data-explain]:hover { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--cool) 85%, transparent)) brightness(1.12); }

/* tokenization / BPE lesson */
.tok-stage { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); padding: 16px 18px; display: flex; flex-direction: column; gap: 11px; min-height: 150px; justify-content: center; }
.tok-wrow { display: flex; align-items: center; gap: 12px; }
.tok-count { font-family: var(--mono); font-size: 0.74rem; color: var(--cream-faint); min-width: 26px; cursor: pointer; }
.tok-row { display: flex; flex-wrap: wrap; gap: 5px; }
.tok-chip { font-family: var(--mono); font-size: 0.9rem; color: var(--cream); background: var(--ink-3); border: 1px solid var(--paper-edge); border-radius: 6px; padding: 4px 9px; cursor: pointer; transition: background .25s, border-color .25s, color .25s; }
.tok-chip.pairhi { border-color: var(--amber); color: var(--amber); background: color-mix(in srgb, var(--amber) 16%, var(--ink-2)); }
.tok-chip.merged { border-color: var(--teal); color: var(--teal); background: color-mix(in srgb, var(--teal) 18%, var(--ink-2)); }
.tok-vocab { margin-top: 12px; font-family: var(--mono); font-size: 0.78rem; line-height: 2; color: var(--cream-dim); }
.tok-vlab { color: var(--cream-faint); }
.tok-vchip { display: inline-block; padding: 2px 7px; margin: 0 3px 4px 0; border-radius: 5px; background: var(--ink-3); border: 1px solid var(--paper-edge); }
.tok-vchip.new { border-color: var(--teal); color: var(--teal); }
.tok-tokenized { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 9px; }
.tok-word { font-family: var(--mono); font-size: 1.3rem; color: var(--cream); letter-spacing: 1px; }
.tok-arrow { font-family: var(--mono); font-size: 0.74rem; color: var(--cream-faint); }
.tok-out { justify-content: center; }
.tok-out .tok-chip { font-size: 1rem; border-color: var(--teal); color: var(--teal); background: color-mix(in srgb, var(--teal) 12%, var(--ink-2)); }
.tok-cap { font-family: var(--mono); font-size: 0.78rem; color: var(--cream-dim); }
.tok-tokrow { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.tok-tokrow input { flex: 1; background: var(--ink-3); color: var(--cream); border: 1px solid var(--paper-edge); border-radius: var(--radius); padding: 7px 10px; font-family: var(--mono); font-size: 0.9rem; }
.tok-tokrow input:focus { outline: none; border-color: var(--cool); }
.tok-tokrow[hidden], .pc-trainrow[hidden] { display: none; }
.tok-stage [data-explain]:hover { filter: brightness(1.15); }

/* softmax & cross-entropy lesson */
.sm-bars { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); }
.sm-bar { stroke: var(--ink); stroke-width: 1; cursor: pointer; transition: y .3s ease, height .3s ease, fill .3s; }
.sm-bar.tgt { stroke: var(--teal); stroke-width: 2.5; }
.sm-pct { font-family: var(--mono); font-size: 12px; fill: var(--cream); }
.sm-clab { font-family: var(--mono); font-size: 13px; fill: var(--cream-dim); }
.sm-clab.tgt { fill: var(--teal); font-weight: 600; }
.sm-zlab { font-family: var(--mono); font-size: 10px; fill: var(--cream-faint); }
.sm-losslab { font-family: var(--mono); font-size: 13px; fill: var(--amber); }
.sm-curve { width: 224px; height: 224px; flex-shrink: 0; overflow: visible; }
.sm-drop { stroke: var(--cool); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.7; }
.sm-curvemode .sm-bars { opacity: 0.78; }
.sm-ctl { display: grid; grid-template-columns: 64px 1fr 38px; align-items: center; gap: 9px; }
.sm-ctl-k { font-family: var(--mono); font-size: 0.74rem; color: var(--cream-dim); }
.sm-ctl-v { font-family: var(--mono); font-size: 0.74rem; color: var(--cream-faint); text-align: right; }
.sm-logrow { display: flex; flex-direction: column; gap: 6px; }
.sm-bars [data-explain], .sm-curve [data-explain] { transition: filter .15s ease; }
.sm-bars [data-explain]:hover, .sm-curve [data-explain]:hover { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--cool) 85%, transparent)) brightness(1.12); }

/* convolution / CNN lesson */
.cv-svg { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); }
.cv-px { stroke: var(--ink-2); stroke-width: 0.5; }
.cv-glab { font-family: var(--mono); font-size: 9.5px; fill: var(--cream-faint); }
.cv-op { font-family: var(--mono); font-size: 16px; fill: var(--cream-dim); dominant-baseline: central; }
.cv-kc { fill: var(--ink-3); stroke: var(--cool); stroke-width: 1; }
.cv-kv { font-family: var(--mono); font-size: 9px; fill: var(--cream); }
.cv-oc { stroke: var(--ink-2); stroke-width: 0.5; transition: fill .12s, opacity .12s; }
.cv-oc.cur { stroke: var(--amber); stroke-width: 1.5; }
.cv-win { fill: color-mix(in srgb, var(--amber) 14%, transparent); stroke: var(--amber); stroke-width: 2; transition: x .1s linear, y .1s linear; }
.cv-ocsel { fill: none; stroke: var(--amber); stroke-width: 2; }
.cv-krow { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.cv-krow button { padding: 4px 8px; border-radius: var(--radius); border: 1px solid var(--paper-edge); background: var(--ink-3); color: var(--cream-dim); font-family: var(--mono); font-size: 0.7rem; cursor: pointer; transition: border-color .2s, color .2s, background .2s; }
.cv-krow button:hover { border-color: var(--cool); color: var(--cream); }
.cv-krow button.on { background: color-mix(in srgb, var(--cool) 20%, var(--ink-2)); border-color: var(--cool); color: var(--cream); }
.cv-svg [data-explain]:hover { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--cool) 85%, transparent)) brightness(1.15); }

/* diffusion lesson */
.df-svg { width: 100%; height: auto; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: calc(var(--radius) + 6px); }
.df-px { stroke: var(--ink-2); stroke-width: 0.3; }
.df-px2 { stroke: var(--ink-2); stroke-width: 0.3; }
.df-lab { font-family: var(--mono); font-size: 9.5px; fill: var(--cream-faint); }
.df-op { font-family: var(--mono); font-size: 16px; fill: var(--cream-dim); dominant-baseline: central; }
.df-timeline { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.df-timeline input { flex: 1; }
.df-tl-lab { font-family: var(--mono); font-size: 0.7rem; color: var(--cream-faint); }
.df-svg [data-explain]:hover { filter: brightness(1.15); }

/* lesson hover-explanations (data-explain tooltips) */
.learn-tip, .app-tip { position: fixed; z-index: 200; pointer-events: none; max-width: 250px; padding: 8px 11px; border-radius: 9px; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--cool-deep); box-shadow: 0 12px 34px -12px rgba(0,0,0,.6); font-family: var(--read); font-size: 0.78rem; line-height: 1.4; color: var(--cream); }
.learn-tip[hidden], .app-tip[hidden] { display: none; }
[data-explain] { cursor: pointer; }
.pc-math [data-explain] { border-bottom: 1px dotted var(--cream-faint); transition: color .15s, border-color .15s; }
.pc-math [data-explain]:hover { color: var(--cool); border-bottom-color: var(--cool); }
/* hover glow on any explained diagram element */
.pc-svg [data-explain], .we-plot [data-explain], .gd-plot [data-explain], .sq-plot [data-explain] { transition: filter .15s ease; }
.pc-svg [data-explain]:hover, .we-plot [data-explain]:hover, .gd-plot [data-explain]:hover, .sq-plot [data-explain]:hover {
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--cool) 85%, transparent)) brightness(1.12);
}
.we-word[data-explain]:hover text { fill: var(--cool); }

/* video-summary links (NotebookLM YouTube overviews) */
.p-video-embed { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--paper-edge); background: #000; }
.p-video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; }
.p-vidlink { display: inline-block; margin-top: 8px; font-family: var(--mono); font-size: 0.72rem; color: var(--rose); }
.p-vidlink:hover { text-decoration: underline; }
.card-video { display: inline-flex; align-items: center; flex-shrink: 0; opacity: 0.92; transition: opacity .2s, transform .15s; }
.card-video:hover { opacity: 1; transform: scale(1.12); }
.yt-ico { width: 19px; height: 14px; display: block; }

/* rich video preview tooltip (thumbnail + title·channel + length) */
.app-tip.vtip { padding: 0; max-width: 268px; width: 268px; overflow: hidden; }
.vtip-thumb { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: #000; }
.vtip-body { padding: 9px 11px 10px; }
.vtip-title { font-family: var(--read); font-size: 0.78rem; line-height: 1.35; color: var(--cream); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.vtip-len { margin-top: 5px; font-family: var(--mono); font-size: 0.7rem; color: var(--rose); }

/* learn: directory ↔ single-lesson view split */
.learn-dir[hidden], .learn-view[hidden] { display: none; }
.learn-back { display: inline-flex; align-items: center; gap: 5px; margin-bottom: 18px; padding: 8px 15px; border-radius: 100px; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream-dim); font-family: var(--mono); font-size: 0.76rem; cursor: pointer; transition: border-color .2s, color .2s; }
.learn-back:hover { border-color: var(--cool); color: var(--cream); }
.learn-back .lc-chev { stroke: currentColor; transform: scaleX(-1); }
.learn-soon .learn-back { display: inline-flex; }

/* perceptron polish: centered decision plot + roomier controls */
.pc-plotwrap { flex-direction: column; align-items: center; justify-content: center; gap: 12px; }
.pc-controls { padding: 16px 18px; gap: 12px; }
.pc-ctl { grid-template-columns: 32px 1fr 42px; gap: 13px; }
.pc-ctl-k { font-size: 0.84rem; }
@media (max-width: 560px) {
  .learn { padding: 22px 14px 70px; }
  .pc-side { gap: 13px; }
}

/* backprop prediction-map caption */
.bp-heat-title { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.03em; color: var(--cream-dim); text-align: center; }

/* plot axes + numeric scale */
.plot-axline { stroke: var(--paper-edge); stroke-width: 1; }
.plot-tick { stroke: var(--cream-faint); stroke-width: 1; }
.plot-tlab { font-family: var(--mono); font-size: 11px; fill: var(--cream-faint); }
.plot-axt { font-family: var(--mono); font-size: 12px; fill: var(--cream-dim); }
.pc-plotbg { /* data-region background only */ }

/* gradient-descent + word-embedding axis labels */
.gd-tick { font-family: var(--mono); font-size: 12px; fill: var(--cream-faint); }
.gd-axt { font-family: var(--mono); font-size: 12px; fill: var(--cream-dim); }
.we-axlab { font-family: var(--mono); font-size: 11px; fill: var(--cream-faint); }

/* perceptron "did you know" step - the Mark I Perceptron machine */
.pc-didyou-img { width: 100%; border-radius: var(--radius); display: block; margin-bottom: 11px; border: 1px solid var(--paper-edge); }

/* "info" step (e.g. Did you know?) - just the text+image, no diagram/plot/controls */
.pc.info-only { grid-template-columns: 1fr; }
.pc.info-only .pc-canvas, .pc.info-only .pc-controls, .pc.info-only .pc-train { display: none; }
.pc.info-only .pc-stepbox { max-width: 600px; margin-inline: auto; }
/* in the single-column info view, centre the nav and keep the arrows hugging the dots
   (otherwise flex:1 dots shove the ‹ › buttons out to the far edges of the wide column) */
.pc.info-only .pc-nav { justify-content: center; }
.pc.info-only .pc-dots { flex: none; }
.pc.info-only .pc-didyou-img { max-height: 360px; object-fit: cover; }

/* ── Auth: sign-in button, user chip, sign-in/register modal ──────────────── */
.navbar { justify-content: flex-start; }
/* The links group up right after the lockup, and the far edge is the theme
   picker and the auth control together. The auto margin has to live on the
   first of those two rather than on the brand: the brand used to carry it,
   and with a second one on the level chip the links ended up floated
   dead-centre - and on a phone .nav-links is a fixed drawer, out of flow
   entirely, so an auto margin there would push nothing. */
.nav-brand { margin-right: 10px; }
/* Stretched to the full height of the bar, with the trigger centred inside it.
   That is what lets .dd-menu's "top: 100%" mean "under the navbar" rather than
   "under the trigger" - anchored to the trigger the menu opened out of the
   middle of the bar and lay across its bottom edge. */
.navbar > .dropdown { margin-left: auto; align-self: stretch; display: flex; align-items: center; }
/* no extra margin: the navbar's own 16px gap is the spacing between these two */
.nav-auth { display: flex; align-items: center; position: relative; }
/* the picker moved here from the papers masthead, where it was reachable only
   from one tab; the trigger is sized down to sit on the navbar's line */
.navbar > .dropdown .dd-trigger { padding: 6px 11px; font-size: 0.7rem; border-radius: 100px; }
@media (max-width: 900px) {
  /* the name of the theme is the first thing to go - the swatch dot already
     says one is picked, and the menu names them all */
  .navbar > .dropdown .dd-label { display: none; }
  .navbar > .dropdown .dd-trigger { padding: 6px 9px; gap: 6px; }
}
.auth-btn { font-family: var(--mono); font-size: 0.74rem; color: var(--on-accent); background: var(--cream); border: 1px solid var(--cream); border-radius: 100px; padding: 7px 15px; cursor: pointer; font-weight: 500; transition: opacity .18s; }
.auth-btn:hover { opacity: 0.88; }
.auth-chip { display: inline-flex; align-items: center; gap: 8px; padding: 4px 11px 4px 4px; border-radius: 100px; border: 1px solid var(--paper-edge); cursor: pointer; background: var(--ink-2); transition: border-color .18s; }
.auth-chip:hover { border-color: var(--cool); }
.auth-av { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.auth-av-fb { display: inline-flex; align-items: center; justify-content: center; background: var(--cool); color: var(--on-accent); font-family: var(--mono); font-size: 0.78rem; font-weight: 600; }
.auth-uname { font-family: var(--mono); font-size: 0.74rem; color: var(--cream); max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auth-chev { color: var(--cream-faint); }
.auth-menu { position: absolute; top: calc(100% + 8px); right: 0; min-width: 172px; background: linear-gradient(170deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; box-shadow: 0 18px 44px -14px rgba(0,0,0,.5); padding: 6px; z-index: 80; display: flex; flex-direction: column; }
.auth-menu[hidden] { display: none; }
.auth-mi { font-family: var(--mono); font-size: 0.76rem; color: var(--cream-dim); text-decoration: none; text-align: left; padding: 9px 11px; border-radius: 8px; background: none; border: none; cursor: pointer; transition: background .15s, color .15s; }
.auth-mi:hover { background: color-mix(in srgb, var(--cool) 14%, transparent); color: var(--cream); }
.auth-signout { color: var(--rose); border-top: 1px solid var(--paper-edge); margin-top: 4px; }
.auth-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; }
.auth-modal[hidden] { display: none; }
.auth-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 62%, transparent); backdrop-filter: blur(3px); }
.auth-card { position: relative; width: min(380px, calc(100vw - 32px)); background: linear-gradient(168deg, var(--ink-3), var(--ink)); border: 1px solid var(--paper-edge); border-radius: 18px; box-shadow: 0 30px 80px -20px rgba(0,0,0,.6); padding: 30px 26px 26px; }
.auth-x { position: absolute; top: 14px; right: 14px; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream-dim); cursor: pointer; }
.auth-x:hover { color: var(--cream); border-color: var(--cool-deep); }
.auth-title { font-family: var(--serif); font-size: 1.4rem; margin-bottom: 4px; color: var(--cream); }
.auth-sub { font-family: var(--read); font-size: 0.86rem; color: var(--cream-dim); margin-bottom: 18px; line-height: 1.4; }
.auth-tabs { display: flex; gap: 4px; background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 100px; padding: 3px; margin-bottom: 18px; }
.auth-tabs button { flex: 1; font-family: var(--mono); font-size: 0.74rem; color: var(--cream-dim); background: none; border: none; border-radius: 100px; padding: 8px; cursor: pointer; transition: background .18s, color .18s; }
.auth-tabs button.on { background: var(--cream); color: var(--on-accent); font-weight: 500; }
.auth-form { display: flex; flex-direction: column; gap: 12px; }
.auth-field { display: flex; flex-direction: column; gap: 5px; }
.auth-field[hidden] { display: none; }   /* flex would otherwise win over [hidden] */
.auth-field span { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cream-faint); }
.auth-field input { font-family: var(--mono); font-size: 0.9rem; color: var(--cream); background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 10px 12px; }
.auth-field input:focus { outline: none; border-color: var(--cool); }
.auth-err { font-family: var(--read); font-size: 0.8rem; color: var(--rose); background: color-mix(in srgb, var(--rose) 12%, transparent); border: 1px solid color-mix(in srgb, var(--rose) 35%, transparent); border-radius: 8px; padding: 8px 11px; }
.auth-err[hidden] { display: none; }
.auth-submit { font-family: var(--mono); font-size: 0.82rem; color: var(--on-accent); background: var(--cream); border: 1px solid var(--cream); border-radius: 10px; padding: 11px; cursor: pointer; font-weight: 500; margin-top: 4px; transition: opacity .18s; }
.auth-submit:hover { opacity: 0.9; }
.auth-submit.busy { opacity: 0.6; cursor: progress; }
.auth-google-wrap[hidden] { display: none; }
.auth-divider { display: flex; align-items: center; gap: 12px; margin: 16px 0; color: var(--cream-faint); font-family: var(--mono); font-size: 0.7rem; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--paper-edge); }
#authGoogleBtn { display: flex; justify-content: center; }
@media (max-width: 520px) { .auth-uname { display: none; } .navbar { padding: 0 14px; } }

/* ── Favorites bookmarks + user views (favorites / lists) ─────────────────── */
.fav-btn { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; color: var(--cream-faint); padding: 2px; transition: color .15s, transform .15s; }
.fav-btn svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }
.fav-btn:hover { color: var(--cool); transform: scale(1.14); }
.fav-btn.on { color: var(--cool); }
.mi-fav { color: var(--cool); }     /* every Favourites label wears the bookmark, in the bookmark's ink */
.mi-heart { color: var(--cool); }   /* the about card's heart, which is not a favourite */
.fav-btn.on svg { fill: currentColor; stroke: currentColor; }

/* ── Shared inline icon set (consistent SVG icons, no unicode glyphs) ─────── */
.ic { width: 1em; height: 1em; display: inline-block; vertical-align: -0.13em; flex-shrink: 0; }
.auth-mi { display: flex; align-items: center; gap: 9px; }
.auth-mi-ico { display: inline-flex; color: var(--cream-faint); }
.auth-mi-ico .ic { width: 15px; height: 15px; }
.auth-mi:hover .auth-mi-ico { color: var(--cream); }
.auth-mi .auth-mi-ico.mi-fav, .auth-mi:hover .auth-mi-ico.mi-fav { color: var(--cool); }
.pf-link { display: inline-flex; align-items: center; gap: 8px; }
.pf-ico { display: inline-flex; }
.pf-ico .ic { width: 15px; height: 15px; }
.about-ico { display: inline-flex; }
.about-ico .ic { width: 23px; height: 23px; }
.p-fav { margin-top: 2px; }
.p-fav svg { width: 19px; height: 19px; }
.uv-fav svg { width: 17px; height: 17px; }

.userview { max-width: 880px; margin: 0 auto; padding: 40px 24px 110px; }
.uv-head { margin-bottom: 18px; }
.uv-kicker { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--cream-faint); }
.uv-h { font-family: var(--serif); font-size: 2rem; margin: 6px 0 4px; color: var(--cream); letter-spacing: -0.02em; }
.uv-sub { font-family: var(--read); color: var(--cream-dim); font-size: 0.9rem; }
.uv-sec { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--cream-faint); margin: 24px 0 10px; }
.uv-grid { display: flex; flex-direction: column; gap: 8px; }
.uv-item { display: flex; align-items: center; gap: 13px; padding: 11px 14px; border: 1px solid var(--paper-edge); border-radius: 12px; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); text-decoration: none; transition: border-color .18s, transform .12s; }
.uv-item:hover { border-color: var(--cool); transform: translateX(2px); }
.uv-logo { width: 30px; height: 30px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border-radius: 7px; overflow: hidden; background: #fff; }
.uv-logo-img { width: 100%; height: 100%; object-fit: contain; }
.uv-logo-fb { font-family: var(--mono); font-size: 0.7rem; color: #2a2a2a; font-weight: 600; }
.uv-lesson-ico { background: color-mix(in srgb, var(--cool) 22%, var(--ink-2)); color: var(--cool-deep); font-size: 0.68rem; }
.uv-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.uv-title { font-family: var(--read); font-size: 0.92rem; color: var(--cream); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uv-meta { font-family: var(--mono); font-size: 0.66rem; color: var(--cream-faint); }
.uv-empty { font-family: var(--read); color: var(--cream-dim); text-align: center; padding: 56px 20px; line-height: 1.7; }
.uv-empty p { margin: 0; }
.uv-empty .uv-empty-h { font-size: 1.08rem; color: var(--cream); margin-bottom: 4px; }
.uv-empty-ic { display: inline-flex; vertical-align: -0.14em; }
.uv-empty-ic .ic { width: 16px; height: 16px; }
.uv-empty .auth-btn { margin-top: 6px; }
.lesson-card { cursor: pointer; }

/* ── Lists (cards, shared view, add-to-list modal) ────────────────────────── */
.list-btn { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; color: var(--cream-faint); padding: 2px; transition: color .15s, transform .15s; }
.list-btn svg { width: 17px; height: 17px; }
.list-btn:hover { color: var(--cool); transform: scale(1.1); }
.p-list { margin-top: 2px; }
.uv-newlist { font-family: var(--mono); font-size: 0.78rem; color: var(--on-accent); background: var(--cream); border: 1px solid var(--cream); border-radius: 100px; padding: 9px 18px; cursor: pointer; font-weight: 500; margin-bottom: 16px; }
.uv-newlist:hover { opacity: 0.9; }
.uv-listcard { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border: 1px solid var(--paper-edge); border-radius: 12px; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); }
.uv-listmain { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; text-decoration: none; }
.uv-listtitle { font-family: var(--serif); font-size: 1.04rem; color: var(--cream); }
.uv-listacts { display: flex; gap: 6px; flex-shrink: 0; }
.uv-iconbtn { font-family: var(--mono); font-size: 0.66rem; color: var(--cream-dim); background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 100px; padding: 5px 11px; cursor: pointer; transition: color .15s, border-color .15s; }
.uv-iconbtn:hover { color: var(--cream); border-color: var(--cool); }
.uv-del:hover { color: var(--rose); border-color: var(--rose); }
.uv-backlink { display: inline-block; font-family: var(--mono); font-size: 0.74rem; color: var(--cream-dim); text-decoration: none; margin-bottom: 14px; }
.uv-backlink:hover { color: var(--cool); }
.uv-listbtns { display: flex; gap: 10px; align-items: center; margin-top: 12px; }
.uv-toast { position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--ink-3); color: var(--cream); border: 1px solid var(--cool-deep); border-radius: 100px; padding: 10px 20px; font-family: var(--mono); font-size: 0.76rem; z-index: 300; opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; box-shadow: 0 14px 36px -12px rgba(0,0,0,.6); }
.uv-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ── Custom modal (replaces native prompt/confirm) ─────────────── */
.ui-modal { position: fixed; inset: 0; z-index: 320; display: flex; align-items: center; justify-content: center; animation: uiFade .15s ease; }
@keyframes uiFade { from { opacity: 0; } }
.ui-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 62%, transparent); }
.ui-card { position: relative; width: min(380px, calc(100vw - 32px)); background: linear-gradient(168deg, var(--ink-3), var(--ink)); border: 1px solid var(--paper-edge); border-radius: 16px; box-shadow: 0 30px 80px -20px rgba(0,0,0,.6); padding: 22px 22px 18px; }
.ui-title { font-family: var(--serif); font-weight: 600; font-size: 1.2rem; color: var(--cream); }
.ui-msg { color: var(--cream-dim); font-size: 0.9rem; margin-top: 6px; line-height: 1.5; }
.ui-input { width: 100%; margin-top: 14px; padding: 10px 12px; font-family: var(--read); font-size: 0.95rem; background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 9px; color: var(--cream); }
.ui-input:focus { outline: none; border-color: var(--cool); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool) 16%, transparent); }
.ui-acts { display: flex; justify-content: flex-end; gap: 9px; margin-top: 18px; }
.ui-btn { font-family: var(--mono); font-size: 0.76rem; padding: 9px 16px; border-radius: 9px; cursor: pointer; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream-dim); transition: all .15s; }
.ui-cancel:hover { color: var(--cream); border-color: var(--cool-deep); }
.ui-ok { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 600; }
.ui-ok:hover { opacity: .9; }
.ui-danger { background: #d9544d; border-color: #d9544d; color: #fff; }
.ui-danger:hover { opacity: .9; color: #fff; }

/* ── About page ────────────────────────────────────────────────── */
.about[hidden] { display: none; }
.about-inner { max-width: 880px; margin: 0 auto; padding: 56px 28px 90px; }
.about-kicker { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--cool); }
.about-h { font-family: var(--serif); font-weight: 700; font-size: clamp(2rem, 6vw, 3.1rem); letter-spacing: -0.03em; line-height: 1.05; margin: 10px 0 14px; }
.theme-editorial .about-h, .theme-softclub .about-h { font-weight: 400; }
.about-lede { font-family: var(--read); font-size: 1.12rem; line-height: 1.6; color: var(--cream-dim); max-width: 60ch; }
.about-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; margin: 36px 0; }
.about-card { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 14px; padding: 20px; }
.about-ico { font-size: 1.05rem; color: var(--cool); }
.about-card h3 { font-family: var(--serif); font-weight: 600; font-size: 1.18rem; margin: 8px 0 7px; color: var(--cream); }
.about-card p { font-size: 0.9rem; line-height: 1.55; color: var(--cream-dim); }
.about-card b, .about-body b { color: var(--cream); }
.about-sub { font-family: var(--serif); font-weight: 600; font-size: 1.4rem; margin: 30px 0 10px; color: var(--cream); }
.about-body { font-family: var(--read); font-size: 1rem; line-height: 1.65; color: var(--cream-dim); max-width: 64ch; }
.about-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.btn-ghost { background: transparent; border: 1px solid var(--paper-edge); color: var(--cream-dim); }
.btn-ghost:hover { border-color: var(--cool); color: var(--cream); }
@media (max-width: 720px) { .about-inner { padding: 34px 16px 70px; } }

/* ── Profile page ──────────────────────────────────────────────── */
.pf-top { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 22px; }
.pf-av { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.pf-id { flex: 1; min-width: 0; }
.pf-name { font-family: var(--serif); font-weight: 700; font-size: 1.7rem; color: var(--cream); line-height: 1.1; }
.pf-handle { font-family: var(--mono); font-size: 0.78rem; color: var(--cream-faint); }
.pf-bio { font-family: var(--read); font-size: 0.95rem; color: var(--cream-dim); line-height: 1.5; margin: 9px 0 0; max-width: 60ch; }
.pf-social-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 10px; }
.pf-url { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 0.76rem; color: var(--cool); text-decoration: none; }
.pf-url:hover { text-decoration: underline; }
.pf-url .link-ico { width: 13px; height: 13px; }
.pf-social { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); text-decoration: none; border: 1px solid var(--paper-edge); border-radius: 100px; padding: 3px 11px; transition: all .15s; }
.pf-social:hover { color: var(--cream); border-color: var(--cool-deep); }
.pf-actions { flex-shrink: 0; display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
.pf-edit { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; gap: 7px; font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 100px; padding: 7px 14px; cursor: pointer; transition: all .16s; text-decoration: none; }
.pf-edit:hover { color: var(--cream); border-color: var(--cool-deep); }
.pf-edit .lf-ico .ic { width: 13px; height: 13px; }
/* profile edit modal */
.pfe-card { width: min(440px, calc(100vw - 32px)); }
.pfe-field { display: block; margin-top: 12px; }
.pfe-field > span { display: block; font-family: var(--mono); font-size: 0.64rem; letter-spacing: .06em; text-transform: uppercase; color: var(--cream-faint); margin-bottom: 5px; }
.pfe-field input, .pfe-field textarea { width: 100%; padding: 9px 11px; font-family: var(--read); font-size: 0.92rem; background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 9px; color: var(--cream); resize: vertical; box-sizing: border-box; }
.pfe-field input:focus, .pfe-field textarea:focus { outline: none; border-color: var(--cool); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool) 16%, transparent); }
.pfe-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 480px) { .pfe-row { grid-template-columns: 1fr; } }
.pf-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 26px; }
.pf-stat { background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; padding: 16px 12px; text-align: center; }
.pf-statn { display: block; font-family: var(--serif); font-weight: 700; font-size: 1.7rem; color: var(--cream); line-height: 1; }
.pf-statl { font-family: var(--mono); font-size: 0.58rem; letter-spacing: .05em; text-transform: uppercase; color: var(--cream-faint); margin-top: 6px; display: block; }
.pf-resume { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; background: color-mix(in srgb, var(--cool) 12%, transparent); border: 1px solid color-mix(in srgb, var(--cool) 30%, transparent); border-radius: 14px; padding: 16px 18px; margin-bottom: 8px; }
.pf-rlabel { font-family: var(--mono); font-size: 0.62rem; letter-spacing: .06em; text-transform: uppercase; color: var(--cool); display: block; }
.pf-rtitle { font-family: var(--serif); font-weight: 600; font-size: 1.2rem; color: var(--cream); text-decoration: none; display: block; margin: 3px 0; }
.pf-rtitle:hover { color: var(--cool); }
.pf-rmeta { font-family: var(--mono); font-size: 0.68rem; color: var(--cream-faint); }
.pf-h { font-family: var(--serif); font-weight: 600; font-size: 1.2rem; color: var(--cream); margin: 26px 0 12px; }
.pf-courses { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.pf-course { display: block; background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; padding: 14px 16px; text-decoration: none; transition: border-color .18s, transform .18s; }
.pf-course:hover { border-color: var(--cool-deep); transform: translateY(-2px); }
.pf-crow { display: flex; justify-content: space-between; align-items: baseline; }
.pf-ctitle { font-family: var(--serif); font-weight: 600; font-size: 1rem; color: var(--cream); }
.pf-cnum { font-family: var(--mono); font-size: 0.7rem; color: var(--cool); }
.pf-cmeta { font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); text-transform: uppercase; letter-spacing: .05em; }
.pf-bar { height: 6px; border-radius: 100px; background: var(--ink); margin-top: 9px; overflow: hidden; }
.pf-bar-fill { height: 100%; background: var(--cool); border-radius: 100px; }
.pf-streak { display: flex; gap: 3px; overflow-x: auto; padding-bottom: 4px; }
.pf-week { display: flex; flex-direction: column; gap: 3px; }
.pf-cell { width: 13px; height: 13px; border-radius: 3px; background: var(--paper-edge); flex-shrink: 0; }
.pf-cell-future { background: transparent; }
.pf-l0 { background: color-mix(in srgb, var(--cream) 8%, transparent); }
.pf-l1 { background: color-mix(in srgb, var(--cool) 35%, var(--ink-2)); }
.pf-l2 { background: color-mix(in srgb, var(--cool) 65%, var(--ink-2)); }
.pf-l3 { background: var(--cool); }
.pf-legend { display: flex; align-items: center; gap: 4px; margin-top: 8px; font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); }
.pf-legend .pf-cell { width: 11px; height: 11px; }
.pf-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }
.pf-link { font-family: var(--mono); font-size: 0.8rem; color: var(--cream-dim); text-decoration: none; background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 100px; padding: 9px 16px; transition: all .16s; }
.pf-link:hover { color: var(--cream); border-color: var(--cool-deep); }
@media (max-width: 560px) { .pf-stats { grid-template-columns: repeat(2, 1fr); } }

.userview[hidden] { display: none !important; }

/* ── Sandbox page ──────────────────────────────────────────────── */
/* the sandbox view is wider than other userviews so the editor fits ~120+ chars */
#labView { max-width: 1300px; }
.lab { display: grid; grid-template-columns: 210px 1fr; gap: 16px; align-items: start; }
.lab-list { display: flex; flex-direction: column; gap: 6px; }
.lab-new-wrap { position: relative; margin-bottom: 6px; }
.lab-new { width: 100%; font-family: var(--mono); font-size: 0.74rem; padding: 9px 12px; border-radius: 9px; cursor: pointer; border: 1px solid var(--cool); background: color-mix(in srgb, var(--cool) 14%, transparent); color: var(--cream); text-align: left; }
.lab-new:hover { background: color-mix(in srgb, var(--cool) 22%, transparent); }
.lab-tmpl { position: absolute; top: calc(100% + 5px); left: 0; right: 0; z-index: 20; padding: 6px; border-radius: 11px;
  background: linear-gradient(168deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); box-shadow: 0 18px 44px -18px rgba(0,0,0,.6); }
.lab-tmpl-h { font-family: var(--mono); font-size: 0.58rem; letter-spacing: .08em; text-transform: uppercase; color: var(--cream-faint); padding: 4px 8px 6px; }
.lab-tmpl-item { display: block; width: 100%; text-align: left; font-family: var(--mono); font-size: 0.74rem; color: var(--cream-dim);
  background: none; border: none; border-radius: 7px; padding: 7px 9px; cursor: pointer; transition: background .14s, color .14s; }
.lab-tmpl-item:hover { background: color-mix(in srgb, var(--cool) 14%, transparent); color: var(--cream); }
.lab-item { display: flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 0.78rem; padding: 8px 8px 8px 12px; border-radius: 9px; cursor: pointer; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream-dim); transition: border-color .15s, background .15s, color .15s; }
.lab-item:hover { color: var(--cream); border-color: var(--cool-deep); }
.lab-item.on { color: var(--cream); border-color: var(--cool); background: color-mix(in srgb, var(--cool) 12%, transparent); }
.lab-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lab-item-rename, .lab-item-del { flex-shrink: 0; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; border-radius: 6px; background: none; color: var(--cream-faint); cursor: pointer; opacity: 0; transition: opacity .14s, color .14s, background .14s; }
.lab-item-rename .ic, .lab-item-del .ic { width: 13px; height: 13px; }
.lab-item:hover .lab-item-rename, .lab-item:hover .lab-item-del, .lab-item.on .lab-item-rename, .lab-item.on .lab-item-del { opacity: 1; }
.lab-item-rename:hover { color: var(--cool); background: color-mix(in srgb, var(--cool) 16%, transparent); }
.lab-item-del:hover { color: var(--rose); background: color-mix(in srgb, var(--rose) 16%, transparent); }
.lab-item-edit { flex: 1; min-width: 0; font-family: var(--mono); font-size: 0.78rem; padding: 2px 6px; background: var(--ink); border: 1px solid var(--cool); border-radius: 6px; color: var(--cream); outline: none; }
.lab-main { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.lab-blank { font-family: var(--read); color: var(--cream-faint); padding: 40px 4px; }
.lab-code { min-height: 240px; }
.lab-out { display: flex; gap: 14px; flex-wrap: wrap; }
#labCanvas { width: 300px; height: 300px; border: 1px solid var(--paper-edge); border-radius: 10px; background: var(--ink); flex-shrink: 0; }
.lab-log { flex: 1; min-width: 200px; min-height: 120px; max-height: 300px; overflow: auto; font-family: var(--mono); font-size: 0.78rem; line-height: 1.5; color: var(--cream-dim); background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 10px 12px; margin: 0; white-space: pre-wrap; }
.lab-log.err { color: #e0726b; border-color: color-mix(in srgb, #d9544d 45%, transparent); }
.uv-sub code { font-family: var(--mono); font-size: 0.85em; background: var(--ink); padding: 1px 5px; border-radius: 4px; color: var(--cream); }
@media (max-width: 640px) { .lab { grid-template-columns: 1fr; } }
.al-card { width: min(360px, calc(100vw - 32px)); }
.al-list { display: flex; flex-direction: column; gap: 5px; max-height: 280px; overflow-y: auto; margin-bottom: 14px; }
.al-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--paper-edge); border-radius: 10px; background: var(--ink-2); cursor: pointer; text-align: left; transition: border-color .15s; }
.al-row:hover { border-color: var(--cool); }
.al-row.on { border-color: var(--cool); background: color-mix(in srgb, var(--cool) 14%, var(--ink-2)); }
.al-check { width: 18px; height: 18px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--paper-edge); border-radius: 5px; color: var(--cool); font-size: 0.8rem; }
.al-row.on .al-check { background: var(--cool); color: var(--on-accent); border-color: var(--cool); }
.al-name { flex: 1; min-width: 0; font-family: var(--read); font-size: 0.88rem; color: var(--cream); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.al-count { font-family: var(--mono); font-size: 0.66rem; color: var(--cream-faint); }
.al-none { font-family: var(--read); color: var(--cream-faint); padding: 16px; text-align: center; }
.al-new { display: flex; gap: 8px; }
.al-new input { flex: 1; min-width: 0; font-family: var(--mono); font-size: 0.84rem; color: var(--cream); background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 9px 11px; }
.al-new input:focus { outline: none; border-color: var(--cool); }
.al-create { margin-top: 0; white-space: nowrap; padding: 9px 14px; }

/* ── Learning paths (graph highlight + picker) ────────────────────────────── */
.graph-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.graph-head-label { margin-right: auto; }
.path-picker { position: relative; }
/*  The neon frame is permanent - it is what marks this out as the one control
    in the header worth pressing, and "reset view" beside it stays deliberately
    plain so the contrast reads. Only the movement below is first-visit-only.
    --cool is theme-defined, so the frame comes out electric on neurons and
    muted on the paper themes without a per-theme rule. Held in a custom
    property because @keyframes path-nudge has to re-state it on every frame:
    box-shadow is one animatable value, so the breathing ring would otherwise
    wipe the glow out for the length of the animation. */
.path-trigger {
  --path-neon: 0 0 11px -2px color-mix(in srgb, var(--cool) 50%, transparent),
               inset 0 0 9px -5px color-mix(in srgb, var(--cool) 60%, transparent);
  position: relative; overflow: hidden; display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 0.7rem; color: var(--cream);
  background: var(--ink-2);
  border: 1px solid color-mix(in srgb, var(--cool) 55%, var(--paper-edge));
  box-shadow: var(--path-neon);
  border-radius: 100px; padding: 6px 13px; cursor: pointer;
  transition: border-color .18s, color .18s, box-shadow .18s;
}
.path-trigger svg { color: var(--cool); }
.path-trigger:hover {
  border-color: var(--cool); color: var(--cream);
  box-shadow: 0 0 16px -2px color-mix(in srgb, var(--cool) 68%, transparent),
              inset 0 0 9px -5px color-mix(in srgb, var(--cool) 60%, transparent);
}
/* ── First-visit motion ─────────────────────────────────────────
   The frame above is always on; this is the part that only runs until the
   picker has been opened once. A ring breathing outward says "there is
   something here" without the jitter of a bounce. It stops for good on the
   first click - a nudge that keeps nudging after you have answered it is
   just noise, and the neon frame goes on doing the standing job afterwards. */
@keyframes path-nudge {
  0%   { box-shadow: var(--path-neon), 0 0 0 0 color-mix(in srgb, var(--cool) 50%, transparent); }
  62%  { box-shadow: var(--path-neon), 0 0 0 11px transparent; }
  100% { box-shadow: var(--path-neon), 0 0 0 0 transparent; }
}
.path-trigger.nudge { animation: path-nudge 2.8s ease-out infinite; }

/*  Three cues on one 2.8s beat, so the control pulses once rather than
    fidgeting in three rhythms at once:

    the ring above, which claims the space around the pill;
    a sheen crossing the face, which is what actually catches the eye at the
    edge of vision - peripheral sight is far better at movement than at
    colour, and the ring alone only ever grows outward into empty page;
    and the route glyph drawing itself, at the same 1.1s as .learn-path-line
    on the graph. That last one is the reason to prefer this over a bounce:
    the icon is a dashed path between two points, so animating it previews
    the thing the button does instead of just waving for attention. */
.path-trigger.nudge::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg,
    transparent 42%,
    color-mix(in srgb, var(--cool) 34%, transparent) 50%,
    transparent 58%);
  animation: path-sheen 2.8s ease-out infinite;
}
@keyframes path-sheen {
  0%        { transform: translateX(-115%); }
  55%, 100% { transform: translateX(115%); }
}
/*  dasharray is 2.5 2.5, so a 10px offset is two whole dashes - the loop
    closes on itself with no jump */
.path-trigger.nudge svg path { animation: path-glyph 1.1s linear infinite; }
@keyframes path-glyph { to { stroke-dashoffset: -10; } }

@media (prefers-reduced-motion: reduce) {
  /* keep the colour cue, drop every bit of the movement */
  .path-trigger.nudge,
  .path-trigger.nudge::after,
  .path-trigger.nudge svg path { animation: none; }
  .path-trigger.nudge::after { content: none; }
}
.path-menu { position: absolute; top: calc(100% + 7px); right: 0; min-width: 240px; background: linear-gradient(170deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 12px; box-shadow: 0 18px 44px -14px rgba(0,0,0,.5); padding: 5px; z-index: 60; list-style: none; margin: 0; }
.path-menu[hidden] { display: none; }
.path-item { display: flex; align-items: center; gap: 9px; font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); padding: 9px 11px; border-radius: 8px; cursor: pointer; transition: background .15s, color .15s; }
.path-item:hover { background: color-mix(in srgb, var(--cool) 14%, transparent); color: var(--cream); }
.path-item.on { color: var(--cream); background: color-mix(in srgb, var(--cool) 10%, transparent); }
.path-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.learn-path-halo { fill: none; stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; opacity: 0.16; }
.learn-path-line { fill: none; stroke-width: 2.4; stroke-dasharray: 7 6; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; opacity: 0.95; animation: pathdash 1.1s linear infinite; }
@keyframes pathdash { to { stroke-dashoffset: -26; } }
#graphSvg.has-path .gnode:not(.on-path) { opacity: 0.14; transition: opacity .2s; }
#graphSvg.has-path .gedge { opacity: 0.05; }
.gnode.on-path circle { stroke: var(--cream); stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.gnode.on-path text { opacity: 1; font-weight: 600; }

/* ── Avatar emoji + mobile hamburger nav ──────────────────────────────────── */
.auth-av-emoji { display: inline-flex; align-items: center; justify-content: center; font-size: 14px; line-height: 1; }
/* hamburger - hidden on desktop; on mobile it sits at the far left (before the logo) */
.nav-burger { display: none; background: none; border: none; border-radius: 9px; width: 34px; height: 32px; color: var(--cream); cursor: pointer; align-items: center; justify-content: center; padding: 0; transition: color .18s, background .18s; flex-shrink: 0; margin-left: -6px; }
.nav-burger:hover { color: var(--cool); background: color-mix(in srgb, var(--cream) 8%, transparent); }
/* left slide-in drawer chrome (only visible inside the drawer on mobile) */
.nav-drawer-head { display: none; align-items: center; justify-content: space-between; margin: 0 4px 10px; padding-bottom: 10px; border-bottom: 1px solid var(--paper-edge); }
.nav-drawer-title { font-family: var(--serif); font-weight: 700; font-size: 1.1rem; color: var(--cream); }
.nav-drawer-x { background: none; border: none; color: var(--cream-faint); font-size: 1rem; cursor: pointer; padding: 4px 6px; line-height: 1; border-radius: 8px; transition: color .15s, background .15s; }
.nav-drawer-x:hover { color: var(--cream); background: color-mix(in srgb, var(--cream) 10%, transparent); }
.nav-scrim {
  position: fixed; inset: 0; z-index: 90; background: color-mix(in srgb, var(--ink) 66%, transparent);
  opacity: 0; pointer-events: none; transition: opacity .24s ease;
}
.nav-scrim.open { opacity: 1; pointer-events: auto; }
body.nav-drawer-open { overflow: hidden; }
/* the drawer lives inside the navbar's stacking context; lift the whole bar
   above the scrim while open so only the page behind dims (drawer stays sharp) */
body.nav-drawer-open .navbar { z-index: 200; }

@media (max-width: 720px) {
  .nav-burger { display: inline-flex; order: -1; margin-right: 2px; }
  .nav-drawer-head { display: flex; }
  .nav-links {
    position: fixed; top: 0; left: 0; height: 100vh; height: 100dvh; width: min(78vw, 280px);
    flex-direction: column; align-items: stretch; gap: 4px;
    background: linear-gradient(170deg, var(--ink-3), var(--ink-2));
    border-right: 1px solid var(--paper-edge);
    padding: 14px 14px 20px; z-index: 95; overflow-y: auto;
    transform: translateX(-100%); transition: transform .26s cubic-bezier(.4, 0, .2, 1);
  }
  /* shadow only when open - otherwise it bleeds onto the screen's left edge (the "dark vignette") */
  .nav-links.open { transform: translateX(0); box-shadow: 24px 0 60px -22px rgba(0,0,0,.6); }
  .nav-link { padding: 12px 14px; font-size: 0.92rem; border-radius: 9px; }
  .nav-link:hover, .nav-link.active { background: color-mix(in srgb, var(--cool) 14%, transparent); }
  .auth-btn { padding: 6px 12px; font-size: 0.7rem; }
  .auth-chip { padding: 3px 8px 3px 3px; }
}

/* ── Spark mascot + guided tours ───────────────────────────────── */
.spark-fox { width: 80px; height: auto; image-rendering: pixelated; animation: sparkBob 2.4s ease-in-out infinite; }
.spark-big { width: 118px; }
@keyframes sparkBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-6%); } }
.spark-hub { max-width: 880px; margin: 0 auto; padding: 50px 28px 90px; }
.spark-hub-head { display: flex; align-items: center; gap: 20px; margin-bottom: 30px; flex-wrap: wrap; }
.spark-hub-h { font-family: var(--serif); font-weight: 700; font-size: clamp(1.8rem, 5vw, 2.6rem); letter-spacing: -0.02em; }
.spark-hub-sub { font-family: var(--read); font-size: 1.05rem; color: var(--cream-dim); max-width: 50ch; margin-top: 6px; }
.spark-hub-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
.spark-tour-card { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-align: left; cursor: pointer; padding: 20px; border-radius: 16px; border: 1px solid var(--paper-edge); background: linear-gradient(165deg, var(--ink-3), var(--ink-2)); transition: border-color .2s, transform .2s, box-shadow .25s; }
.spark-tour-card:hover { border-color: var(--cool); transform: translateY(-3px); box-shadow: 0 16px 36px -18px rgba(0,0,0,.5); }
.spark-card-fox { width: 56px; }
.spark-tour-name { font-family: var(--serif); font-weight: 600; font-size: 1.15rem; color: var(--cream); }
.spark-tour-blurb { font-size: 0.88rem; color: var(--cream-dim); line-height: 1.5; }
.spark-tour-go { font-family: var(--mono); font-size: 0.72rem; color: var(--cool); margin-top: 2px; }

body.spark-open { overflow: hidden; }
.spark-ov { position: fixed; inset: 0; z-index: 340; display: flex; align-items: center; justify-content: center; }
.spark-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 86%, transparent); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.spark-stage { position: relative; width: min(680px, calc(100vw - 32px)); max-height: calc(100vh - 40px); overflow-y: auto; background: linear-gradient(168deg, var(--ink-3), var(--ink-2)); border: 1px solid var(--paper-edge); border-radius: 20px; box-shadow: 0 40px 100px -24px rgba(0,0,0,.7); padding: 24px 26px 22px; }
.spark-in { animation: sparkIn .28s cubic-bezier(.2,.7,.2,1); }
@keyframes sparkIn { from { opacity: 0; transform: translateY(14px) scale(.98); } }
.spark-x { position: absolute; top: 12px; right: 14px; background: none; border: none; color: var(--cream-faint); font-size: 1rem; cursor: pointer; padding: 4px 7px; border-radius: 8px; z-index: 2; }
.spark-x:hover { color: var(--cream); background: color-mix(in srgb, var(--cream) 10%, transparent); }
.spark-kick { font-family: var(--mono); font-size: 0.62rem; letter-spacing: .12em; text-transform: uppercase; color: var(--cool); }
.spark-scene { display: flex; align-items: center; justify-content: center; min-height: 190px; margin: 14px 0 6px; }
.spark-talk { display: flex; align-items: flex-end; gap: 12px; margin-top: 8px; }
.spark-talk-fox { width: 62px; flex-shrink: 0; }
.spark-bubble { position: relative; flex: 1; background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 14px; padding: 13px 16px; }
.spark-bubble::before { content: ""; position: absolute; left: -7px; bottom: 16px; width: 12px; height: 12px; background: var(--ink); border-left: 1px solid var(--paper-edge); border-bottom: 1px solid var(--paper-edge); transform: rotate(45deg); }
.spark-h { font-family: var(--serif); font-weight: 600; font-size: 1.15rem; color: var(--cream); margin-bottom: 4px; }
.spark-text { font-family: var(--read); font-size: 0.96rem; line-height: 1.55; color: var(--cream-dim); }
.spark-text b { color: var(--cream); } .spark-text a { color: var(--cool); }
.spark-nav { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 18px; }
.spark-btn { font-family: var(--mono); font-size: 0.76rem; padding: 9px 16px; border-radius: 9px; cursor: pointer; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream-dim); transition: all .15s; }
.spark-btn:disabled { opacity: .4; cursor: default; }
.spark-btn:not(:disabled):hover { color: var(--cream); border-color: var(--cool-deep); }
.spark-primary { color: var(--on-accent); background: var(--cream); border-color: var(--cream); font-weight: 600; }
.spark-primary:hover { color: var(--on-accent); opacity: .9; }
.spark-dots { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.spark-dot { width: 8px; height: 8px; border-radius: 50%; border: none; background: var(--paper-edge); cursor: pointer; padding: 0; }
.spark-dot.on { background: var(--cool); }

.spark-card { width: 100%; max-width: 430px; background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 14px; padding: 16px 18px; }
.spark-card-top { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.spark-card-logo { width: 34px; height: 34px; border-radius: 8px; background: #fff; object-fit: contain; flex-shrink: 0; }
.spark-card-logo-fb { width: 34px; height: 34px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; background: var(--cool-deep); color: #fff; font-family: var(--mono); font-weight: 700; font-size: 0.8rem; flex-shrink: 0; }
.spark-card-y { font-family: var(--mono); font-size: 0.62rem; color: var(--cream-faint); text-transform: uppercase; letter-spacing: .04em; }
.spark-card-t { font-family: var(--serif); font-weight: 600; font-size: 1.12rem; color: var(--cream); line-height: 1.15; }
.spark-card-s { font-size: 0.86rem; line-height: 1.5; color: var(--cream-dim); margin: 8px 0; }
.spark-card-link { font-family: var(--mono); font-size: 0.72rem; color: var(--cool); text-decoration: none; }
.spark-card-link:hover { text-decoration: underline; }

.spark-neuron { width: 100%; max-width: 430px; }
.spark-n-in, .spark-n-sum, .spark-n-out, .spark-n-bias, .spark-n-act { fill: var(--ink-2); stroke: var(--cream-faint); stroke-width: 1.5; transition: all .2s; }
.spark-n-edge { stroke: var(--cream-faint); stroke-width: 1.5; transition: all .2s; }
.spark-n-step { fill: none; stroke: var(--cool); stroke-width: 2; }
.spark-n-lab, .spark-n-wlab, .spark-n-sig { fill: var(--cream-dim); font-family: var(--mono); font-size: 11px; text-anchor: middle; }
.spark-n-sig { font-size: 17px; fill: var(--cream); }
.spark-hl .spark-n-in, .spark-hl .spark-n-sum, .spark-hl .spark-n-out, .spark-hl .spark-n-bias, .spark-hl .spark-n-act { stroke: var(--cool); stroke-width: 2.5; fill: color-mix(in srgb, var(--cool) 20%, var(--ink-2)); }
.spark-hl .spark-n-edge { stroke: var(--cool); stroke-width: 2.5; }
.spark-hl .spark-n-lab, .spark-hl .spark-n-sig, .spark-hl .spark-n-wlab { fill: var(--cream); }
.spark-eq { color: var(--cream); }
@media (max-width: 560px) { .spark-talk-fox { width: 48px; } .spark-stage { padding: 20px 18px; } .spark-big { width: 96px; } }

/* ── Spark paper reader: "Walk through the Transformer" ─────────────────── */
.spp-ov { position: fixed; inset: 0; z-index: 345; display: flex; align-items: center; justify-content: center; }
.spp-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 88%, transparent); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.spp-shell { position: relative; display: flex; width: min(1180px, calc(100vw - 28px)); height: calc(100vh - 36px); background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 18px; overflow: hidden; box-shadow: 0 40px 110px -26px rgba(0,0,0,.72); }

/* reader (the real arXiv PDF, embedded) */
.spp-reader { flex: 1.55 1 0; min-width: 0; display: flex; flex-direction: column; overflow: hidden; background: var(--ink-3); }
.spp-pdfhead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 18px; border-bottom: 1px solid var(--paper-edge); }
.spp-pdfmeta { font-size: 0.76rem; color: var(--cream-dim); }
.spp-pdftitle { font-family: var(--serif); font-weight: 600; color: var(--cream); }
.spp-pdfmeta a { color: var(--cool); }
.spp-pdf { flex: 1 1 auto; width: 100%; border: 0; background: #525659; }
.spp-pdffall { padding: 14px 18px; font-size: 0.82rem; color: var(--cream-dim); border-top: 1px solid var(--paper-edge); }
.spp-pdffall a { color: var(--cool); }
.spp-paperhead { border-bottom: 1px solid var(--paper-edge); padding-bottom: 18px; margin-bottom: 8px; }
.spp-badge { display: inline-flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 0.66rem; letter-spacing: .08em; text-transform: uppercase; color: var(--cool); background: color-mix(in srgb, var(--cool) 14%, transparent); border: 1px solid color-mix(in srgb, var(--cool) 35%, transparent); border-radius: 20px; padding: 4px 10px 4px 6px; }
.spp-badge-fox { width: 20px; height: 18px; }
.spp-title { font-family: var(--serif); font-size: clamp(1.5rem, 3vw, 2.1rem); line-height: 1.12; margin: 12px 0 8px; color: var(--cream); }
.spp-auth { font-size: 0.84rem; color: var(--cream-dim); line-height: 1.5; }
.spp-venue { font-family: var(--mono); font-size: 0.72rem; color: var(--cream-faint); margin-top: 5px; }
.spp-venue a { color: var(--cool); }
.spp-sec { margin-top: 24px; }
.spp-sec-h { font-family: var(--mono); font-size: 0.74rem; letter-spacing: .07em; text-transform: uppercase; color: var(--cool); margin: 0 0 8px; }
.spp-block { position: relative; padding: 10px 14px; margin: 0 -14px 6px; border-radius: 10px; border: 1px solid transparent; cursor: pointer; transition: background .25s, border-color .25s; }
.spp-block:hover { background: color-mix(in srgb, var(--cream) 4%, transparent); }
.spp-block.spp-active { background: color-mix(in srgb, var(--cool) 12%, transparent); border-color: color-mix(in srgb, var(--cool) 45%, transparent); }
.spp-block.spp-active::before { content: ""; position: absolute; left: -1px; top: 8px; bottom: 8px; width: 3px; border-radius: 3px; background: var(--cool); }
.spp-block p { font-size: 0.95rem; line-height: 1.62; color: var(--cream); margin: 0 0 10px; }
.spp-block p:last-child { margin-bottom: 0; }
.spp-block em { color: var(--cream); font-style: italic; }
.spp-eq { color: var(--cream); margin: 12px 0; padding: 6px 4px; overflow-x: auto; }

/* guide (Spark companion) */
.spp-guide { flex: 1 1 0; min-width: 320px; max-width: 440px; display: flex; flex-direction: column; background: var(--ink-3); border-left: 1px solid var(--paper-edge); position: relative; }
.spp-x { position: absolute; top: 12px; right: 12px; z-index: 2; width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream-dim); cursor: pointer; font-size: 0.9rem; }
.spp-x:hover { color: var(--cream); border-color: var(--cool); }
.spp-guide-in { flex: 1 1 auto; overflow-y: auto; padding: 20px 20px 14px; }
.spp-guide-loc { display: flex; align-items: center; gap: 8px; justify-content: space-between; margin-bottom: 14px; padding-right: 30px; }
.spp-guide-loc .spp-guide-sec { display: block; font-family: var(--mono); font-size: 0.66rem; letter-spacing: .06em; text-transform: uppercase; color: var(--cool); margin: 0; }
.spp-jump { flex: 0 0 auto; font-family: var(--mono); font-size: 0.64rem; padding: 4px 9px; border-radius: 7px; border: 1px solid color-mix(in srgb, var(--cool) 40%, transparent); background: color-mix(in srgb, var(--cool) 12%, transparent); color: var(--cool); cursor: pointer; }
.spp-jump:hover { background: color-mix(in srgb, var(--cool) 22%, transparent); }
.spp-guide-talk { display: flex; gap: 11px; align-items: flex-start; }
.spp-guide-fox { width: 44px; height: 40px; flex: 0 0 auto; margin-top: 2px; }
.spp-guide-sec { display: block; font-family: var(--mono); font-size: 0.62rem; letter-spacing: .07em; text-transform: uppercase; color: var(--cool); margin-bottom: 3px; }
.spp-guide-kick { font-family: var(--serif); font-size: 1.12rem; line-height: 1.2; color: var(--cream); font-weight: 600; }
.spp-guide-note { font-size: 0.88rem; line-height: 1.58; color: var(--cream-dim); margin-top: 8px; }
.spp-guide-note b { color: var(--cream); }
.spp-guide-viz { margin-top: 16px; }
.spp-guide-viz[hidden] { display: none; }
.spp-guide-nav { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-top: 1px solid var(--paper-edge); background: var(--ink-2); }
.spp-nav-btn { font-family: var(--mono); font-size: 0.78rem; padding: 8px 14px; border-radius: 9px; border: 1px solid var(--paper-edge); background: transparent; color: var(--cream); cursor: pointer; }
.spp-nav-btn:disabled { opacity: .4; cursor: default; }
.spp-nav-primary { background: var(--cool); color: var(--ink); border-color: var(--cool); font-weight: 600; margin-left: auto; }
.spp-prog { display: flex; gap: 5px; flex-wrap: wrap; flex: 1 1 auto; justify-content: center; }
.spp-dot { width: 8px; height: 8px; border-radius: 50%; border: none; background: var(--paper-edge); cursor: pointer; padding: 0; }
.spp-dot.on { background: var(--cool); transform: scale(1.25); }

@media (max-width: 880px) {
  .spp-shell { flex-direction: column; width: calc(100vw - 16px); height: calc(100vh - 20px); }
  .spp-reader { flex: 1 1 auto; padding: 20px 18px 40px; }
  .spp-guide { max-width: none; min-width: 0; flex: 0 0 46%; border-left: none; border-top: 1px solid var(--paper-edge); }
}

/* ── visualisations ─────────────────────────────────────────────────────── */
/* Figure 1 architecture */
.spp-arch { width: 100%; max-width: 340px; display: block; margin: 0 auto; }
.spp-arch-stack { fill: color-mix(in srgb, var(--cream) 4%, transparent); stroke: var(--paper-edge); }
.spp-arch-attn { fill: color-mix(in srgb, var(--cool) 22%, var(--ink-2)); stroke: color-mix(in srgb, var(--cool) 50%, transparent); }
.spp-arch-cross { fill: color-mix(in srgb, var(--teal) 22%, var(--ink-2)); stroke: color-mix(in srgb, var(--teal) 50%, transparent); }
.spp-arch-ffn { fill: color-mix(in srgb, var(--amber) 20%, var(--ink-2)); stroke: color-mix(in srgb, var(--amber) 48%, transparent); }
.spp-arch-norm { fill: color-mix(in srgb, var(--cream) 8%, transparent); stroke: none; }
.spp-arch-soft { fill: color-mix(in srgb, var(--teal) 26%, var(--ink-2)); stroke: none; }
.spp-arch-lin { fill: color-mix(in srgb, var(--cream) 9%, transparent); stroke: none; }
.spp-arch-emb { fill: color-mix(in srgb, var(--cream) 7%, transparent); stroke: var(--paper-edge); }
.spp-arch-pe { fill: color-mix(in srgb, var(--cool) 30%, var(--ink-2)); stroke: var(--cool); }
.spp-arch-t { fill: var(--cream); font-size: 8.5px; text-anchor: middle; font-family: var(--mono); }
.spp-arch-tn { fill: var(--cream-dim); font-size: 7px; text-anchor: middle; font-family: var(--mono); }
.spp-arch-cap { fill: var(--cream-faint); font-size: 8px; text-anchor: middle; font-family: var(--mono); }
.spp-arch-lab { fill: var(--cream-dim); font-size: 9px; text-anchor: middle; font-family: var(--mono); letter-spacing: .05em; }
.spp-arch-nx { fill: var(--cream-faint); font-size: 8px; text-anchor: middle; font-family: var(--mono); }
.spp-arch-plus { fill: var(--cream); font-size: 11px; text-anchor: middle; dominant-baseline: middle; }
.spp-arch-flow, .spp-arch-flow2 { stroke: var(--cream-faint); stroke-width: 1.2; fill: none; opacity: .6; }
.spp-arch-flow { stroke: var(--teal); opacity: .8; marker-end: none; }
.spp-arch-hl rect, .spp-arch-hl circle { filter: drop-shadow(0 0 5px color-mix(in srgb, var(--cool) 80%, transparent)); }
.spp-arch-hl .spp-arch-stack { stroke: var(--cool); stroke-width: 2; }

/* attention demo */
.spp-attn-q { font-size: 0.82rem; color: var(--cream-dim); margin-bottom: 12px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.spp-tok { font-family: var(--mono); font-size: 0.8rem; padding: 4px 9px; border-radius: 7px; border: 1px solid var(--paper-edge); background: var(--ink-2); color: var(--cream); cursor: pointer; }
.spp-tok.on { background: var(--cool); color: var(--ink); border-color: var(--cool); font-weight: 600; }
.spp-attn-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
.spp-attn-head, .spp-attn-row { display: grid; grid-template-columns: 1.1fr 0.8fr 0.9fr 1.6fr; gap: 6px; align-items: center; font-size: 0.74rem; }
.spp-attn-head { font-family: var(--mono); color: var(--cream-faint); font-size: 0.66rem; padding-bottom: 4px; }
.spp-attn-row { padding: 3px 0; }
.spp-attn-key { font-family: var(--mono); color: var(--cream); }
.spp-attn-num { font-family: var(--mono); color: var(--cream-dim); }
.spp-attn-bar { position: relative; height: 16px; background: var(--ink-2); border-radius: 5px; overflow: hidden; display: flex; align-items: center; }
.spp-attn-fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--cool); border-radius: 5px; transition: width .35s; }
.spp-attn-bar b { position: relative; font-family: var(--mono); font-size: 0.64rem; color: var(--cream); padding-left: 6px; }
.spp-attn-heat-t { font-family: var(--mono); font-size: 0.66rem; color: var(--cream-faint); margin-bottom: 5px; }
.spp-attn-heat-t span { color: var(--cool); }
.spp-heatgrid { display: inline-flex; flex-direction: column; gap: 3px; }
.spp-heatrow { display: flex; gap: 3px; align-items: center; cursor: pointer; }
.spp-heathead { cursor: default; }
.spp-heatlab { width: 30px; font-family: var(--mono); font-size: 0.6rem; color: var(--cream-dim); text-align: right; }
.spp-heathead .spp-heatlab, .spp-heathead span { width: 30px; font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); text-align: center; }
.spp-heatcell { position: relative; width: 30px; height: 22px; border-radius: 4px; background: var(--ink-2); display: flex; align-items: center; justify-content: center; }
.spp-heatfill { position: absolute; inset: 0; border-radius: 4px; }
.spp-heatcell b { position: relative; font-family: var(--mono); font-size: 0.58rem; color: var(--cream); }
.spp-heatrow.on { outline: 1.5px solid var(--cool); outline-offset: 1px; border-radius: 5px; }
.spp-attn-axes { font-family: var(--mono); font-size: 0.58rem; color: var(--cream-faint); margin-top: 4px; padding-left: 33px; }
.spp-attn-out { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--paper-edge); }
.spp-attn-outlab { font-size: 0.78rem; color: var(--cream-dim); line-height: 1.5; }
.spp-vec { display: flex; align-items: flex-end; gap: 5px; height: 48px; margin-top: 10px; }
.spp-vec-bar { width: 16px; height: 100%; background: var(--ink-2); border-radius: 4px; display: flex; align-items: flex-end; overflow: hidden; }
.spp-vec-bar span { width: 100%; background: var(--teal); border-radius: 4px; transition: height .35s; }
.spp-vec-cap { font-family: var(--mono); font-size: 0.64rem; color: var(--cream-faint); align-self: center; margin-left: 6px; }

/* multi-head */
.spp-mh-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.spp-mh-name { font-family: var(--mono); font-size: 0.6rem; color: var(--cream-dim); margin-bottom: 5px; line-height: 1.3; height: 2.3em; }
.spp-heatmini .spp-heatcell { width: 100%; height: 13px; }
.spp-heatmini .spp-heatlab, .spp-heatmini .spp-heathead span { width: 22px; font-size: 0.52rem; }
.spp-heatmini .spp-heatrow { gap: 2px; }
.spp-mh-flow { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin: 14px 0 10px; }
.spp-mh-step { font-family: var(--mono); font-size: 0.68rem; padding: 5px 9px; border-radius: 7px; background: var(--ink-2); border: 1px solid var(--paper-edge); color: var(--cream-dim); }
.spp-mh-out { background: var(--cool); color: var(--ink); border-color: var(--cool); }
.spp-mh-arrow { color: var(--cream-faint); }
.spp-mh-note { font-size: 0.78rem; line-height: 1.5; color: var(--cream-dim); }

/* positional encoding */
.spp-pe-wrap { display: flex; gap: 6px; }
.spp-pe-yax { writing-mode: vertical-rl; transform: rotate(180deg); font-family: var(--mono); font-size: 0.6rem; color: var(--cream-faint); text-align: center; }
.spp-pe-grid { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.spp-pe-row { display: flex; gap: 2px; cursor: pointer; border-radius: 3px; padding: 1px; }
.spp-pe-row.on { outline: 1.5px solid var(--cool); }
.spp-pe-cell { flex: 1; height: 11px; border-radius: 2px; }
.spp-pe-xax { font-family: var(--mono); font-size: 0.58rem; color: var(--cream-faint); margin: 6px 0 0 18px; }
.spp-pe-read { margin-top: 12px; font-size: 0.78rem; color: var(--cream-dim); line-height: 1.5; }
.spp-pe-read b { color: var(--cream); }
.spp-pe-curve { width: 220px; max-width: 100%; height: 44px; margin-top: 6px; display: block; }
.spp-pe-axis { stroke: var(--paper-edge); stroke-width: 1; }
.spp-pe-line { fill: none; stroke: var(--cool); stroke-width: 1.6; }

/* sequential vs parallel */
.spp-seq { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.spp-seq-h { font-family: var(--mono); font-size: 0.66rem; color: var(--cool); margin-bottom: 8px; }
.spp-seq-chain, .spp-seq-fanrow { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.spp-seq-node { width: 26px; height: 26px; border-radius: 50%; background: var(--ink-2); border: 1px solid var(--paper-edge); display: grid; place-items: center; font-family: var(--mono); font-size: 0.62rem; color: var(--cream); }
.spp-seq-q { border-color: color-mix(in srgb, var(--cool) 55%, transparent); background: color-mix(in srgb, var(--cool) 16%, var(--ink-2)); }
.spp-seq-link, .spp-seq-arrow { color: var(--cream-faint); font-size: 0.7rem; }
.spp-seq-cap { font-size: 0.72rem; color: var(--cream-dim); margin-top: 8px; line-height: 1.45; }
.spp-seq-cap b { color: var(--cream); }
.spp-seq-fan { position: relative; }

/* complexity table + results */
.spp-tbl { width: 100%; border-collapse: collapse; font-size: 0.72rem; }
.spp-tbl th, .spp-tbl td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--paper-edge); font-family: var(--mono); }
.spp-tbl th { color: var(--cream-faint); font-size: 0.62rem; text-transform: uppercase; letter-spacing: .04em; }
.spp-tbl td { color: var(--cream-dim); }
.spp-tbl-hi td { color: var(--cream); background: color-mix(in srgb, var(--cool) 12%, transparent); }
.spp-tbl-hi td:first-child { font-weight: 600; }
.spp-results { display: flex; gap: 10px; margin-top: 14px; }
.spp-result { flex: 1; text-align: center; background: var(--ink-2); border: 1px solid var(--paper-edge); border-radius: 10px; padding: 10px 6px; }
.spp-result b { display: block; font-family: var(--serif); font-size: 1.3rem; color: var(--cool); }
.spp-result span { font-family: var(--mono); font-size: 0.58rem; color: var(--cream-faint); line-height: 1.3; display: block; margin-top: 2px; }
.spp-results-note { font-size: 0.76rem; color: var(--cream-dim); margin-top: 10px; line-height: 1.45; }

/* ═══════════════════════════════════════════════════════════════
   SKILL TREE - the neural constellation (#tree, constellation.js)

   Every colour here is a semantic var, so the tree re-skins with the
   other six themes for free. States are told apart by FORM as much as
   hue (hollow → filled → ringed → rimmed), because in some themes
   --cool and --amber resolve to the same neon.
   ═══════════════════════════════════════════════════════════════ */
/* Secondary text on these surfaces is lifted a little toward the body colour.
   Two of the seven palettes make a raw --cream-dim genuinely hard to read
   against their own paper, and repainting a shared theme to fix one page
   would be the wrong trade; in the palettes that were already fine this is
   close to a no-op. Measured at 4.5:1 or better in all seven. */
.tree, .tree-card, .reward { --tree-dim: color-mix(in srgb, var(--cream-dim) 55%, var(--cream)); }

.tree { max-width: none; margin: 0 auto; padding: 34px clamp(16px, 2.5vw, 40px) 80px; }
.tree .learn-sub { color: var(--tree-dim); }
.tree-head, .tree-badges { max-width: var(--maxw); margin-left: auto; margin-right: auto; }

/* ── header: level ring, the four counts, and what to do next ── */
.tree-head { margin-bottom: 16px; }
.tree-hero { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.tree-hero-txt { flex: 1 1 260px; }
.tree-hero .learn-h { margin-bottom: 4px; }

.tlevel { position: relative; width: 72px; height: 72px; flex: none; }
.tlevel svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.tlevel circle { fill: none; stroke-width: 7; stroke-linecap: round; }
.tlevel-bg { stroke: var(--paper-edge); }
/* 2πr for r=52 = 326.7; --frac is a bare number so calc() can scale it */
.tlevel-fg { stroke: var(--cool); stroke-dasharray: calc(var(--frac) * 326.7) 326.7;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--cool) 55%, transparent)); transition: stroke-dasharray .7s ease; }
.tlevel-num { position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--serif); font-weight: 700; font-size: 1.6rem; color: var(--cream); }

.tstats { display: flex; gap: 22px; flex-wrap: wrap; }
.tstat { display: flex; flex-direction: column; }
.tstat b { font-family: var(--serif); font-size: 1.5rem; font-weight: 700; color: var(--cream); line-height: 1; }
.tstat b i { font-style: normal; font-size: 0.9rem; color: var(--tree-dim); }
.tstat span { font-family: var(--mono); font-size: 0.68rem; letter-spacing: .09em; text-transform: uppercase; color: var(--tree-dim); margin-top: 5px; }

.tree-next { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px;
  background: color-mix(in srgb, var(--cool) 7%, var(--ink-2)); border: 1px solid color-mix(in srgb, var(--cool) 26%, transparent);
  border-radius: 14px; padding: 14px 18px; }
.tn-label { font-family: var(--mono); font-size: 0.6rem; letter-spacing: .14em; text-transform: uppercase; color: var(--cool); }
.tree-next .tn-title { font-family: var(--serif); font-weight: 700; font-size: 1.05rem; color: var(--cream); text-decoration: none; }
.tree-next .tn-title:hover { text-decoration: underline; }
.tn-why { font-size: 0.78rem; color: var(--tree-dim); flex: 1 1 200px; }
.tn-go { margin-left: auto; }
.tn-ico .ic { width: 14px; height: 14px; margin-left: 6px; vertical-align: -2px; }

/* ── the stage ── */
/* a starting height only; constellation.js sizes it to the drawn tree */
.tree-stage { position: relative; height: clamp(460px, 80vh, 1100px); border: 1px solid var(--paper-edge);
  border-radius: 16px; background:
    radial-gradient(ellipse at 50% 45%, color-mix(in srgb, var(--glow-1) 60%, transparent), transparent 62%),
    var(--ink-2);
  /* Only ever sideways, and only on a screen too narrow to hold the board at
     a readable size - constellation.js sizes the svg to the stage otherwise,
     and the height always matches, so the y axis has nothing to scroll. */
  overflow-x: auto; overflow-y: hidden; }
/* sized in px by constellation.js, off the board's own measured extent; the
   auto margins centre it on the stages wider than the board itself */
.tree-stage svg { display: block; margin-inline: auto; }

.tree-legend { position: absolute; left: 14px; bottom: 12px; display: flex; gap: 15px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: .07em; text-transform: uppercase; color: var(--tree-dim); pointer-events: none; }
.tleg { display: inline-flex; align-items: center; gap: 6px;
  pointer-events: auto; cursor: help; }   /* the row itself stays transparent to drags */
.tdot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; box-sizing: border-box; }
.tdot.is-dormant  { background: var(--ink-3); border: 1px solid color-mix(in srgb, var(--cream-faint) 60%, transparent); }
.tdot.is-ready    { background: var(--ink-3); border: 1px dashed var(--cream-dim); }
.tdot.is-read     { background: var(--cool); }
.tdot.is-mastered { background: var(--cool); box-shadow: 0 0 0 2px var(--ink-2), 0 0 0 3px var(--teal); }
.tdot.is-complete { background: var(--teal); border: 1.5px solid var(--cream); }

/* ── edges ── */
.tedge { fill: none; stroke: color-mix(in srgb, var(--cream-faint) 78%, var(--paper-edge));
  stroke-width: 1.4; stroke-linecap: butt; stroke-linejoin: round;
  opacity: .6; transition: opacity .2s ease, stroke .3s ease; }
.tedge.t-trunk { stroke-width: 2.2; }
.tedge.t-branch { stroke-width: 1.8; }
/* the drop between two lessons in a course - the order to take them in */
.tedge.t-synapse { stroke-dasharray: 2 5; opacity: .35; stroke-width: 1.2; }
.tedge.lit { stroke: color-mix(in srgb, var(--cool) 70%, transparent); opacity: .8; }
.tedge.strong { stroke: var(--teal); opacity: .9;
  animation: tflow 3.4s ease-in-out infinite; animation-delay: var(--d, 0s); }
@keyframes tflow { 0%, 100% { opacity: .9; } 50% { opacity: .38; } }
.tedge.faded { opacity: .1; animation: none; }
.tedge.hl { opacity: 1; stroke-width: 2; }

/* ── nodes ── */
.tnode { cursor: pointer; transition: opacity .2s ease; }
.tnode:focus { outline: none; }
.tn-halo { fill: transparent; }                    /* also the generous hit target */
.tn-core { fill: var(--ink-3); stroke: var(--cream-faint); stroke-width: 1.4;
  transition: fill .3s ease, stroke .3s ease, r .3s ease; }
.tn-ring { fill: none; stroke: var(--teal); stroke-width: 1.6; opacity: .85; }
.tn-arc { fill: none; stroke: var(--cool); stroke-width: 2.4; stroke-linecap: round; opacity: .85; }
.tn-label { font-family: var(--read); font-size: 15px; fill: var(--cream);
  dominant-baseline: middle; pointer-events: none; user-select: none; transition: fill .2s ease; }
.tn-count { font-family: var(--mono); font-size: 12px; fill: var(--tree-dim);
  dominant-baseline: middle; pointer-events: none; user-select: none; }

.troot .tn-core { fill: var(--ink-3); stroke: var(--cream-dim); stroke-width: 2; }
.troot.lit .tn-core { fill: color-mix(in srgb, var(--cool) 22%, var(--ink-3)); stroke: var(--cool); }
.troot .tn-label { font-family: var(--mono); font-size: 15px; fill: var(--cream);
  letter-spacing: .16em; text-transform: uppercase; }

.tsubject .tn-label { font-family: var(--mono); font-size: 15px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; fill: var(--cream); }
.tcourse .tn-label { font-size: 15px; font-weight: 600; fill: var(--cream); }
.tsubject.lit .tn-core, .tcourse.lit .tn-core { fill: color-mix(in srgb, var(--cool) 18%, var(--ink-3)); stroke: var(--cool-deep); }
.tsubject.done .tn-core, .tcourse.done .tn-core { fill: var(--teal); stroke: var(--teal); }
.tsubject.soon .tn-core { stroke: var(--cream-faint); }
.tsubject.soon .tn-label { fill: var(--cream-faint); }
.tsubject.soon .tn-core { stroke-dasharray: 3 3; }

/* the five lesson states - hollow → dashed → filled → ringed → rimmed.
   Only the DOT carries state: the name stays at full contrast either way,
   because an unreadable lesson title tells you nothing about anything. */
.tlesson.is-dormant .tn-core { fill: var(--ink-2); stroke: var(--cream-faint); stroke-width: 1.6; }
.tlesson.is-ready .tn-core { stroke: var(--cream-dim); stroke-dasharray: 2.5 2.5; }
.tlesson.is-ready .tn-halo { fill: color-mix(in srgb, var(--cream) 6%, transparent);
  animation: tready 2.8s ease-in-out infinite; }
@keyframes tready { 0%, 100% { opacity: .25; } 50% { opacity: .8; } }
.tlesson.is-read .tn-core { fill: var(--cool); stroke: var(--cool); }
.tlesson.is-mastered .tn-core, .tlesson.is-complete .tn-core { stroke-width: 1.8; }
.tlesson.is-mastered .tn-core { fill: var(--cool); stroke: var(--cool); }
.tlesson.is-complete .tn-core { fill: var(--teal); stroke: var(--cream); }
.tlesson.is-read .tn-core, .tlesson.is-mastered .tn-core, .tlesson.is-complete .tn-core {
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--cool) 65%, transparent)); }
.tlesson.is-complete .tn-core { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--teal) 75%, transparent)); }

/* hover / focus / selection */
.tnode.faded { opacity: .16; }
.tnode.faded .tn-label { opacity: 0; }
.tnode.hl .tn-core, .tnode:focus-visible .tn-core { stroke: var(--cream); stroke-width: 2.2; }
.tnode.hl .tn-label, .tnode:focus-visible .tn-label { fill: var(--cream); font-weight: 500; }
.tnode.sel .tn-core { stroke: var(--cream); stroke-width: 2.6; }
.tnode.sel .tn-halo { fill: color-mix(in srgb, var(--cream) 10%, transparent); }
.tlesson.next .tn-core { stroke: var(--cream); stroke-width: 2.2; }
.tlesson.next .tn-label { fill: var(--cream); font-weight: 600; }

/* ── the glass info card ── */
.tree-scrim { position: fixed; inset: 0; z-index: 78; background: color-mix(in srgb, var(--ink) 18%, transparent); }
.tree-card { position: fixed; z-index: 79; right: 26px; top: 50%; transform: translateY(-50%) translateX(12px);
  width: min(380px, calc(100vw - 40px)); max-height: 82vh; overflow-y: auto; padding: 24px 24px 22px;
  border-radius: 18px; border: 1px solid color-mix(in srgb, var(--cream) 16%, transparent);
  background: color-mix(in srgb, var(--ink-2) 68%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4);
  box-shadow: 0 26px 70px -24px color-mix(in srgb, var(--ink) 90%, transparent);
  opacity: 0; transition: opacity .22s ease, transform .22s ease; }
.tree-card.open { opacity: 1; transform: translateY(-50%) translateX(0); }
.tcard-x { position: absolute; right: 12px; top: 12px; background: none; border: none; color: var(--cream-faint);
  font-size: 0.85rem; cursor: pointer; line-height: 1; padding: 4px; }
.tcard-x:hover { color: var(--cream); }
.tcard-kicker { font-family: var(--mono); font-size: 0.6rem; letter-spacing: .14em; text-transform: uppercase; color: var(--cool); }
.tcard-h { font-family: var(--serif); font-weight: 700; font-size: 1.3rem; line-height: 1.15; margin: 6px 0 8px; padding-right: 20px; }
.tcard-blurb { font-size: 0.85rem; color: var(--tree-dim); line-height: 1.5; }
.tcard-note { font-size: 0.78rem; color: var(--tree-dim); margin-top: 12px; line-height: 1.45; }
.tcard-note a { color: var(--cool); }

.tpips { display: flex; flex-direction: column; gap: 6px; margin: 16px 0 4px; }
.tpip { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 0.72rem;
  color: var(--tree-dim); text-decoration: none; padding: 6px 9px; border-radius: 8px;
  border: 1px solid var(--paper-edge); background: color-mix(in srgb, var(--ink) 30%, transparent); transition: all .16s; }
a.tpip:hover { color: var(--cream); border-color: var(--cool-deep); }
.tpip.on { color: var(--cream); border-color: color-mix(in srgb, var(--cool) 45%, transparent);
  background: color-mix(in srgb, var(--cool) 12%, transparent); }
.tp-ic { display: inline-flex; opacity: .55; }
.tp-ic .ic { width: 13px; height: 13px; }
.tpip.on .tp-ic { opacity: 1; color: var(--cool); }

.tcard-meter { margin-top: 16px; }
.tcm-bar { height: 5px; border-radius: 3px; background: var(--paper-edge); overflow: hidden; }
.tcm-bar i { display: block; height: 100%; border-radius: 3px; background: var(--cool); transition: width .5s ease; }
.tcm-lab { display: block; font-family: var(--mono); font-size: 0.68rem; color: var(--tree-dim); margin-top: 7px; }
.tcard-acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }
.tcard-acts .ld-btn { padding: 9px 14px; font-size: 0.74rem; color: var(--tree-dim); }
.tcard-acts .ld-btn:hover { color: var(--cream); }
.tcard-acts .ld-primary { color: var(--on-accent); }

/* ── the pointer from the Learn directory into the tree ── */
.tree-strip { display: flex; align-items: center; gap: 14px; margin-top: 20px; padding: 14px 18px;
  text-decoration: none; border-radius: 14px; border: 1px solid var(--paper-edge);
  background: color-mix(in srgb, var(--cool) 6%, var(--ink-2)); transition: all .18s; }
.tree-strip:hover { border-color: color-mix(in srgb, var(--cool) 48%, transparent); transform: translateY(-1px); }
.ts-orb { width: 30px; height: 30px; flex: none; border-radius: 50%;
  background: radial-gradient(circle at 35% 32%, var(--cool), color-mix(in srgb, var(--teal) 70%, transparent) 68%, transparent 72%);
  box-shadow: 0 0 14px color-mix(in srgb, var(--cool) 45%, transparent); }
.ts-txt { display: flex; flex-direction: column; gap: 2px; }
.ts-txt b { font-family: var(--serif); font-size: 0.98rem; color: var(--cream); }
.ts-txt span { font-family: var(--mono); font-size: 0.66rem; color: var(--cream-dim); }
.ts-go { margin-left: auto; font-family: var(--mono); font-size: 0.68rem; color: var(--cool); white-space: nowrap; }
.ts-go .lc-chev { margin-left: 4px; vertical-align: -1px; }

/* ── narrow screens: the card becomes a sheet, the stage gets shorter ── */
@media (max-width: 720px) {
  .tree { padding: 24px 16px 70px; }
  .tree-stage { height: 66vh; }
  .tree-hero { gap: 14px; }
  .tlevel { width: 62px; height: 62px; }
  .tlevel-num { font-size: 1.4rem; }
  .tree-hero .learn-h { font-size: 1.7rem; }
  .tstat b { font-size: 1.15rem; }
  .tree-next { margin-top: 14px; padding: 12px 14px; gap: 8px; }
  .tree-next .tn-title { font-size: 0.95rem; }
  .tree-legend { font-size: 0.52rem; gap: 9px; left: 10px; }
  .tstats { gap: 16px; }
  .tn-go { margin-left: 0; }
  .tree-card { right: 0; left: 0; top: auto; bottom: 0; width: 100%; max-height: 76vh;
    border-radius: 18px 18px 0 0; transform: translateY(18px); }
  .tree-card.open { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .tedge.strong, .tlesson.is-ready .tn-halo { animation: none; }
  .tree-card, .tcm-bar i, .tlevel-fg { transition: none; }
}

/* ── The reward moment (quiz results / lesson done / exercise pass) ──────
   Same neuron vocabulary as the tree, so the dot you see here is literally
   the one that just changed on #tree. */
.reward { margin: 20px 0; padding: 16px 18px; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--cool) 28%, transparent);
  background: color-mix(in srgb, var(--cool) 7%, var(--ink-2)); }
.reward.levelled { border-color: color-mix(in srgb, var(--teal) 55%, transparent);
  background: color-mix(in srgb, var(--teal) 10%, var(--ink-2)); }
.rw-main { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.rw-neuron { width: 20px; height: 20px; flex: none; border-radius: 50%; box-sizing: border-box;
  background: var(--ink-3); border: 1.5px solid var(--cream-faint); }
.rw-neuron.is-ready { border-style: dashed; border-color: var(--cream-dim); }
.rw-neuron.is-read { background: var(--cool); border-color: var(--cool);
  box-shadow: 0 0 12px color-mix(in srgb, var(--cool) 65%, transparent); }
.rw-neuron.is-mastered { background: var(--cool); border-color: var(--cool);
  box-shadow: 0 0 0 3px var(--ink-2), 0 0 0 4.5px var(--teal), 0 0 14px color-mix(in srgb, var(--cool) 60%, transparent); }
.rw-neuron.is-complete { background: var(--teal); border-color: var(--cream);
  box-shadow: 0 0 16px color-mix(in srgb, var(--teal) 75%, transparent); }
.rw-txt { display: flex; flex-direction: column; gap: 2px; flex: 1 1 220px; }
.rw-head { font-family: var(--serif); font-size: 1.02rem; color: var(--cream); }
.rw-sub { font-size: 0.8rem; color: var(--tree-dim); }
.rw-right { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; margin-left: auto; }
.rw-xp { font-family: var(--serif); font-weight: 700; font-size: 1.25rem; color: var(--tree-dim); line-height: 1; }
.rw-xp.up { color: var(--cool); }
.rw-level { font-family: var(--mono); font-size: 0.68rem; color: var(--tree-dim); }
.rw-level.up { color: var(--teal); font-weight: 600; letter-spacing: .04em; }

.rw-badges { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px;
  padding-top: 14px; border-top: 1px solid color-mix(in srgb, var(--cream) 10%, transparent); }
.rw-badge { display: inline-flex; align-items: center; gap: 9px; padding: 8px 12px; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--teal) 45%, transparent);
  background: color-mix(in srgb, var(--teal) 14%, transparent); }
.rw-bico { width: 20px; height: 20px; color: var(--teal); display: inline-flex; }
.rw-bico svg { width: 100%; height: 100%; }
.rw-btxt { display: flex; flex-direction: column; }
.rw-btxt b { font-size: 0.82rem; color: var(--cream); }
.rw-btxt span { font-family: var(--mono); font-size: 0.62rem; letter-spacing: .1em; text-transform: uppercase; color: var(--tree-dim); }
.rw-link { display: inline-block; margin-top: 12px; font-family: var(--mono); font-size: 0.68rem; color: var(--cool); text-decoration: none; }
.rw-link:hover { text-decoration: underline; }

/* ── Badge shelf on #tree ── */
.tree-badges { margin-top: 26px; }
.tb-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.tb-h { font-family: var(--serif); font-weight: 700; font-size: 1.2rem; }
.tb-count { font-family: var(--mono); font-size: 0.7rem; color: var(--tree-dim); }
.tb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.tbadge { display: flex; align-items: center; gap: 11px; padding: 12px 14px; border-radius: 12px;
  border: 1px solid var(--paper-edge); background: var(--ink-2); transition: all .2s; }
.tbadge.on { opacity: 1; border-color: color-mix(in srgb, var(--teal) 42%, transparent);
  background: color-mix(in srgb, var(--teal) 9%, var(--ink-2)); }
.tb-ico { width: 22px; height: 22px; flex: none; color: var(--cream-faint); display: inline-flex; }
.tbadge.on .tb-ico { color: var(--teal); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--teal) 55%, transparent)); }
.tb-ico svg { width: 100%; height: 100%; }
.tb-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tb-txt b { font-size: 0.86rem; color: var(--cream); }
.tb-txt span { font-size: 0.72rem; color: var(--tree-dim); line-height: 1.35; }

@media (max-width: 720px) {
  .rw-right { align-items: flex-start; margin-left: 0; }
  .tb-grid { grid-template-columns: 1fr; }
}

/* ── The reader's own status, carried onto the landing and the navbar ────
   Same numbers the tree draws, built from the same model. Both hide
   themselves when nothing has been earned: a level 1 / 0 XP chip is noise. */
.hero-status { margin-top: 22px; max-width: 660px; margin-left: auto; margin-right: auto; }
.hs-main { display: flex; align-items: center; gap: 14px; padding: 12px 16px; text-decoration: none;
  border-radius: 14px; border: 1px solid color-mix(in srgb, var(--cool) 30%, transparent);
  background: color-mix(in srgb, var(--cool) 8%, color-mix(in srgb, var(--ink) 72%, transparent));
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); transition: all .18s; }
.hs-main:hover { border-color: color-mix(in srgb, var(--cool) 55%, transparent); transform: translateY(-1px); }
.hs-ring { position: relative; width: 42px; height: 42px; flex: none; }
.hs-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.hs-ring circle { fill: none; stroke-width: 9; stroke-linecap: round; }
.hs-ring b { position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--serif); font-weight: 700; font-size: 0.95rem; color: var(--cream); }
.hs-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hs-txt b { font-family: var(--serif); font-size: 0.95rem; color: var(--cream); line-height: 1.2; }
.hs-txt span { font-family: var(--mono); font-size: 0.68rem; color: var(--tree-dim, var(--cream-dim)); }
.hs-go { margin-left: auto; font-family: var(--mono); font-size: 0.7rem; color: var(--cool); white-space: nowrap; }

/* --tree-dim only exists on the tree surfaces; give the strip its own */
.hero-status { --tree-dim: color-mix(in srgb, var(--cream-dim) 55%, var(--cream)); }

@media (max-width: 720px) {
  .hero-status { max-width: none; }
  .hs-go { display: none; }
}

/* ── Share on LinkedIn ─────────────────────────────────────────────────── */
.tshare, .hs-share { display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--mono); font-size: 0.72rem; color: var(--cream);
  background: color-mix(in srgb, var(--cool) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--cool) 38%, transparent);
  border-radius: 100px; padding: 9px 16px; transition: all .16s; white-space: nowrap; }
.tshare:hover, .hs-share:hover { background: color-mix(in srgb, var(--cool) 22%, transparent);
  border-color: var(--cool); transform: translateY(-1px); }
.tshare:disabled, .hs-share:disabled { opacity: .6; cursor: default; transform: none; }
.li-ico { width: 15px; height: 15px; flex: none; color: var(--cool); }
.tshare { margin-left: 18px; }
.hero-status { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.hero-status .hs-main { flex: 1 1 340px; }
@media (max-width: 720px) {
  .tshare { margin-left: 0; margin-top: 12px; }
  .hero-status .hs-share { width: 100%; justify-content: center; }
}

/* ── "not saved yet" — shown until the reader signs in ─────────────────── */
.tree-unsaved { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; margin-top: 14px;
  padding: 13px 17px; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--rose) 46%, transparent);
  background: color-mix(in srgb, var(--rose) 10%, var(--ink-2)); }
.tu-ic { display: inline-flex; color: var(--rose); flex: none; }
.tu-ic .ic { width: 19px; height: 19px; }
.tu-txt { display: flex; flex-direction: column; gap: 2px; flex: 1 1 300px; }
.tu-txt b { font-family: var(--serif); font-size: 0.98rem; color: var(--cream); }
.tu-txt span { font-size: 0.8rem; color: var(--tree-dim, var(--cream-dim)); line-height: 1.45; }
.tu-btn { margin-left: auto; cursor: pointer; white-space: nowrap;
  font-family: var(--mono); font-size: 0.74rem; font-weight: 600;
  color: var(--on-accent); background: var(--cream); border: 1px solid var(--cream);
  border-radius: 100px; padding: 10px 18px; transition: opacity .16s; }
.tu-btn:hover { opacity: .88; }
.rw-keep { display: inline-block; margin-top: 12px; font-family: var(--mono); font-size: 0.72rem;
  font-weight: 600; color: var(--rose); text-decoration: none; }
.rw-keep:hover { text-decoration: underline; }
@media (max-width: 720px) { .tu-btn { margin-left: 0; width: 100%; } }

/* ── Sharing: one sheet, and the bubble that points at it ───────────────
   Every share surface on the site opens .sh-modal, so a new destination is
   added in share.js and turns up everywhere at once. */
.sh-modal { position: fixed; inset: 0; z-index: 300; display: flex; align-items: center; justify-content: center; padding: 20px; }
.sh-modal[hidden] { display: none; }
.sh-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 78%, transparent); backdrop-filter: blur(4px); }
.sh-card {
  position: relative; width: min(520px, 100%); max-height: 92vh; overflow-y: auto;
  background: linear-gradient(170deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--paper-edge); border-radius: 18px; padding: 26px 24px 22px;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.6);
}
.sh-x { position: absolute; right: 14px; top: 12px; background: none; border: none; color: var(--cream-faint); font-size: 0.95rem; cursor: pointer; line-height: 1; padding: 4px; }
.sh-x:hover { color: var(--cream); }
.sh-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 16px; padding-right: 26px; }
.sh-title { font-family: var(--serif); font-size: 1.22rem; color: var(--cream); }
.sh-sub { font-family: var(--mono); font-size: 0.7rem; color: var(--cream-dim); }
.sh-card-img { width: 100%; height: auto; border-radius: 12px; border: 1px solid var(--paper-edge); display: block; }
.sh-targets { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin: 16px 0 4px; }
.sh-loading { grid-column: 1 / -1; font-family: var(--mono); font-size: 0.72rem; color: var(--cream-dim); padding: 14px 2px; }
.sh-t {
  display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer;
  background: color-mix(in srgb, var(--cool) 8%, transparent);
  border: 1px solid var(--paper-edge); border-radius: 11px; padding: 10px 12px;
  transition: border-color .18s, background .18s;
}
.sh-t:hover { border-color: var(--cool-deep); background: color-mix(in srgb, var(--cool) 15%, transparent); }
.sh-t-ico { display: inline-flex; flex: none; color: var(--cool); }
.sh-t-ico svg { width: 18px; height: 18px; }
.sh-t-txt { display: flex; flex-direction: column; min-width: 0; }
.sh-t-txt b { font-family: var(--mono); font-size: 0.73rem; color: var(--cream); font-weight: 500; }
.sh-t-txt span { font-family: var(--mono); font-size: 0.6rem; color: var(--cream-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sh-badge { margin-top: 16px; padding-top: 15px; border-top: 1px solid var(--paper-edge); }
.sh-badge[hidden] { display: none; }
.sh-badge-head { display: flex; align-items: center; gap: 8px; margin-bottom: 11px; }
.sh-badge-head svg { width: 15px; height: 15px; color: var(--cream-dim); }
.sh-badge-head b { font-family: var(--mono); font-size: 0.7rem; color: var(--cream); font-weight: 500; }
.sh-badge-img { display: block; height: 20px; width: auto; margin-bottom: 11px; }
.sh-snip { display: flex; align-items: stretch; gap: 8px; }
.sh-code {
  flex: 1; min-width: 0; font-family: var(--mono); font-size: 0.6rem; color: var(--cream-dim);
  background: var(--ink); border: 1px solid var(--paper-edge); border-radius: 8px;
  padding: 8px 10px; overflow-x: auto; white-space: nowrap;
}
.sh-copy {
  flex: none; font-family: var(--mono); font-size: 0.66rem; color: var(--on-accent);
  background: var(--cream); border: 1px solid var(--cream); border-radius: 8px;
  padding: 0 14px; cursor: pointer; transition: opacity .18s;
}
.sh-copy:hover { opacity: .88; }

/* the bubble - anchored to whichever share button raised it */
/* top/right are set in share.js from the button it points at - see nudge() */
.sh-nudge {
  position: absolute; z-index: 80;
  width: min(280px, 78vw); display: flex; flex-direction: column; gap: 5px;
  background: linear-gradient(170deg, var(--ink-3), var(--ink-2));
  border: 1px solid color-mix(in srgb, var(--cool) 45%, transparent); border-radius: 13px;
  padding: 13px 14px 12px; box-shadow: 0 18px 44px -14px rgba(0,0,0,.55);
  opacity: 0; transform: translateY(-6px); transition: opacity .24s ease, transform .24s ease;
}
.sh-nudge.in { opacity: 1; transform: none; }
/* the little arrow up at the button it belongs to */
.sh-nudge::before {
  content: ""; position: absolute; top: -5px; right: 22px; width: 9px; height: 9px;
  background: var(--ink-3); border-left: 1px solid color-mix(in srgb, var(--cool) 45%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--cool) 45%, transparent); transform: rotate(45deg);
}
.sh-nudge b { font-family: var(--serif); font-size: 0.86rem; color: var(--cream); padding-right: 16px; }
.sh-nudge > span { font-family: var(--mono); font-size: 0.63rem; line-height: 1.5; color: var(--cream-dim); }
.sh-n-x { position: absolute; right: 9px; top: 8px; background: none; border: none; color: var(--cream-faint); font-size: 0.7rem; cursor: pointer; padding: 3px; line-height: 1; }
.sh-n-x:hover { color: var(--cream); }
.sh-n-go {
  align-self: flex-start; margin-top: 6px; font-family: var(--mono); font-size: 0.66rem;
  color: var(--on-accent); background: var(--cream); border: 1px solid var(--cream);
  border-radius: 100px; padding: 6px 13px; cursor: pointer; transition: opacity .18s;
}
.sh-n-go:hover { opacity: .88; }

/* a share button has to be a positioning context for its own bubble */
.tshare, .hs-share, .rw-share { position: relative; }
/* the reward moment's own row: back to the tree on the left, share on the right */
.rw-acts { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.rw-acts .rw-link { margin-top: 0; }
.rw-share {
  margin-left: auto; display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font-family: var(--mono); font-size: 0.66rem; color: var(--cream);
  background: color-mix(in srgb, var(--cool) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--cool) 42%, transparent);
  border-radius: 100px; padding: 6px 13px; transition: background .18s, border-color .18s;
}
.rw-share:hover { background: color-mix(in srgb, var(--cool) 24%, transparent); border-color: var(--cool); }
.rw-share svg { width: 13px; height: 13px; }
@media (max-width: 620px) { .rw-share { margin-left: 0; } }

@media (max-width: 620px) {
  .sh-targets { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .sh-nudge { transition: none; }
}

/* ── GitHub sign-in button in the auth modal ──────────────────────────────
   Google renders its own button and we cannot restyle it, so this one is cut
   to the measurements of theirs instead: filled_black at size large is 40px
   tall, 4px of radius, #202124 on #e8eaed, 14px at weight 400, no border. The
   one thing that cannot follow is the face - Google Sans is theirs - so this
   takes the site's own sans at the same size rather than the mono the form
   fields use, which was the loudest half of the mismatch. */
.auth-gh {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--read); font-size: 14px; font-weight: 400; text-decoration: none;
  color: #e8eaed; background: #202124;
  border: 0; border-radius: 4px;
  height: 40px; padding: 0 12px; box-sizing: border-box;
  margin-bottom: 10px; transition: background .18s;
}
/*  Mark and label travel together as one centred group. The 8px is Google's
    own gap, measured off their outline button, so the two pairs sit at the
    same width. */
.auth-gh svg { flex: none; width: 18px; height: 18px; }
.auth-gh:hover { background: #2c2d31; }
/*  Google's dark button parks its G on a white 36px tile, which on a dark
    card reads as a sticker stuck to the button. Blanking it puts the mark
    straight on the dark, which is how their own modern dark treatment draws
    it - and how ours has always drawn the Octocat. The selector leans on
    Google's hashed class: if they rename it the tile comes back, which is a
    cosmetic regression and nothing worse. */
.theme-neurons  #authGoogleBtn [class*="Bz112c-haAclf"],
.theme-technical #authGoogleBtn [class*="Bz112c-haAclf"],
.theme-midnight #authGoogleBtn [class*="Bz112c-haAclf"] {
  background: transparent;
  /*  The tile is 36px around an 18px mark: 9px of air a side, plus a 12px
      margin, which is the 21px it sat away from its label. That air was the
      sticker's, and the sticker is gone - so the box shrinks to the mark and
      takes the 8px Google itself uses on the outline button, where there is no
      tile at all. Both themes then space the pair identically. */
  width: 18px; min-width: 18px; padding: 0;
  /*  their own -10px margin hung the tile off the row's left inset, back when
      it lived at the edge; centred in a group it just drags the pair 5px off */
  margin-left: 0; margin-right: 8px;
}

/*  ...and the same idea for the layout: their label is a flex:1 item, so it
    takes the whole row and leaves the mark stranded out at the edge. Letting
    the label shrink to its text and centring the row puts the two together in
    the middle, which is where ours sits. Both selectors are Google's own
    hashed classes - a rename means their button goes back to its own default
    layout, and nothing worse. */
#authGoogleBtn [class*="bN97Pc-sM5MNb"] { justify-content: center; }
#authGoogleBtn [class*="LgbsSe-BPrWId"] { flex: 0 1 auto; }

/*  The four light themes take the light half of the pair: Google renders its
    outline button there, and this follows its values rather than ours - white,
    #1f1f1f type, and the hairline they draw instead of a border. */
.theme-editorial .auth-gh, .theme-archival .auth-gh, .theme-softclub .auth-gh {
  color: #1f1f1f; background: #fff; box-shadow: inset 0 0 0 1px #dadce0;
}
.theme-editorial .auth-gh:hover, .theme-archival .auth-gh:hover, .theme-softclub .auth-gh:hover {
  background: #f7f8f8;
}
.auth-gh[hidden] { display: none; }
.auth-alt[hidden] { display: none; }

/* ── Views and likes on the Learn covers ────────────────────────────────
   The two numbers sit at the end of the line a card already had - the
   subject pane's "3 courses · 12 lessons", the course card's "5 lessons",
   the lesson card's "Foundations · 1958" - rather than adding a row. That
   line is already the card's quiet metadata, which is what these are. */
/*  The eye and the heart are one pair, drawn in the same ink at the same
    weight so neither reads as the louder half - but the heart is the like
    button, not a picture of one, so the pair is sized to be hit as well as
    read. */
.ct-stats { display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: .03em; }
.ct-stat { display: inline-flex; align-items: center; gap: 5px; }
.ct-stat svg { width: 13px; height: 13px; }
.ct-stat b { font-weight: 400; font-variant-numeric: tabular-nums; }

/*  The like. Its own button, not .fav-btn - the favourite is a bookmark and
    lives on the cover; this is the public one, and the count is beside it. */
.ct-heart {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; background: none; border: none; cursor: pointer; color: inherit;
  transition: color .15s, transform .15s;
}
.ct-heart svg { width: 13px; height: 13px; }
.ct-heart:hover { color: #ff5d70; transform: scale(1.18); }
.ct-heart.on { color: #ff5d70; }
.ct-heart.on svg { fill: currentColor; stroke: currentColor; }
/* the number goes with it, so a card you have liked reads as liked at a glance */
.ct-likes:has(.ct-heart.on) b { color: #ff5d70; }

/*  The favourite, back on the lesson cover where it was - and on a disc,
    because a bare mark on artwork is invisible against half the images in
    the set. Bookmark, not heart: see HEART_ICON in app.js. */
.lc-fav {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 27px; height: 27px; padding: 0; border-radius: 50%;
  background: rgba(9, 12, 20, .58);
  -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
  border: 1px solid rgba(255, 255, 255, .14);
  color: rgba(255, 255, 255, .85);
}
.lc-fav:hover { background: rgba(9, 12, 20, .74); color: #fff; }
.lc-fav.on { color: var(--cool); border-color: color-mix(in srgb, var(--cool) 55%, transparent); }
.lc-fav.on svg { fill: currentColor; }

/*  On the course and lesson cards the pair sits on the kicker line above the
    title - "5 lessons", "Foundations · 1958" - pushed to the far end of it,
    and only while the card is under the cursor. That line is the card's own
    metadata and it never wraps, so the counts land at the same height on
    every card in the grid however long its title runs.
    pointer-events go with the opacity: an invisible heart that can still be
    clicked is a trap. :focus-within is what keeps it reachable by keyboard -
    tabbing to the heart brings the row up. */
.cc-meta, .lc-tag { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/*  On the course and lesson cards the pair sits in the bottom-right corner and
    stays there. Those grids are a list you scan, and a number you have to
    hover to read is no use for comparing one card against another. */
.card-stats { position: absolute; right: 14px; bottom: 12px; z-index: 3; color: var(--cream-dim); }

/*  Inside a lesson: the same pair, in the top-right corner, level with the
    "back to ..." link that starts the page. Always there - by this point the
    reader is in the thing the numbers are about. */
.learn-view { position: relative; }
.lesson-stats { position: absolute; right: 0; top: 2px; z-index: 3; color: var(--cream-dim); }
@media (max-width: 620px) {
  .lesson-stats { position: static; display: block; margin: -6px 0 14px; }
}

/*  The five subject panes are the exception. They are covers, not a list, and
    that grid is meant to read as five pictures until you point at one - so the
    pair goes above the name and comes up with the rest of the copy.
    pointer-events go with the opacity: an invisible heart that can still be
    clicked is a trap, and the heart is the like button. :focus-within keeps it
    reachable without a mouse. */
.sp-stats { display: block; margin-bottom: 3px; color: rgba(255,255,255,.85);
  opacity: 0; pointer-events: none; transition: opacity .3s ease .04s; }
.subject-pane:hover .sp-stats, .subject-pane:focus-within .sp-stats,
.subject-pane:focus-visible .sp-stats { opacity: 1; pointer-events: auto; }
/*  A phone has no cursor, so hiding them there would hide the like button
    for good. */
@media (hover: none) {
  .sp-stats { opacity: 1; pointer-events: auto; }
}





@media (max-width: 520px) {
  .ct-stats { gap: 8px; margin-left: 8px; }
}
