/* ===========================================================================
   QubitLogic - derived from the mockup.

   Palette: deep navy field, with the blue→violet→magenta ramp used the way the
   mockup uses it - as a state transition, not as decoration. Gradient is spent
   on exactly three things: the word "decoded", the primary button, and the
   section rules. Everything else stays quiet so the hero carries the page.
   =========================================================================== */

:root {
  --bg:            #05070f;
  --bg-2:          #070b18;
  --panel:         #0b1020;
  --panel-2:       #0e142a;
  --line:          #1b2547;
  --line-bright:   #2a3766;

  --ink:           #eef1fb;
  --ink-2:         #b8c2e0;
  --ink-dim:       #7f8cb4;

  --blue:          #38bdf8;
  --indigo:        #6366f1;
  --violet:        #a855f7;
  --magenta:       #ec4899;

  --ramp: linear-gradient(100deg, var(--blue) 0%, var(--indigo) 45%, var(--violet) 75%, var(--magenta) 100%);

  --major:         #fb7185;
  --interesting:   #c084fc;
  --research:      #38bdf8;

  --hype-low:      #34d399;
  --hype-medium:   #fbbf24;
  --hype-high:     #fb7185;

  --r:             14px;
  --r-sm:          9px;
  --measure:       68ch;
  --shell:         1320px;

  --font: "Segoe UI Variable Display", "Segoe UI", Inter, ui-sans-serif, system-ui, sans-serif;
  --mono: "Cascadia Code", "JetBrains Mono", ui-monospace, Consolas, monospace;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible { outline: 2px solid var(--violet); outline-offset: 3px; border-radius: 4px; }

.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: 1rem; top: 1rem; z-index: 100;
  background: var(--panel-2); padding: .6rem 1rem; border-radius: var(--r-sm);
}

.shell { max-width: var(--shell); margin: 0 auto; padding: 0 clamp(1rem, 3vw, 2.5rem); }

/* --- Masthead ----------------------------------------------------------- */

.masthead {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.masthead .shell {
  display: flex; align-items: center; gap: 2.5rem;
  height: 66px;
}

.brand {
  display: flex; align-items: center; gap: .6rem;
  font-size: 1.42rem; font-weight: 800; letter-spacing: -.035em;
  color: #fff; text-decoration: none; flex: 0 0 auto;
}
.brand:hover { text-decoration: none; }
.brand .mark {
  /* viewBox is 48x44, so height follows width rather than forcing a square. */
  width: 38px; height: 35px; flex: 0 0 auto;
  filter: drop-shadow(0 0 9px color-mix(in srgb, var(--violet) 50%, transparent));
}
.brand .word { display: inline; }
/* Same ramp as the "decoded." headline, so the wordmark and the hero agree. */
.brand em {
  font-style: normal;
  background: var(--ramp);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}

.masthead nav { display: flex; gap: 1.6rem; margin-left: auto; flex-wrap: wrap; }
.masthead nav a {
  color: var(--ink-2); font-size: .93rem; font-weight: 500;
  text-decoration: none; position: relative; padding: .2rem 0;
}
.masthead nav a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: -2px; height: 2px;
  background: var(--ramp); transition: right .25s ease;
}
.masthead nav a:hover { color: var(--ink); text-decoration: none; }
.masthead nav a:hover::after { right: 0; }

/* --- Hero --------------------------------------------------------------- */

.hero {
  position: relative; isolation: isolate;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  background:
    radial-gradient(1100px 520px at 68% 48%, color-mix(in srgb, var(--indigo) 22%, transparent), transparent 70%),
    radial-gradient(700px 400px at 88% 20%, color-mix(in srgb, var(--magenta) 14%, transparent), transparent 70%),
    var(--bg);
}
.hero .shell {
  display: grid;
  grid-template-columns: minmax(0, 47fr) minmax(0, 53fr);
  align-items: center;
  gap: 1.5rem;
  min-height: min(500px, 66vh);
  padding-top: 2.2rem; padding-bottom: 2.2rem;
}

.hero h1 {
  font-size: clamp(2.3rem, 4.4vw, 3.5rem);
  line-height: 1.03;
  letter-spacing: -.04em;
  font-weight: 800;
  margin: 0 0 1.1rem;
}
.hero h1 .grad {
  background: var(--ramp);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  display: inline-block;
}
.hero p {
  color: var(--ink-2); font-size: .98rem; max-width: 42ch; margin: 0 0 1.6rem;
}

.cta-row { display: flex; gap: .9rem; flex-wrap: wrap; }

.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  padding: .86rem 1.6rem; border-radius: 999px;
  font-weight: 600; font-size: .97rem; text-decoration: none; line-height: 1;
  border: 1px solid transparent; cursor: pointer; isolation: isolate;
  transition: transform .18s ease, filter .18s ease;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }

.btn-primary {
  background: var(--ramp);
  /* THE actual cause of the "cut off" caps.
     background-origin defaults to padding-box, so the gradient is SIZED to the
     padding box, while background-clip defaults to border-box, so it is PAINTED
     across the wider border box. With the 1px transparent border on .btn, the
     tile ends up 2px narrower than the area it fills, so it repeats - putting
     the ramp's magenta end on the left cap and its cyan start on the right cap.
     Sizing the gradient to the border box removes the gap and the repeat. */
  background-origin: border-box;
  background-repeat: no-repeat;
  color: #fff;
  /* No rim, deliberately.
     A light rim was tried twice and failed both times: the ramp runs light at
     BOTH ends, so white vanished over the magenta cap at 38% and over the cyan
     cap at 62%. There is no opacity that works at both. The reference button
     has no outline either - the bright fill against the dark hero is already a
     crisp edge, provided the glow stays away from it. */
}
/* Glow sits low and well inside the horizontal extents, so it reads as light
   cast on the page and never touches the rounded caps. */
.btn-primary::after {
  content: ""; position: absolute; inset: 48% 12% -34%; z-index: -1;
  border-radius: inherit;
  background: var(--ramp);
  filter: blur(15px); opacity: .4;
  transition: opacity .18s ease;
}
.btn-primary:hover::after { opacity: .6; }

.btn-ghost { border-color: var(--line-bright); color: var(--ink); background: transparent; }
.btn-ghost:hover { border-color: var(--blue); }

/* Hero canvas + the floating readouts pinned over it. */
.hero > canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
  /* Vignette rather than a hard stop. Fades hardest on the left so the
     headline sits on clean background, and feathers every outer edge so the
     field has no visible boundary. */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0%, rgba(0,0,0,.35) 16%, #000 42%, #000 88%, transparent 100%),
    linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent 0%, rgba(0,0,0,.35) 16%, #000 42%, #000 88%, transparent 100%),
    linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  mask-composite: intersect;
}

.hero .shell { position: relative; z-index: 1; }

/* Now only a positioning frame for the floating readouts. */
.hero-visual { position: relative; min-height: 400px; pointer-events: none; }

.readout {
  position: absolute; z-index: 2;
  background: color-mix(in srgb, var(--panel-2) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue) 40%, var(--line-bright));
  border-radius: var(--r-sm);
  padding: .65rem .95rem;
  backdrop-filter: blur(10px);
  font-family: var(--mono);
  box-shadow: 0 0 30px -10px color-mix(in srgb, var(--indigo) 70%, transparent);
}
.readout .k {
  display: block; font-size: .58rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-dim); margin-bottom: .25rem;
}
.readout .v { font-size: 1.05rem; color: var(--ink); font-weight: 600; }
.readout-state { top: 8%; right: 2%; }
.readout-coherence { bottom: 10%; right: 8%; }

/* --- Section furniture -------------------------------------------------- */

section.band { padding: 2.5rem 0; }
section.band + section.band { padding-top: 0; }

.section-head { display: flex; align-items: center; gap: .8rem; margin-bottom: 1.1rem; }
.section-head::before {
  content: ""; width: 26px; height: 3px; border-radius: 2px;
  background: var(--ramp); flex: 0 0 auto;
}
.section-head h2 {
  font-size: 1.18rem; font-weight: 700; letter-spacing: -.02em; margin: 0;
}
.section-head .more { margin-left: auto; font-size: .88rem; color: var(--ink-dim); }
.section-head .more:hover { color: var(--blue); }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

/* --- Learn cards -------------------------------------------------------- */

.learn-grid {
  display: grid; gap: .85rem;
  grid-template-columns: repeat(auto-fit, minmax(252px, 1fr));
}

.learn-card {
  position: relative; overflow: hidden;
  /* Transparent: the ::after pseudo-element carries the panel fill, leaving a
     1px ring for the beam underneath to shine through. */
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: .95rem 1.05rem;
  text-decoration: none; color: inherit;
  display: block;
  /* Landscape, like the reference. The art is the card; the title sits on it. */
  min-height: 178px;
  transition: border-color .2s ease, transform .2s ease, background .2s ease, box-shadow .2s ease;
}
.learn-card:hover {
  text-decoration: none;
  border-color: transparent;
  transform: translateY(-3px);
  box-shadow: 0 16px 44px -20px color-mix(in srgb, var(--indigo) 90%, transparent);
}
.learn-card:hover::after { background: var(--panel-2); }

/* --- Hover: a light running the border ---------------------------------- */
/* A conic gradient rotating behind the card, with the interior masked out by
   ::after so only a hairline ring shows. Rotating the element itself rather
   than animating a custom property keeps this working in browsers without
   @property support, and it stays on the compositor. */
.learn-card::before {
  content: "";
  position: absolute; left: 50%; top: 50%;
  width: 190%; aspect-ratio: 1; z-index: 0;
  translate: -50% -50%;
  background: conic-gradient(
    transparent 0deg 250deg,
    color-mix(in srgb, var(--blue) 70%, transparent) 296deg,
    #ffffff 316deg,
    color-mix(in srgb, var(--violet) 80%, transparent) 332deg,
    transparent 360deg);
  opacity: 0;
  transition: opacity .28s ease;
}
.learn-card::after {
  content: "";
  position: absolute; inset: 1px; z-index: 0;
  border-radius: calc(var(--r) - 1px);
  background: var(--panel);
  transition: background .2s ease;
}
.learn-card:hover::before {
  opacity: 1;
  animation: cardBeam 2.6s linear infinite;
}
@keyframes cardBeam {
  to { rotate: 360deg; }
}

/* The number badge lights up with it. */
.learn-card:hover .idx { color: #a5f3fc; text-shadow: 0 0 12px color-mix(in srgb, var(--blue) 70%, transparent); }

/* The 01/02/03 markers earn their place: the Learn track is a real sequence and
   the order tells you what to read first. */
.learn-card .idx {
  position: relative; z-index: 2; display: block;
  font-family: var(--mono); font-size: .72rem; color: var(--blue);
  letter-spacing: .12em;
}
.learn-card h3 {
  position: relative; z-index: 2;
  margin: .3rem 0 0; font-size: .93rem; font-weight: 650;
  letter-spacing: -.02em; line-height: 1.3;
  /* Wider and slightly tighter so two-word titles hold one line. Long ones
     ("Quantum computer vs. regular computer") still wrap, which is correct. */
  max-width: 78%;
}
/* Artwork fills the card and sits behind the title, which is why every thumb
   shares a 320x170 viewBox with its content biased right of centre. */
.learn-card .thumb {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; margin: 0;
  /* The artwork is centred in its own frame, because that is what the Learn rail
     needs and what a thumbnail should be by default. This card is the one place
     that wants it off-centre, since the title sits on top of the art at the
     upper left - so the bias is asked for here rather than baked into every
     drawing. Previously two of the drawings carried their own rightward bias for
     this card's benefit, which left them visibly off-centre everywhere else. */
  transform: translateX(9%);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--indigo) 38%, transparent));
  transition: filter .3s ease, transform .4s ease;
}
.learn-card:hover .thumb {
  filter: drop-shadow(0 0 16px color-mix(in srgb, var(--blue) 55%, transparent)) brightness(1.14);
  /* Both parts restated: a bare scale() here would drop the translate above. */
  transform: translateX(9%) scale(1.035);
}
/* --- Learn index: course path ------------------------------------------- */

.learn-intro { padding-bottom: .5rem; }
.learn-intro .lede { max-width: 56ch; }

/* The rail runs the whole path; nodes sit on it. */
.path { position: relative; padding: .5rem 0 2rem 0; }
.path::before {
  content: ""; position: absolute; left: 21px; top: 0; bottom: 2.6rem; width: 1px;
  background: linear-gradient(180deg,
    transparent,
    color-mix(in srgb, var(--blue) 45%, transparent) 8%,
    color-mix(in srgb, var(--violet) 40%, transparent) 60%,
    transparent);
}

.path-stage {
  position: relative; display: flex; align-items: baseline; gap: .75rem;
  padding: 1.6rem 0 .9rem 58px;
}
.path-stage:first-child { padding-top: .4rem; }
.path-stage-dot {
  position: absolute; left: 15px; top: 50%; transform: translateY(-50%);
  width: 13px; height: 13px; border-radius: 3px; rotate: 45deg;
  background: var(--bg);
  border: 1.5px solid color-mix(in srgb, var(--violet) 70%, transparent);
}
.path-stage h2 {
  margin: 0; font-size: .78rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink);
}
.path-stage-count { font-size: .72rem; color: var(--ink-dim); }

.path-item {
  position: relative;
  display: grid;
  grid-template-columns: 58px minmax(200px, 240px) minmax(0, 1fr) 34px;
  align-items: center; gap: 1.2rem;
  padding: .85rem 1.2rem .85rem 0;
  border: 1px solid transparent; border-radius: var(--r);
  text-decoration: none; color: inherit;
  transition: border-color .2s ease, background .2s ease, transform .2s ease;
}
.path-item + .path-item { margin-top: .35rem; }
.path-item:hover {
  text-decoration: none;
  background: var(--panel);
  border-color: color-mix(in srgb, var(--blue) 35%, var(--line));
  transform: translateX(3px);
}

/* Node sits on the rail, filled so the line does not show through it. */
.path-node {
  justify-self: center;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--mono); font-size: .68rem; font-weight: 700;
  color: var(--ink-dim);
  background: var(--bg);
  border: 1px solid var(--line-bright);
  transition: all .2s ease;
}
.path-item:hover .path-node {
  color: #fff; border-color: transparent;
  background: var(--ramp); background-origin: border-box;
  box-shadow: 0 0 16px -3px color-mix(in srgb, var(--indigo) 85%, transparent);
}

/* The box matches the thumbnail viewBox.
   An SVG with no preserveAspectRatio uses xMidYMid meet: fit and centre. The box
   was 296x104 against art at 320x170, so the drawing rendered 196px wide with
   50px of empty card either side, and every card showed its art in a narrow
   central strip instead of filling the frame. Matching the aspect removes the
   dead space entirely rather than papering over it with padding. */
.path-art {
  display: block; border-radius: var(--r-sm); overflow: hidden;
  aspect-ratio: 320 / 170;
  background: color-mix(in srgb, var(--panel) 70%, transparent);
  border: 1px solid var(--line);
}
.path-art .thumb {
  position: static; width: 100%; height: 100%; display: block; margin: 0;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--indigo) 40%, transparent));
  transition: transform .35s ease, filter .25s ease;
}
.path-item:hover .path-art .thumb {
  transform: scale(1.05);
  filter: drop-shadow(0 0 14px color-mix(in srgb, var(--blue) 55%, transparent));
}

.path-text { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.path-title { font-size: 1.05rem; font-weight: 650; letter-spacing: -.02em; color: var(--ink); }
.path-summary { font-size: .87rem; color: var(--ink-dim); line-height: 1.5; max-width: 58ch; }
.path-meta {
  display: flex; align-items: center; gap: .6rem; margin-top: .2rem;
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-dim);
}
.path-badge {
  padding: .15rem .5rem; border-radius: 999px; letter-spacing: .08em;
  background: color-mix(in srgb, var(--blue) 16%, transparent);
  color: var(--blue); font-weight: 700;
}

.path-go {
  justify-self: end; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; color: var(--ink-dim);
  border: 1px solid var(--line); transition: all .2s ease;
}
.path-item:hover .path-go {
  color: var(--blue); border-color: var(--blue);
  box-shadow: 0 0 14px -3px color-mix(in srgb, var(--blue) 70%, transparent);
}

@media (max-width: 820px) {
  .path::before { display: none; }
  .path-stage { padding-left: 0; }
  .path-stage-dot { display: none; }
  .path-item {
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas: "node text" "art art";
    padding: .9rem;
  }
  .path-node { grid-area: node; justify-self: start; }
  .path-text { grid-area: text; }
  .path-art  { grid-area: art; margin-top: .7rem; }
  .path-go   { display: none; }
}

.learn-card .arrow {
  position: absolute; z-index: 3; top: 1.05rem; right: 1.15rem;
  width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--line-bright);
  display: grid; place-items: center; color: var(--ink-dim);
  transition: all .2s ease;
}
.learn-card:hover .arrow {
  border-color: var(--blue); color: var(--blue);
  box-shadow: 0 0 14px -2px color-mix(in srgb, var(--blue) 70%, transparent);
}


/* Labels inside a thumbnail.
   This rule had gone missing, and the symptom was subtle rather than obvious:
   the root <svg> carries fill="none", so an unstyled <text> inherits it and
   renders invisible. Only "Quantum" showed on the quantum-vs-classical card,
   because that one element happened to carry its own fill - so the card looked
   like it had a single stray label rather than a broken pair. */
.thumb-t {
  /* Sized in viewBox units, so it scales with the card. The art renders about
     240px wide against a 320-unit box, a factor of 0.75: 15 units lands at
     roughly 11px on screen, which is a readable caption. 11 units, the obvious
     first guess, would have rendered at 8. */
  font-family: var(--mono); font-size: 15px; font-weight: 600;
  fill: var(--ink-dim); letter-spacing: .04em;
}

.thumb .pulse { animation: thumbPulse 2.6s ease-in-out infinite; transform-origin: center; }
.thumb .pulse.delay { animation-delay: 1.3s; }
.thumb .dash { stroke-dasharray: 5 7; animation: thumbDash 3.4s linear infinite; }

@keyframes thumbPulse {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}
@keyframes thumbDash {
  to { stroke-dashoffset: -48; }
}

/* --- Radar cards -------------------------------------------------------- */

.radar-grid {
  display: grid; gap: .85rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* Card = image, title, short dek. The dek used to be the raw source abstract,
   which turned every card into a wall of text. */
.radar-item {
  display: flex; flex-direction: column; overflow: hidden;
  text-decoration: none; color: inherit;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
  transition: border-color .2s ease, background .2s ease, transform .2s ease, box-shadow .2s ease;
}
.radar-item:hover {
  text-decoration: none;
  border-color: color-mix(in srgb, var(--blue) 40%, var(--line-bright));
  background: var(--panel-2); transform: translateY(-3px);
  box-shadow: 0 16px 40px -22px color-mix(in srgb, var(--indigo) 90%, transparent);
}

.radar-cover {
  position: relative; display: block;
  aspect-ratio: 16 / 9; overflow: hidden;
  background: var(--bg-2); border-bottom: 1px solid var(--line);
}
.radar-cover img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .45s ease;
}
.radar-item:hover .radar-cover img { transform: scale(1.05); }

/* Palette-matched stand-in so a story with no cover does not leave a short card. */
.radar-cover-fallback {
  position: absolute; inset: 0;
  background:
    radial-gradient(420px 180px at 30% 20%, color-mix(in srgb, var(--blue) 30%, transparent), transparent 70%),
    radial-gradient(380px 200px at 75% 90%, color-mix(in srgb, var(--magenta) 26%, transparent), transparent 70%),
    linear-gradient(140deg, var(--panel-2), var(--bg));
}
.radar-cover .tag { position: absolute; left: .7rem; top: .7rem; }

.radar-body { display: flex; flex-direction: column; padding: .95rem 1.1rem 1.1rem; flex: 1; }
.radar-title {
  font-size: .98rem; font-weight: 650; line-height: 1.35; letter-spacing: -.015em;
  color: var(--ink); margin-bottom: .4rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.radar-dek {
  font-size: .84rem; color: var(--ink-dim); line-height: 1.5; margin-bottom: .8rem;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.radar-item .why { font-size: .82rem; color: var(--blue); font-weight: 600; margin-top: auto; }

/* --- News list: lead story + grid ----------------------------------------- */

.lead-story {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 0; overflow: hidden; margin: 1.4rem 0 1.2rem;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); text-decoration: none; color: inherit;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.lead-story:hover {
  text-decoration: none; transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--blue) 40%, var(--line-bright));
  box-shadow: 0 20px 50px -26px color-mix(in srgb, var(--indigo) 90%, transparent);
}
.lead-cover { position: relative; display: block; min-height: 260px; overflow: hidden; }
.lead-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lead-body { display: flex; flex-direction: column; padding: 1.6rem 1.8rem; justify-content: center; }
.lead-tags { display: flex; gap: .5rem; align-items: center; margin-bottom: .8rem; }
.lead-title {
  font-size: 1.4rem; font-weight: 700; letter-spacing: -.025em;
  line-height: 1.25; color: var(--ink); margin-bottom: .6rem;
}
.lead-dek { font-size: .92rem; color: var(--ink-2); line-height: 1.6; margin-bottom: .8rem; }
.lead-meta { font-size: .76rem; color: var(--ink-dim); margin-bottom: .9rem; }

.story-grid {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}
.radar-meta { font-size: .72rem; color: var(--ink-dim); margin-top: auto; }
.more-row { margin: 1.6rem 0 0; }

@media (max-width: 820px) {
  .lead-story { grid-template-columns: 1fr; }
  .lead-cover { min-height: 190px; aspect-ratio: 16/9; }
  .lead-body { padding: 1.2rem; }
}

/* --- Story page ----------------------------------------------------------- */

/* Prose left, cover and facts right. The same shape as a lesson page, for the
   same reason: a reading measure for the text, and the leftover width put to
   work instead of left empty. */
.story-layout {
  display: grid;
  grid-template-columns: minmax(0, var(--measure)) minmax(240px, 1fr);
  gap: 2.6rem;
  align-items: start;
  padding: 2.2rem 0 1rem;
}

.story-main { min-width: 0; }
.story-head { margin-bottom: 1rem; }
.story-head h1 {
  font-size: clamp(1.65rem, 2.9vw, 2.2rem);
  line-height: 1.2; letter-spacing: -.03em; margin: .45rem 0 0; font-weight: 800;
}
.story-main .lede { margin: 0 0 1.3rem; font-size: .98rem; line-height: 1.65; max-width: none; }
.story-main h2 { font-size: 1.15rem; margin: 2rem 0 .7rem; }

.story-aside { position: sticky; top: 88px; display: grid; gap: .9rem; }

.story-cover { margin: 0; }
.story-cover img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  border-radius: var(--r); border: 1px solid var(--line-bright);
}
.story-cover figcaption {
  margin-top: .5rem; font-size: .68rem; color: var(--ink-dim);
  font-style: italic; line-height: 1.4;
}

/* Facts read as a definition list because that is what they are. */
.facts { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: .45rem .9rem; }
.facts dt {
  font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-dim); align-self: center;
}
.facts dd { margin: 0; font-size: .84rem; color: var(--ink-2); align-self: center; }
.facts dd a { font-size: .76rem; margin-left: .35rem; }

@media (max-width: 960px) {
  .story-layout { grid-template-columns: 1fr; gap: 1.6rem; }
  .story-aside { position: static; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
  .story-cover img { aspect-ratio: 16 / 9; }
  .story-row { grid-template-columns: 1fr; }
}


/* --- Roadmap tracker ------------------------------------------------------ */
/* Each organisation gets a continuous rail in its own colour, with a stop at
   every period. Reads as a trajectory rather than a spreadsheet, which is the
   point: a roadmap IS a claimed trajectory. */

.roadmap { padding: 1.2rem 1.35rem 1rem; overflow-x: auto; }
.rm { min-width: 780px; padding-right: 30px; }

.rm-head, .rm-row {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  align-items: start; gap: .9rem;
}
.rm-head { align-items: center; padding-bottom: .9rem; border-bottom: 1px solid var(--line); margin-bottom: .2rem; }

.rm-track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
  gap: .6rem;
}

.rm-period {
  display: flex; align-items: center; gap: .5rem;
  font-size: .78rem; font-weight: 700; color: var(--ink);
  letter-spacing: .01em; font-variant-numeric: tabular-nums;
}
.rm-tick {
  width: 5px; height: 5px; flex: 0 0 auto;
  background: linear-gradient(135deg, var(--blue), var(--violet)); rotate: 45deg;
}

.rm-row { padding: .7rem 0 .5rem; }
.rm-row + .rm-row { border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }

.rm-org {
  display: flex; align-items: center; gap: .5rem;
  font-weight: 650; font-size: .8rem; line-height: 1.2; color: var(--ink);
}
.rm-badge {
  flex: 0 0 auto; width: 27px; height: 27px; border-radius: 8px;
  display: grid; place-items: center;
  font-family: var(--mono); font-style: normal;
  font-size: .58rem; font-weight: 700; letter-spacing: .02em;
  color: var(--row);
  background: color-mix(in srgb, var(--row) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--row) 38%, transparent);
  box-shadow: inset 0 0 12px -4px color-mix(in srgb, var(--row) 60%, transparent);
}

.rm-row .rm-track::before {
  content: ""; position: absolute; left: 3px; right: -22px; top: 3px; height: 1px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--row) 12%, transparent),
    color-mix(in srgb, var(--row) 70%, transparent));
}

.rm-row .rm-track::after {
  content: ""; position: absolute; top: 1px; left: 3px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--row);
  box-shadow: 0 0 10px 2px color-mix(in srgb, var(--row) 70%, transparent);
  opacity: 0;
  animation: rmPulse 6s cubic-bezier(.45, 0, .2, 1) infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes rmPulse {
  0%        { left: 3px;   opacity: 0; }
  8%        {              opacity: 1; }
  70%       { left: calc(100% + 14px); opacity: 1; }
  85%, 100% { left: calc(100% + 14px); opacity: 0; }
}

.rm-stop { position: relative; display: block; min-height: 12px; }
.rm-dot {
  display: block; position: relative; z-index: 1;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--bg);
  border: 1.6px solid var(--row);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--row) 14%, transparent);
}
.rm-dot.done { background: var(--row); }
.rm-text {
  display: block; margin-top: .5rem; padding-right: .7rem;
  font-size: .72rem; line-height: 1.42; color: var(--ink-2);
  min-height: calc(2 * 1.42em);
}
.rm-arrow {
  position: absolute; right: -30px; top: 3.5px;
  transform: translateY(-50%);
  width: 0; height: 0;
  border-left: 8px solid var(--row);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--row) 60%, transparent));
}
.roadmap .verified { margin: 1.1rem 0 0; font-size: .74rem; color: var(--ink-dim); }

/* --- Roadmap page: per-organisation detail -------------------------------- */

.rm-detail { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }

.rm-org-card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.15rem 1.25rem;
  border-top: 2px solid var(--row);
}
.rm-org-card header { display: flex; align-items: center; gap: .6rem; margin-bottom: .9rem; }
.rm-org-card h3 { margin: 0; font-size: 1rem; font-weight: 700; letter-spacing: -.015em; }
.rm-count { margin-left: auto; font-size: .68rem; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-dim); }

.rm-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: .85rem; }
.rm-steps li { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: .8rem; }
.rm-year {
  font-family: var(--mono); font-size: .74rem; font-weight: 700;
  color: var(--row); padding-top: .1rem;
}
.rm-body { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.rm-milestone { font-size: .86rem; line-height: 1.45; color: var(--ink); }
.rm-note { font-size: .76rem; color: var(--ink-dim); line-height: 1.45; }

.rm-prov { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; font-size: .7rem; }
.rm-shipped {
  padding: .1rem .45rem; border-radius: 999px; font-weight: 700; letter-spacing: .06em;
  background: color-mix(in srgb, var(--hype-low) 18%, transparent); color: var(--hype-low);
}
.rm-target {
  padding: .1rem .45rem; border-radius: 999px; font-weight: 700; letter-spacing: .06em;
  background: color-mix(in srgb, var(--ink-dim) 16%, transparent); color: var(--ink-dim);
}
/* Called out rather than left blank: an unsourced claim is the thing this page
   exists to make visible. */
.rm-nosource { color: var(--hype-high); }
.rm-prov .muted { font-size: .7rem; }

.rm-caveat { padding: 1.4rem 1.5rem; margin-top: 1.6rem; max-width: 70ch; }
.rm-caveat h2 { margin: 0 0 .7rem; font-size: 1.05rem; }
.rm-caveat p { margin: 0 0 .8rem; font-size: .88rem; line-height: 1.6; color: var(--ink-2); }
.rm-caveat p:last-child { margin-bottom: 0; }

/* --- Reality check -------------------------------------------------------- */

.reality {
  display: grid;
  grid-template-columns: minmax(165px, .9fr) 5.2fr minmax(170px, 1fr);
  gap: 0; overflow: hidden;
}
.reality .intro { padding: 1.4rem 1.25rem; border-right: 1px solid var(--line); }
.reality .intro h2 { margin: 0 0 .5rem; font-size: 1.08rem; letter-spacing: -.02em; }
.reality .intro p { margin: 0; font-size: .82rem; color: var(--ink-dim); line-height: 1.55; }

.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }

.metric {
  position: relative;
  padding: 1.2rem .95rem;
  display: flex; gap: .7rem; align-items: center;
}
.metric + .metric { border-left: 1px solid var(--line); }

/* Fixed box, or the inline SVG expands to fill the column and the strip becomes
   a stack of enormous circles. */
.metric .glyph { width: 50px; height: 50px; flex: 0 0 auto; }
.metric-body { min-width: 0; }

.metric .label {
  font-size: .62rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-dim); line-height: 1.3;
  min-height: calc(2 * 1.3em);
}
.metric .value {
  font-size: 1.45rem; font-weight: 750; letter-spacing: -.03em;
  margin: .1rem 0 .15rem; line-height: 1.05;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.metric .value.soft {
  background: var(--ramp); -webkit-background-clip: text; background-clip: text;
  color: transparent; font-size: 1.08rem;
}
.metric .caption { font-size: .67rem; color: var(--ink-dim); line-height: 1.38; }

.metric-sep {
  position: absolute; right: -5px; top: 50%; transform: translateY(-50%);
  z-index: 2; color: var(--ink-dim);
  background: var(--panel); padding: 4px 0;
  display: flex; align-items: center;
}

.our-take {
  padding: 1.4rem 1.25rem; border-left: 1px solid var(--line);
  background: linear-gradient(160deg, color-mix(in srgb, var(--indigo) 14%, transparent), transparent);
}
.our-take h3 {
  margin: 0 0 .5rem; font-size: .68rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--blue);
}
.our-take p { margin: 0; font-size: .8rem; line-height: 1.55; color: var(--ink-2); }

@media (max-width: 980px) {
  .reality { grid-template-columns: 1fr; }
  .reality .intro { border-right: 0; border-bottom: 1px solid var(--line); }
  .our-take { border-left: 0; border-top: 1px solid var(--line); }
  .metric-sep { display: none; }
  .metric + .metric { border-left: 0; border-top: 1px solid var(--line); }
}


/* --- Quantum 101 glossary ------------------------------------------------- */

.g-jump {
  display: flex; gap: .5rem; flex-wrap: wrap; margin: 0 0 1.6rem;
  padding-bottom: 1rem; border-bottom: 1px solid var(--line);
}
.g-jump a {
  font-size: .74rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-dim); border: 1px solid var(--line);
  padding: .35rem .8rem; border-radius: 999px;
}
.g-jump a:hover { color: var(--blue); border-color: var(--blue); text-decoration: none; }

.g-section { margin-bottom: 2.2rem; scroll-margin-top: 84px; }
.g-grid { display: grid; gap: .85rem; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }

.g-card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.05rem 1.15rem;
  display: flex; flex-direction: column; scroll-margin-top: 84px;
  transition: border-color .2s ease, transform .2s ease;
}
.g-card:hover { border-color: var(--line-bright); transform: translateY(-2px); }
.g-card h3 { margin: 0 0 .45rem; font-size: .98rem; font-weight: 700; letter-spacing: -.015em; }
.g-def { margin: 0; font-size: .85rem; line-height: 1.55; color: var(--ink-2); }

/* The distinguishing part of the page, so it is styled as a caution, not a note. */
.g-watch {
  margin: .8rem 0 0; padding: .6rem .75rem;
  border-left: 2px solid var(--hype-medium);
  background: color-mix(in srgb, var(--hype-medium) 7%, transparent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: .79rem; line-height: 1.5; color: var(--ink-2);
}
.g-watch-label {
  display: block; font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--hype-medium); font-weight: 700; margin-bottom: .2rem;
}
.g-lesson { margin-top: auto; padding-top: .8rem; font-size: .78rem; font-weight: 600; }

/* --- Newsletter ----------------------------------------------------------- */

.subscribe {
  position: relative; overflow: hidden; isolation: isolate;
  border-radius: var(--r);
  border: 1px solid var(--line-bright);
  background-origin: border-box;
  background:
    radial-gradient(760px 220px at 8% 130%, color-mix(in srgb, var(--blue) 22%, transparent), transparent),
    radial-gradient(760px 240px at 92% -30%, color-mix(in srgb, var(--magenta) 20%, transparent), transparent),
    var(--panel);
  padding: 1.5rem 1.8rem;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 430px);
  gap: 1.6rem; align-items: center;
}
/* Field lines run the full width behind the content. */
.sub-field {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: -1; opacity: .5; pointer-events: none;
}

.sub-copy { display: flex; gap: 1.1rem; align-items: center; }
/* Fixed box. Without it the inline SVG expands to fill the column and the
   envelope renders about 400px tall. */
.sub-icon { width: 58px; height: 58px; flex: 0 0 auto; }
.sub-icon svg {
  width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 0 12px color-mix(in srgb, var(--indigo) 60%, transparent));
}

.subscribe h2 { margin: 0 0 .4rem; font-size: 1.22rem; letter-spacing: -.025em; line-height: 1.25; }
.subscribe p { margin: 0; color: var(--ink-2); font-size: .86rem; }

.sub-action { min-width: 0; }
.sub-form { display: flex; gap: .55rem; }
.sub-form input {
  flex: 1; min-width: 0;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border: 1px solid var(--line-bright); border-radius: 999px;
  padding: .8rem 1.2rem; color: var(--ink); font: inherit; font-size: .9rem;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.sub-form input::placeholder { color: var(--ink-dim); }
.sub-form input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--blue) 70%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 16%, transparent);
}
.sub-form .btn { flex: 0 0 auto; padding-inline: 1.35rem; }

.sub-note, .sub-msg { margin: .6rem 0 0; font-size: .78rem; }
.sub-note { color: var(--ink-dim); }
.sub-msg.ok  { color: var(--hype-low); }
.sub-msg.bad { color: var(--hype-high); }

@media (max-width: 860px) {
  .subscribe { grid-template-columns: 1fr; }
  .sub-copy { flex-direction: column; align-items: flex-start; gap: .8rem; }
  .sub-form { flex-direction: column; }
  .sub-form .btn { justify-content: center; }
}


/* --- Lesson visual band --------------------------------------------------- */

/* Full-bleed background so the interactive reads as the centrepiece rather than
   a figure inside the article. */
.viz-band {
  position: relative; margin: .4rem 0 2rem; padding: 1.6rem 0 1.8rem;
  border-block: 1px solid var(--line);
  background:
    radial-gradient(900px 300px at 25% 0%, color-mix(in srgb, var(--blue) 15%, transparent), transparent 70%),
    radial-gradient(800px 320px at 80% 100%, color-mix(in srgb, var(--magenta) 13%, transparent), transparent 70%),
    color-mix(in srgb, var(--panel) 45%, transparent);
}

.viz-large { max-width: none; }
.viz-large .viz-stage { aspect-ratio: 21 / 9; min-height: 380px; }
.viz-large canvas { width: 100%; height: 100%; display: block; }

/* Controls read as a strip under the stage, not a form.
   The strip must not reflow when a readout changes. Every value in it is live:
   moving the search slider takes "256" to "4096" and the speedup from "3.4x" to
   "41.0x", and because the row was laid out purely from content widths, each of
   those pushed the slider and the buttons sideways. Dragging the slider made the
   whole strip walk about.
   Three rules fix it, in this order:
     1. the actions are pinned to the right edge, so nothing before them can move
        them
     2. the slider is the flexible element, so it absorbs every width change
     3. the stats reserve a floor width, so short-labelled ones like SPEEDUP do
        not resize under their own value
   Reserving width on the stats alone would not have been enough: the tally and
   the label lengths differ per widget, and pinning the buttons is what actually
   makes the row stable for renderers not yet written. */
.viz-large .viz-panel {
  display: flex; align-items: center; gap: 1.6rem; flex-wrap: wrap;
  padding: 1rem 1.3rem;
}
.viz-large .viz-readout { display: flex; gap: 1.8rem; }
/* .viz-stat is what the script creates; .v was a guess and matched nothing. */
.viz-large .viz-stat { min-width: 7.5rem; }
.viz-large .viz-stat .v { font-size: 1.7rem; }
.viz-large .viz-slider { flex: 1 1 260px; min-width: 0; }
.viz-large .viz-actions { margin-left: auto; }

@media (max-width: 720px) {
  .viz-large .viz-stage { aspect-ratio: 4 / 3; min-height: 300px; }
  .viz-large .viz-panel { gap: 1rem; }
  /* Once the strip wraps, each part is on its own line. Pinning right there
     would strand the buttons against the edge under a left-aligned readout. */
  .viz-large .viz-actions { margin-left: 0; }
  .viz-large .viz-stat { min-width: 0; }
}

/* --- Lesson page ---------------------------------------------------------- */

.lesson-head { padding-block: 2rem 1.4rem; }
.crumbs { display: flex; gap: .5rem; align-items: center; font-size: .78rem; color: var(--ink-dim); }
.crumbs a { color: var(--ink-dim); }
.crumbs a:hover { color: var(--blue); text-decoration: none; }

.lesson-title-row { display: flex; gap: 1.1rem; align-items: flex-start; margin-top: .9rem; }
/* The number is the sequence made visible, same as on the Learn path. */
.lesson-num {
  flex: 0 0 auto; font-family: var(--mono); font-size: 1.5rem; font-weight: 700;
  line-height: 1; padding-top: .35rem;
  background: var(--ramp); -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.lesson-head h1 {
  font-size: clamp(1.8rem, 3.4vw, 2.6rem);
  line-height: 1.14; letter-spacing: -.035em; margin: 0; font-weight: 800;
}
.lesson-head .lede { margin: .6rem 0 0; font-size: 1rem; max-width: 56ch; }

.lesson-progress { display: flex; align-items: center; gap: .3rem; margin-top: 1.3rem; }
.lesson-progress > span {
  width: 26px; height: 3px; border-radius: 2px;
  background: var(--line-bright);
}
.lesson-progress > span.done { background: color-mix(in srgb, var(--blue) 60%, transparent); }
.lesson-progress > span.here {
  background: var(--ramp); width: 40px;
  box-shadow: 0 0 12px -2px color-mix(in srgb, var(--indigo) 90%, transparent);
}
.lesson-progress-label {
  width: auto !important; height: auto !important; background: none !important;
  margin-left: .7rem; font-size: .72rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-dim);
}

.lesson-body {
  display: grid; gap: 2.4rem;
  grid-template-columns: minmax(0, var(--measure)) minmax(220px, 1fr);
  align-items: start; padding-bottom: 1rem;
}
.lesson-body .prose { max-width: none; }
.lesson-body .prose p { font-size: 1.02rem; line-height: 1.75; margin: 0 0 1.15rem; }

/* The opening paragraph carries the lesson, so it gets a little more weight. */
.lesson-body .prose > p:first-of-type {
  font-size: 1.12rem; line-height: 1.65; color: var(--ink);
}
.lesson-body .prose h2 { font-size: 1.2rem; margin: 2.2rem 0 .7rem; }

.lesson-aside { position: sticky; top: 88px; display: grid; gap: .85rem; }
.aside-card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.1rem 1.2rem;
}
.aside-card h2 {
  margin: 0 0 .7rem; font-size: .68rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-2);
}

.term-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.term-chips a {
  display: inline-block; font-size: .76rem;
  padding: .25rem .6rem; border-radius: 999px;
  border: 1px solid var(--line-bright); color: var(--ink-2);
}
.term-chips a:hover { border-color: var(--blue); color: var(--blue); text-decoration: none; }

.aside-list { list-style: none; margin: 0; padding: 0; counter-reset: aside; display: grid; gap: .45rem; }
.aside-list li { counter-increment: aside; font-size: .84rem; line-height: 1.4; }
.aside-list li::before {
  content: counter(aside, decimal-leading-zero) "  ";
  font-family: var(--mono); font-size: .7rem; color: var(--ink-dim);
}
.aside-list a { color: var(--ink-2); }
.aside-list a:hover { color: var(--blue); text-decoration: none; }
.aside-list li.current span { color: var(--blue); font-weight: 650; }
.aside-list li.current::before { color: var(--blue); }
.aside-btn { width: 100%; justify-content: center; margin-top: .8rem; font-size: .85rem; }

/* Prev and next carry the artwork, so the next lesson is recognisable before
   you read its title. */
.lesson-nav {
  display: grid; grid-template-columns: 1fr 1fr; gap: .85rem;
  margin: 1.8rem 0 1rem;
}
.lesson-nav a {
  display: flex; align-items: center; gap: .9rem;
  border: 1px solid var(--line); border-radius: var(--r);
  padding: .9rem 1rem; background: var(--panel);
  text-decoration: none; overflow: hidden;
  transition: border-color .2s ease, background .2s ease, transform .2s ease;
}
.lesson-nav a:hover {
  border-color: color-mix(in srgb, var(--blue) 45%, var(--line-bright));
  background: var(--panel-2); text-decoration: none; transform: translateY(-2px);
}
.lesson-nav-art {
  /* Same reason as .path-art: 84x54 against a 320x170 viewBox letterboxed the
     art with a 5px bar above and below. */
  flex: 0 0 84px; aspect-ratio: 320 / 170; overflow: hidden; border-radius: var(--r-sm);
  background: var(--bg-2); border: 1px solid var(--line);
}
.lesson-nav-art .thumb {
  position: static; width: 100%; height: 100%; margin: 0;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--indigo) 40%, transparent));
}
.lesson-nav-text { display: flex; flex-direction: column; gap: .25rem; min-width: 0; }
.lesson-nav .k {
  font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-dim);
}
.lesson-nav .t { font-size: .92rem; font-weight: 650; color: var(--ink); line-height: 1.3; }
.lesson-next { flex-direction: row-reverse; text-align: right; }
.lesson-next .lesson-nav-text { align-items: flex-end; }

@media (max-width: 960px) {
  .lesson-body { grid-template-columns: 1fr; gap: 1.6rem; }
  .lesson-aside { position: static; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
}
@media (max-width: 620px) {
  .lesson-nav { grid-template-columns: 1fr; }
  .lesson-next { flex-direction: row; text-align: left; }
  .lesson-next .lesson-nav-text { align-items: flex-start; }
  .lesson-title-row { gap: .7rem; }
}

/* --- Generic content ---------------------------------------------------- */

main { display: block; }
/* padding-block, not the shorthand: `class="shell page"` would otherwise
   reset .shell's horizontal padding to 0 and the title would sit flush to the
   viewport edge while the body below stayed indented. */
.page { padding-block: 2.6rem 1rem; }
.page h1 { font-size: clamp(2rem, 4vw, 2.9rem); letter-spacing: -.035em; margin: 0 0 .6rem; font-weight: 800; }
.lede { color: var(--ink-2); font-size: 1.05rem; max-width: var(--measure); }
.muted { color: var(--ink-dim); font-size: .88rem; }
.prose { max-width: var(--measure); }
.prose h2 { font-size: 1.25rem; margin: 2rem 0 .6rem; letter-spacing: -.02em; }
.prose p { color: var(--ink-2); }
.eyebrow { text-transform: uppercase; letter-spacing: .14em; font-size: .7rem; color: var(--ink-dim); }

.empty {
  border: 1px dashed var(--line-bright); border-radius: var(--r);
  padding: 2.2rem; text-align: center; color: var(--ink-dim);
}
/* An empty state should explain itself, not just report emptiness. */
.empty-rich { text-align: left; padding: 2rem 2.2rem; max-width: 62ch; margin: 0 auto; }
.empty-rich h2 { margin: 0 0 .6rem; font-size: 1.1rem; color: var(--ink); letter-spacing: -.02em; }
.empty-rich p { margin: 0 0 .7rem; font-size: .9rem; line-height: 1.6; }
.empty-rich p:last-child { margin-bottom: 0; }

.story-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 1.25rem; }
.card h3 { margin: .4rem 0 .5rem; font-size: 1.08rem; }

.badge {
  display: inline-block; padding: .18rem .6rem; border-radius: 999px;
  font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
}
.badge-low    { background: color-mix(in srgb, var(--hype-low) 18%, transparent);    color: var(--hype-low); }
.badge-medium { background: color-mix(in srgb, var(--hype-medium) 18%, transparent); color: var(--hype-medium); }
.badge-high   { background: color-mix(in srgb, var(--hype-high) 18%, transparent);   color: var(--hype-high); }

.analysis { display: grid; gap: 1rem; margin: 1.6rem 0; }
.analysis section {
  border-left: 3px solid var(--indigo); background: var(--panel);
  padding: 1rem 1.2rem; border-radius: 0 var(--r) var(--r) 0;
}
.analysis section.not-achieved { border-left-color: var(--magenta); }
.analysis h3 { margin: 0 0 .4rem; font-size: .95rem; }
.analysis p { margin: 0; color: var(--ink-2); }

.source-quote {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.1rem 1.3rem; margin: 1.4rem 0;
}
.source-quote p { margin: 0 0 .5rem; font-style: italic; }
.source-quote footer { font-size: .84rem; color: var(--ink-dim); }

.rubric { width: 100%; border-collapse: collapse; font-size: .92rem; }
.rubric th, .rubric td { text-align: left; padding: .65rem .8rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.rubric th { color: var(--ink-dim); font-size: .74rem; text-transform: uppercase; letter-spacing: .09em; }
.rubric .points { font-family: var(--mono); font-weight: 700; white-space: nowrap; }
.rubric .neg { color: var(--hype-low); }
.rubric .pos { color: var(--hype-high); }

.sources { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.sources li { padding: .7rem .9rem; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-sm); }
.sources .tier { font-size: .76rem; color: var(--ink-dim); }

/* --- Lesson visualizations --------------------------------------------- */

.viz {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); margin: 1.8rem 0; overflow: hidden;
}
.viz-stage {
  background:
    radial-gradient(600px 200px at 50% 0%, color-mix(in srgb, var(--indigo) 12%, transparent), transparent),
    var(--bg-2);
  border-bottom: 1px solid var(--line);
}
.viz-stage canvas { display: block; touch-action: none; cursor: grab; }
.viz-stage canvas:active { cursor: grabbing; }

.viz-panel { padding: 1.1rem 1.25rem 1.25rem; }

.viz-readout { display: flex; flex-wrap: wrap; gap: 1.6rem; margin-bottom: .9rem; }
.viz-stat { display: flex; flex-direction: column; gap: .1rem; }
.viz-stat .k {
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-dim);
}
.viz-stat .v {
  font-family: var(--mono); font-size: 1.25rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--ink);
  /* --reserve is set by statBox() in viz.js: the widest value that stat can ever
     hold, in characters. Resolved here rather than there because 1ch has to be
     measured in this font, not in the parent's. */
  min-width: calc(var(--reserve, 0) * 1ch);
}

/* Shown when a lesson names a renderer that is not registered. Deliberately
   plain and readable rather than styled like an error page: it is a note to
   whoever is building, and it never appears once the key resolves. */
.viz-missing {
  padding: 2rem 1.5rem; text-align: center;
  font-family: var(--mono); font-size: .85rem; color: var(--ink-dim);
}

.viz-hint { margin: .9rem 0 0; font-size: .85rem; color: var(--ink-dim); line-height: 1.55; max-width: 62ch; }

.viz-actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.viz-btn {
  border: 1px solid transparent; border-radius: 999px;
  padding: .5rem 1.1rem; font: inherit; font-size: .87rem; font-weight: 600;
  background: var(--ramp); color: #fff; cursor: pointer;
  /* Same cause as .btn-primary: background-origin defaults to padding-box while
     background-clip defaults to border-box, so with a 1px border the gradient
     tile is 2px narrower than the area it paints and repeats. The caps then show
     the wrong end of the ramp and read as chopped off. */
  background-origin: border-box;
  background-repeat: no-repeat;
  transition: transform .16s ease, opacity .16s ease;
}
.viz-btn:hover { transform: translateY(-1px); }
.viz-btn-ghost { background: transparent; border-color: var(--line-bright); color: var(--ink-2); }
.viz-btn-ghost:hover { border-color: var(--blue); color: var(--ink); }
/* Reserves room for the widest value it will hold, so the slider track does not
   twitch shorter as the number gains a digit. */
.viz-tally {
  font-size: .82rem; color: var(--ink-dim); margin-left: .3rem;
  flex: none; white-space: nowrap;
  display: inline-block; min-width: 4.5ch;
  font-variant-numeric: tabular-nums;
}

/* nowrap, deliberately. Wrapping let the label drop above its own track and the
   tally below it, at different points for each slider, so two sliders in one
   strip sat at two different heights and nothing lined up with the buttons.
   The track is the only part that may shrink. */
.viz-slider { display: flex; align-items: center; gap: .9rem; flex-wrap: nowrap; }
.viz-slider label {
  flex: none; white-space: nowrap;
  font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim);
}
.viz-slider input[type=range] {
  flex: 1 1 120px; min-width: 90px; accent-color: var(--violet);
  background: transparent; height: 22px;
}

.footer {
  border-top: 1px solid var(--line); margin-top: 3.5rem;
  padding: 2.6rem 0 1.6rem;
  color: var(--ink-dim); font-size: .86rem;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--panel) 55%, transparent));
}

.footer-grid {
  display: grid; gap: 2rem;
  grid-template-columns: minmax(240px, 1.6fr) repeat(3, minmax(150px, 1fr));
  padding-bottom: 2rem;
}

.footer-brand .brand { font-size: 1.25rem; margin-bottom: .8rem; }
.footer-brand .mark { width: 32px; height: 29px; }
.footer-brand p { margin: 0; max-width: 42ch; line-height: 1.6; font-size: .84rem; }

.footer-col { display: flex; flex-direction: column; gap: .5rem; }
.footer-col h3 {
  margin: 0 0 .3rem; font-size: .68rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-2); font-weight: 700;
}
.footer-col a { color: var(--ink-dim); font-size: .84rem; }
.footer-col a:hover { color: var(--blue); text-decoration: none; }
.footer-note { margin: 0; font-size: .8rem; line-height: 1.55; }

.footer-bar {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  border-top: 1px solid var(--line); padding-top: 1.3rem;
  font-size: .8rem;
}
.footer-bar a { color: var(--ink-2); font-weight: 600; }
.footer-bar a:hover { color: var(--blue); text-decoration: none; }
.footer-dot {
  width: 3px; height: 3px; border-radius: 50%; background: var(--line-bright);
}
.footer-bar-end { margin-left: auto; color: var(--ink-dim); display: flex; align-items: center; gap: .8rem; }
.footer-ops {
  font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-dim); border: 1px solid var(--line);
  padding: .2rem .55rem; border-radius: 999px;
}
.footer-ops:hover { color: var(--blue); border-color: var(--blue); text-decoration: none; }

/* --- Responsive --------------------------------------------------------- */

@media (max-width: 980px) {
  .hero .shell { grid-template-columns: 1fr; min-height: 0; }
  .hero-visual { min-height: 280px; order: -1; }
  .split { grid-template-columns: 1fr; }
  .reality { grid-template-columns: 1fr; }
  .reality .intro { border-right: 0; border-bottom: 1px solid var(--line); }
  .our-take { border-left: 0; border-top: 1px solid var(--line); }
  .metric-sep { display: none; }
  .footer-grid { grid-template-columns: minmax(220px, 1.4fr) repeat(2, minmax(140px, 1fr)); }
  .subscribe { grid-template-columns: 1fr; }
  .lesson-body { grid-template-columns: 1fr; gap: 1.6rem; }
  .lesson-aside { position: static; }
  .metric { border-left: 0; border-top: 1px solid var(--line); }
}

@media (max-width: 620px) {
  .masthead .shell { height: auto; padding-top: .8rem; padding-bottom: .8rem; flex-wrap: wrap; gap: .8rem; }
  .masthead nav { gap: 1.1rem; width: 100%; margin-left: 0; }
  .readout { display: none; }
  .sub-form { flex-direction: column; }
  .sub-copy { flex-direction: column; align-items: flex-start; gap: .8rem; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-bar-end { margin-left: 0; width: 100%; }
  .subscribe .btn { justify-content: center; }
  .lesson-nav { grid-template-columns: 1fr; }
  .lesson-next { text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Static lit ring instead of a travelling one. */
  .learn-card:hover::before { animation: none; rotate: 300deg; }
  .rm-row .rm-track::after { animation: none; opacity: 0; }
  .learn-card:hover .thumb { transform: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}


/* --- Mobile sweep --------------------------------------------------------- */
/*
   Measured at 375px, where the shell leaves 343px of content.

   Worth recording what did NOT need changing, because a first pass "fixed" three
   layouts that were already fine: .reality collapses at 620px, .rm-row is
   132px + 1fr so it fits, and .rm-track uses minmax(0, 1fr) columns which shrink
   rather than overflow. Rules were written for .rm-year and .rm-source, neither of
   which exists in the markup at all. Those are all removed; what follows is only
   what a real measurement justified.
*/
@media (max-width: 620px) {
  /* 44px is the smallest target a thumb hits reliably. These were sized for a
     mouse pointer, and the viz controls are the main thing a reader touches. */
  .btn-sm, .viz-btn, .tabchip { min-height: 44px; }
  .viz-actions { gap: .5rem; }

  /* The slider track has a 90px minimum, which on a phone leaves a control too
     short to drag with any precision. Full width, taller hit area. */
  .viz-slider { flex-wrap: wrap; }
  .viz-slider label { flex: 1 1 100%; }
  .viz-slider input[type=range] { flex: 1 1 100%; min-width: 0; height: 32px; }

  /* Slugs, URLs and arXiv identifiers are unbreakable strings and are the one
     thing in generated content that can push a page sideways. Invisible on
     desktop, which is why it needs saying rather than testing for. */
  .path, code, .story-cell .path { overflow-wrap: anywhere; }
}

/*
   No global overflow-x: hidden.

   It is the usual reflex for a page that scrolls sideways, and it would have
   broken this site: the masthead is position: sticky, and an overflow container
   on html or body stops sticky working. The wrap rules above address the actual
   cause instead of hiding it.
*/

/* Subscribe confirmation. The tick and the text sit on one line, and the block
   holds its height so the section does not jump when the message replaces the
   form's helper text. */
.sub-msg {
  display: flex; align-items: center; gap: .5rem;
  margin: .7rem 0 0; font-size: .88rem; min-height: 1.4rem;
}
.sub-msg.ok { color: var(--ok, #34d399); }
.sub-msg.bad { color: var(--bad, #f87171); }

/* --- Error and status pages ----------------------------------------------- */
/* Full-height so a 404 does not sit as a thin strip above a tall empty footer
   gap, which is what makes an error page feel like a broken page rather than a
   deliberate one. */
.err {
  display: flex; align-items: center;
  min-height: clamp(420px, 62vh, 640px);
  padding: 3rem 0;
}
.err-inner {
  display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  align-items: center; gap: clamp(1.5rem, 4vw, 3.5rem);
}
.err-art svg { width: 100%; height: auto; display: block; }

/* The orbits drift slowly. Enough to read as alive, slow enough not to pull the
   eye away from the links, which are the point of the page. */
.err-art ellipse { animation: errDrift 26s linear infinite; transform-origin: 110px 100px; }
.err-art ellipse:nth-of-type(2) { animation-duration: 34s; animation-direction: reverse; }
.err-art ellipse:nth-of-type(3) { animation-duration: 42s; }

@keyframes errDrift { to { transform: rotate(360deg); } }

.err-text h1 {
  margin: .4rem 0 .6rem;
  font-size: clamp(1.7rem, 4.2vw, 2.6rem); letter-spacing: -.03em; line-height: 1.1;
}
.err-text .lede { max-width: 46ch; }
.err-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.6rem; }
.err-ref { margin-top: 1.4rem; font-family: var(--mono); font-size: .74rem; }

@media (max-width: 720px) {
  /* Art above the text, and smaller: on a phone the words and the links matter
     and the illustration is decoration. */
  .err-inner { grid-template-columns: 1fr; gap: 1.2rem; }
  .err-art { max-width: 190px; margin: 0 auto; }
  .err { min-height: 0; padding: 2rem 0 3rem; }
  .err-actions .btn { flex: 1 1 auto; text-align: center; min-height: 44px; }
}

/* The drifting orbits stop for anyone who asked motion to stop. */
@media (prefers-reduced-motion: reduce) {
  .err-art ellipse { animation: none; }
}
