/* Attention DNA — the public landing page (index.html only; the app never loads this).

   Built from the owner's "Strand" design system (Attention DNA - Home):
   - Two grounds that alternate: a navy band (#0b1020) and a pale band
     (#eceff7). Panels on navy are #141b34.
   - One family: Bricolage Grotesque for everything, set large, light and
     tightly tracked, with one bold accent phrase per headline. JetBrains Mono
     for kickers, labels, axis ticks and the numbers inside cards.
   - The three strand channels carry the colour: visual #a855f7, language
     #6366f1, auditory #14b8a6. A strand cell is the channel mixed into the
     panel colour by its strength (8–100%).
   - Every number a reader could take for a result sits in a
     <figure class="example"> whose visible caption says it is an example.

   Contrast notes (WCAG AA):
   - Body on navy #aab2ca ≈ 9:1; mono labels #8e97b3 ≈ 6.5:1 on navy and
     5.9:1 on panels. The design's #6b7390 axis ticks (3.6:1) use #8e97b3.
   - The nav pill is rgba(20,27,52,.82), not the design's .72: over the pale
     band .72 leaves the links at 3.4:1; .82 gives 4.8:1.
   - The READ card is #9333ea, not #a855f7: white body text on #a855f7 is
     4.0:1, on #9333ea 5.4:1. Its "Example" caption is white at .92 (4.8:1).
   - Language DNA keeps the app's own five colours (css/styles.css): the
     light set on the white LABEL card, the app's dark-theme set inside the
     navy readout panels, where text over a 24% tint stays above 10:1.
   - The CTA band is #6265f0, one step under the design's #6366f1, which puts
     white body text at 4.53:1 instead of 4.47:1. The two are indistinguishable. */

:root {
  /* Grounds */
  --ground: #0b1020;
  --panel: #141b34;
  --band: #eceff7;
  --white: #ffffff;
  --cta-band: #6265f0;

  /* Text on navy */
  --fg: #eceff7;
  --fg-body: #aab2ca;
  --fg-panel: #c9cfe0;
  --fg-meta: #8e97b3;

  /* Text on the pale band */
  --ink: #0b1020;
  --ink-body: #3b4360;
  --ink-meta: #4a5270;
  --line-light: #d7dbe8;

  /* Strand channels */
  --ch-visual: #a855f7;
  --ch-language: #6366f1;
  --ch-auditory: #14b8a6;

  /* Accents */
  --mint: #5eead4;
  --lilac: #c084fc;
  --indigo: #6366f1;
  --teal: #14b8a6;
  --read: #9333ea;

  /* Language DNA, in the app's fixed order: Facts, Fun, Feeling,
     Opinionated, Action. Readout panels switch to the dark-theme set. */
  --dna-facts: #2a78d6;
  --dna-fun: #eb6834;
  --dna-feeling: #e87ba4;
  --dna-opinion: #4a3aa7;
  --dna-action: #e34948;

  /* Hairlines on navy */
  --hair: rgba(255, 255, 255, 0.08);
  --hair-2: rgba(255, 255, 255, 0.12);
  --ghost: rgba(255, 255, 255, 0.2);

  /* Radii */
  --r-pill: 999px;
  --r-chip: 6px;
  --r-tile: 16px;
  --r-row: 20px;
  --r-card: 24px;
  --r-step: 28px;
  --r-band: 36px;

  /* Type and rhythm */
  --sans: 'Bricolage Grotesque', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --ease: cubic-bezier(.2, .7, .2, 1);
  --gutter: clamp(20px, 4vw, 56px);
  --section-y: clamp(100px, 12vw, 180px);
  --max: 1520px;
  --band-edge: clamp(8px, 1vw, 16px);

  /* Focus ring and headline accent; sections override both. */
  --focus: var(--mint);
  --accent: var(--mint);
}

/* ── Base ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
body {
  margin: 0;
  background: var(--ground);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, pre { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; transition: color .2s, background-color .2s, border-color .2s; }
a:hover { color: var(--mint); }
strong, b { font-weight: 700; }
svg { display: block; }
::selection { background: var(--teal); color: var(--ink); }

/* main clips sideways overflow without becoming a scroll container, so the
   pinned how-it-works stage can still stick. */
main { display: block; overflow-x: clip; }
main:focus { outline: none; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}
/* The fixed nav pill reaches 68px down the screen. Without this, focus
   moving upward leaves a control at (or scrolls it to) the top edge, under
   the pill. The padding makes the browser treat the top 88px (pill + focus
   ring + room) as covered. The sections cancel it, so an in-page link still
   lands its section at the very top, as in the design; an engine without
   negative margins lands it 88px down instead. */
html { scroll-padding-top: 88px; }
section[id] { scroll-margin-top: -88px; }

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

.skip-link {
  position: fixed; top: 12px; left: 12px; z-index: 100;
  padding: 12px 18px; border-radius: var(--r-pill);
  background: var(--fg); color: var(--ink);
  font-size: 15px; font-weight: 500;
  transform: translateY(-160%);
  transition: transform .2s var(--ease);
}
.skip-link:focus { transform: none; color: var(--ink); }

/* ── Shared patterns ──────────────────────────────────────────────────── */
.band-dark { background: var(--ground); color: var(--fg); }
.band-light { background: var(--band); color: var(--ink); --focus: #4f46e5; }

.section { padding: var(--section-y) var(--gutter); }
.wrap { max-width: var(--max); margin: 0 auto; }
.stack-56 { display: grid; gap: 56px; }
.stack-48 { display: grid; gap: 48px; }
.stack-20 { display: grid; gap: 20px; }

/* Single-column grids get an explicit minmax(0, 1fr) column. An implicit
   column sizes to its children's min-content, and an auto-fit grid inside
   one (the access columns, the method cards) reports a min-content wider
   than a phone, which would push the column past the screen edge. */
.stack-56, .stack-48, .stack-20, .hero-copy, .manifesto-inner, .cuts,
.formats, .fmt-panels, .fmt-copy, .fmt-panel, .flow-block,
.imports-copy, .faq-inner, .qa-list, .band, .band-top {
  grid-template-columns: minmax(0, 1fr);
}

.kicker {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-meta);
}
.band-light .kicker { color: var(--ink-meta); }

.h2 {
  font-weight: 400;
  font-size: clamp(44px, 6vw, 96px);
  line-height: .92;
  letter-spacing: -.05em;
}
.h2--sm { font-size: clamp(40px, 5vw, 80px); }
.h2 .accent { font-weight: 700; color: var(--accent); }

.sec-head {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
  gap: 32px;
  align-items: end;
}
.sec-lede {
  max-width: 44ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--fg-body);
  text-wrap: pretty;
}
.band-light .sec-lede { color: var(--ink-body); }

/* Example figures: the caption is always visible, in the quiet mono voice. */
.example figcaption {
  margin-top: 14px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: .02em;
  color: var(--fg-meta);
}
.band-light .example figcaption { color: var(--ink-meta); }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 15px 24px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-size: 15px; font-weight: 500; line-height: 1.2;
  white-space: nowrap;
}
.btn-primary { background: var(--fg); color: var(--ink); }
.btn-primary:hover { background: var(--mint); color: var(--ink); }
.btn-ghost { border-color: var(--ghost); color: var(--fg); }
.btn-ghost:hover { border-color: var(--mint); color: var(--mint); }

/* ── Strand cells (hero, cut cards, readout panel) ─────────────────────
   js/landing.js fills each .row with one <span> per second. Until it does —
   or if it never runs — an empty row paints evenly spaced cells at a middle
   strength, so the shape of a strand is there either way. */
.row:empty {
  --cell-fill: rgba(99, 102, 241, .45);
  background: linear-gradient(90deg, var(--cell-fill) calc(100% - var(--gap, 3px)), transparent 0)
              0 0 / calc((100% + var(--gap, 3px)) / var(--n, 30)) 100% repeat-x;
}
@supports (color: color-mix(in oklab, red 50%, blue)) {
  .row:empty { --cell-fill: color-mix(in oklab, var(--ch) 55%, var(--panel)); }
}

/* ── Navigation ───────────────────────────────────────────────────────── */
.nav {
  position: fixed; top: 14px; left: 50%; z-index: 30;
  transform: translateX(-50%);
  max-width: calc(100% - 24px);
}
.nav-pill {
  display: flex; align-items: center;
  gap: clamp(12px, 2vw, 28px);
  padding: 8px 8px 8px 18px;
  border-radius: var(--r-pill);
  background: rgba(20, 27, 52, .82);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--hair);
}
.wordmark {
  font-weight: 700; font-size: 15px; letter-spacing: -.02em;
  white-space: nowrap; color: var(--fg);
}
.wordmark span { color: var(--mint); }
.wordmark:hover { color: var(--fg); }
.nav-links {
  display: flex; gap: clamp(10px, 1.8vw, 22px);
  font-size: 14px; color: var(--fg-body); white-space: nowrap;
}
.nav-signin { font-size: 14px; color: var(--fg); white-space: nowrap; }
.btn-nav {
  padding: 9px 16px; border-radius: var(--r-pill);
  background: var(--teal); color: var(--ink);
  font-weight: 500; font-size: 14px; line-height: 1.25; white-space: nowrap;
}
.btn-nav:hover { background: var(--mint); color: var(--ink); }

/* The phone menu button: a 44px target drawn as a 36px circle, pulled into
   the pill's padding so the pill keeps the design's height. */
.nav-toggle {
  display: none;
  position: relative;
  width: 44px; height: 44px; margin: -4px -4px -4px 0;
  padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--fg);
  cursor: pointer;
  place-items: center;
}
.nav-toggle::before {
  content: ""; position: absolute; inset: 4px;
  border-radius: 50%; border: 1px solid var(--hair-2);
  background: rgba(255, 255, 255, .04);
}
.nav-toggle svg { position: relative; width: 16px; height: 16px; }
.nav-toggle .i-close { display: none; }
.nav-toggle[aria-expanded="true"] .i-open { display: none; }
.nav-toggle[aria-expanded="true"] .i-close { display: inline; }

.nav-menu {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  padding: 8px;
  border-radius: var(--r-card);
  background: rgba(20, 27, 52, .96);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--hair);
}
.nav-menu[hidden] { display: none; }
.nav-menu nav { display: grid; }
.nav-menu a {
  display: flex; align-items: center;
  min-height: 48px; padding: 0 14px;
  border-radius: 14px;
  font-size: 18px; letter-spacing: -.01em; color: var(--fg);
}
.nav-menu a:hover { background: rgba(255, 255, 255, .05); }
.nav-menu .nav-menu-signin { margin-top: 4px; border-top: 1px solid var(--hair); border-radius: 0 0 14px 14px; color: var(--fg-body); }

@media (max-width: 759px) {
  .nav { left: 12px; right: 12px; transform: none; max-width: none; }
  .nav-pill { gap: 10px; padding: 8px 8px 8px 18px; }
  .wordmark { margin-right: auto; }
  .nav-links, .nav-signin { display: none; }
  .nav-toggle { display: inline-grid; }
}
@media (min-width: 760px) {
  .nav-menu { display: none !important; }
}
/* Without the script the menu cannot open, so do not offer it. */
html:not(.js) .nav-toggle { display: none; }

/* ── 01 Hero ──────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  /* minmax(0, 1fr): the strand is 3,000px wide; without this the column
     grows to fit it and the copy centres in a column wider than the screen. */
  grid-template-columns: minmax(0, 1fr);
  padding: 120px 0 48px;
}
/* Four formats in the kicker: on a phone it takes two even lines. */
.hero-copy > .kicker { text-wrap: balance; }
.hero-copy {
  display: grid; align-content: center; gap: 28px;
  width: 100%; max-width: var(--max);
  margin: 0 auto; padding: 0 var(--gutter);
}
.h1 {
  font-weight: 400;
  font-size: clamp(60px, 11vw, 184px);
  line-height: .86;
  letter-spacing: -.055em;
  text-wrap: balance;
}
.h1 .accent { font-weight: 700; color: var(--mint); }
/* "Your content has" is 6.5 times the type size wide: at the 60px floor it
   needs a 391px measure, so below 460px the break moves and the h1 stays
   two lines, "Your content / has a DNA.", at full size. */
.h1 .br-phone { display: none; }
@media (max-width: 459px) {
  .h1 .br-phone { display: inline; }
  .h1 .br-wide { display: none; }
}
.hero-row {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 32px; flex-wrap: wrap;
  container-type: inline-size;
}
.lede {
  max-width: 48ch;
  font-size: clamp(16px, 1.3vw, 19px);
  line-height: 1.55;
  color: var(--fg-body);
  text-wrap: pretty;
}
/* As in the design, the buttons sit flush right while they share a line with
   the lede, and line up with it on the left once the row wraps. The row
   wraps below lede (48ch = 499px at 16px) + gap (32px) + actions column
   (469px, the width of the mono note) = 1000px of row, so the query is on the
   row itself and the gutter does not enter into it. Re-measure if that copy
   or those sizes change. Without container queries the actions stay left. */
.hero-actions { display: grid; gap: 14px; justify-items: start; }
@container (min-width: 1000px) {
  .hero-actions { justify-items: end; }
}
.btns { display: flex; gap: 10px; flex-wrap: wrap; }
.hero-note {
  font-family: var(--mono); font-size: 12px; line-height: 1.5;
  letter-spacing: .02em; color: var(--fg-meta);
}

.hero-strand { min-width: 0; margin-top: 56px; }
.strand-view { position: relative; overflow: hidden; }
.strand {
  display: grid; gap: 4px;
  width: max-content;
  transform: translateX(-40px);
}
.js .strand { will-change: transform; }
.strand .row { display: flex; gap: 4px; height: 22px; }
.strand .row:nth-child(2) { height: 34px; }
.strand .row span { flex: none; width: 18px; border-radius: 3px; }
.strand .row:empty { width: 3076px; --gap: 4px; --n: 140; }
.scan {
  position: absolute; top: -8px; bottom: -8px; left: 50%;
  width: 2px; background: var(--fg);
  animation: adna-scan 1.8s infinite;
}
@keyframes adna-scan { 0%, 100% { opacity: .9; } 50% { opacity: .4; } }
.fade { position: absolute; top: 0; bottom: 0; width: 12%; pointer-events: none; }
.fade-l { left: 0; background: linear-gradient(90deg, var(--ground), rgba(11, 16, 32, 0)); }
.fade-r { right: 0; background: linear-gradient(-90deg, var(--ground), rgba(11, 16, 32, 0)); }
.legend {
  display: flex; justify-content: center; flex-wrap: wrap;
  gap: 8px 28px; margin-top: 18px; padding: 0 var(--gutter);
  font-family: var(--mono); font-size: 11px; line-height: 1.5;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-meta);
}
.legend .key { display: inline-flex; align-items: center; gap: 8px; }
.legend .key::before {
  content: ""; width: 10px; height: 10px; border-radius: 2px; background: var(--c);
}
/* On a phone "· illustrative" would wrap on its own anyway, so it takes a
   centred line of its own and drops the dot. */
@media (max-width: 759px) {
  .legend { font-size: 12px; gap: 8px 20px; }
  .legend-note { flex-basis: 100%; text-align: center; }
  .legend-dot { display: none; }
}

/* ── 02 Manifesto ─────────────────────────────────────────────────────── */
.manifesto { padding: clamp(110px, 14vw, 200px) var(--gutter); }
.manifesto-inner { max-width: 1320px; margin: 0 auto; display: grid; gap: 40px; }
.manifesto-text {
  font-size: clamp(32px, 4.6vw, 72px);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.04em;
  text-wrap: pretty;
}
.manifesto-text strong { color: var(--indigo); font-weight: 700; }
.manifesto-text .w { transition: opacity .2s linear; }
.proof {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px; margin-top: clamp(16px, 4vw, 56px);
}
.proof li {
  display: grid; gap: 12px; align-content: start;
  padding-top: 22px; border-top: 1px solid var(--line-light);
}
.proof-n {
  font-size: clamp(40px, 5vw, 72px); font-weight: 400;
  line-height: 1; letter-spacing: -.04em;
}
.proof-l {
  font-family: var(--mono); font-size: 12px; line-height: 1.5;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-meta);
}
@media (max-width: 639px) {
  .proof { grid-template-columns: 1fr; gap: 20px; }
}

/* ── 03 Two cuts ──────────────────────────────────────────────────────── */
.cuts { display: grid; gap: 16px; }
.cuts figcaption { margin-top: 0; }
.cut {
  display: grid; gap: 24px; align-items: center;
  padding: clamp(18px, 2.4vw, 28px);
  border-radius: var(--r-card);
  background: var(--panel);
  border: 1px solid var(--hair);
}
.cut--a { border-color: rgba(94, 234, 212, .5); }
/* Side by side from 900px: the info column is a quarter of the card, as in
   the design (300px at 1440), but never under the design's 240px floor, so
   the names stay on one line and the stats keep clear of the strand. */
@media (min-width: 900px) {
  .cut { grid-template-columns: max(240px, calc((100% - 72px) / 4)) minmax(0, 1fr); }
}
.cut-info { display: grid; gap: 10px; }
.cut-name {
  display: flex; align-items: center; gap: 10px;
  font-size: 20px; font-weight: 400; line-height: 1.3; letter-spacing: -.02em;
}
.cut-tag {
  font-family: var(--mono); font-size: 12px; line-height: 1.2; letter-spacing: 0;
  padding: 4px 8px; border-radius: var(--r-chip);
  background: var(--teal); color: var(--ink);
}
.cut--b .cut-tag { background: rgba(255, 255, 255, .1); color: var(--fg); }
.cut-stats { display: flex; gap: 24px; }
.cut-stats div { display: flex; flex-direction: column-reverse; }
.cut-stats dd { font-size: 44px; line-height: 1; letter-spacing: -.04em; }
.cut-stats dt {
  margin-top: 4px;
  font-family: var(--mono); font-size: 11px; line-height: 1.4;
  text-transform: uppercase; color: var(--fg-meta);
}
.cut-strand { min-width: 0; }
.cells { display: grid; gap: 3px; }
.cells .row {
  display: grid; grid-template-columns: repeat(30, minmax(0, 1fr)); gap: 3px;
  height: 22px;
}
.cells .row span { border-radius: 3px; }
.axis {
  display: flex; justify-content: space-between; gap: 12px;
  margin-top: 9px;
  font-family: var(--mono); font-size: 11px; line-height: 1.4;
  color: var(--fg-meta);
}
.axis span:nth-child(2) { text-align: center; }
@media (max-width: 759px) {
  .cut-stats dt, .axis { font-size: 12px; }
  .axis { gap: 8px; }
}

/* ── 04 How a readout gets made ───────────────────────────────────────── */
.how { background: var(--band); color: var(--ink); --focus: #4f46e5; --accent: var(--indigo); }
.how-stage { padding: var(--section-y) 0; }
.how-head {
  display: flex; justify-content: space-between; align-items: flex-end; gap: 24px;
  width: 100%; max-width: var(--max);
  margin: 0 auto; padding: 0 var(--gutter);
}
.h2--how { font-size: clamp(40px, 5vw, 80px); line-height: .94; text-wrap: balance; }
.how-count {
  display: none;
  font-family: var(--mono); font-size: 13px; line-height: 1.5;
  color: var(--ink-meta); white-space: nowrap;
}
/* Unpinned (phones, reduced motion, no script): one column under a 620px
   track (from 674px wide), then two — never more, since each track's floor
   is half the row — so a step stays a poster, like the design's
   min(78vw, 520px) cards, rather than a one-line banner. */
.how-track {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, max(300px, calc((100% - 20px) / 2))), 1fr));
  gap: 20px;
  max-width: var(--max);
  margin: 0 auto; padding: 40px var(--gutter) 0;
}
/* Number on top, words at the bottom, and between them the card's drawn
   example, which takes whatever height the card leaves free. */
.step {
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto; gap: 24px;
  min-height: clamp(380px, 46vw, 520px);
  padding: clamp(24px, 3vw, 40px);
  border-radius: var(--r-step);
}
.step-meta {
  display: flex; justify-content: space-between; gap: 16px;
  font-family: var(--mono); font-size: 12px; line-height: 1.5;
  letter-spacing: .1em; text-transform: uppercase; opacity: .8;
}
.step h3 {
  font-weight: 400;
  font-size: clamp(36px, 3.6vw, 56px);
  line-height: .98;
  letter-spacing: -.045em;
  text-wrap: balance;
}
.step-body { max-width: 48ch; font-size: 16px; line-height: 1.55; opacity: .86; text-wrap: pretty; }
.step--import { background: var(--ground); color: var(--fg); }
.step--read { background: var(--read); color: var(--white); }
.step--read .step-body, .step--read .step-meta { opacity: 1; }
.step--label { background: var(--white); color: var(--ink); }
.step--compare { background: var(--teal); color: var(--ink); }

/* The drawn examples. Each is a figure.example whose "Example" caption
   sits under its bottom-right corner, in the card's own quiet ink. Widths
   and heights inside answer to the figure (a container), not the screen. */
.step-viz {
  align-self: center;
  min-width: 0;
  container: viz / inline-size;
}
.step-viz figcaption { margin-top: 12px; text-align: right; letter-spacing: .04em; }
.step--import .step-viz figcaption { color: var(--fg-meta); }
.step--read .step-viz figcaption { color: rgba(255, 255, 255, .92); }
.step--label .step-viz figcaption { color: var(--ink-meta); }
.step--compare .step-viz figcaption { color: rgba(11, 16, 32, .8); }
.viz { display: grid; gap: 14px; }

/* 01 Import: a link field, and four links each sent where it belongs. */
.imp-field {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 7px 7px 16px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .16);
  background: rgba(255, 255, 255, .04);
  font-size: 15px; line-height: 1.3; color: var(--fg-meta);
}
.imp-field svg { flex: none; width: 16px; height: 16px; color: var(--mint); }
.imp-field span:first-of-type { flex: 1; min-width: 0; }
.imp-go {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--mint); color: var(--ink);
}
.imp-go svg { width: 14px; height: 14px; color: currentColor; }
.imp-rows { display: grid; gap: 6px; }
/* The first column is 2ch, the width of the "or" that marks the last row
   (a dot sits in it on the others), so every source starts on one line. */
.imp-rows li {
  display: grid; grid-template-columns: 2ch minmax(0, 1fr) auto;
  align-items: center; gap: 4px 12px;
  padding: 9px 13px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: rgba(255, 255, 255, .06);
  font-family: var(--mono); font-size: 12px; line-height: 1.4;
}
.imp-rows li:not(.imp-alt)::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--dot); }
.imp-src { color: var(--fg); overflow-wrap: anywhere; }
.imp-kind { color: var(--fg-meta); text-align: right; }
/* Pasted copy does not go through the link field: it has a field of its
   own, so its row is an outline, not a fill, after an "or". Every row has
   the same 1px border (clear on the link rows), so it is the same height
   and the shorter forms below shrink it with the rest. */
.imp-rows .imp-alt {
  margin-top: 4px;
  background: transparent;
  border: 1px dashed rgba(255, 255, 255, .34);
}
.imp-or { color: var(--fg-meta); }
@container viz (max-width: 359px) {
  .imp-rows li { grid-template-columns: 2ch minmax(0, 1fr); }
  .imp-kind { grid-column: 2; text-align: left; }
}

/* 02 Read: a small white strand read up to the scan line (cells past it
   are not read yet), and the three ways a piece is read. */
.read-strand { position: relative; }
.cells--16 .row { grid-template-columns: repeat(16, minmax(0, 1fr)); height: 26px; }
.cells--16 .row:empty { --n: 16; }
.viz-read .row:empty { --cell-fill: rgba(255, 255, 255, .42); }
.read-scan {
  position: absolute; top: -8px; bottom: -8px;
  left: 62.5%; width: 2px; margin-left: -1px;
  border-radius: 1px;
  background: var(--white);
}
.read-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.read-chips li {
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .72);
  font-size: 14px; line-height: 1.3;
}

/* 03 Label: Language DNA as one bar, and two timed labels. */
.dna { display: grid; gap: 12px; }
.dna-bar { display: flex; gap: 2px; height: 14px; border-radius: var(--r-pill); overflow: hidden; }
.dna-bar span { flex: var(--w) 1 0; min-width: 4px; background: var(--c); }
.dna-legend {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font-family: var(--mono); font-size: 12px; line-height: 1.4;
  color: var(--ink-meta);
}
.dna-legend span { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.dna-legend span::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--c); }
/* Narrow: the five names in three columns, two lines, never one orphan. */
@container viz (max-width: 400px) {
  .dna-legend { display: grid; grid-template-columns: repeat(3, max-content); column-gap: 16px; }
}
.moments--light .moment { background: #f1f3f9; }
.moments--light .moment-t { color: var(--ink-meta); }

/* 04 Compare: one trait across the high and the low tier. */
.cmp-feature { font-size: 17px; font-weight: 500; line-height: 1.3; letter-spacing: -.015em; }
.cmp-rows { display: grid; gap: 10px; }
/* Both rows lay the same three tracks: the count column is a fixed 8ch
   ("10 of 12" in the mono face), so the High and Low dots line up dot for
   dot. The dots take the width the card gives them, up to 22px each, and
   spread edge to edge past that. */
.cmp-row {
  display: grid; grid-template-columns: 3.4em minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
}
.cmp-k, .cmp-n { font-family: var(--mono); font-size: 12px; line-height: 1.4; }
.cmp-k { letter-spacing: .08em; text-transform: uppercase; }
.cmp-n { width: 8ch; white-space: nowrap; }
.cmp-dots {
  display: grid; grid-template-columns: repeat(12, minmax(0, 22px));
  justify-content: space-between; gap: 4px;
}
.cmp-dots i { aspect-ratio: 1; border-radius: 50%; border: 1.5px solid var(--ink); }
.cmp-dots i.on { background: var(--ink); }
.cmp-result {
  justify-self: start;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 6px;
  border-radius: var(--r-pill);
  background: rgba(11, 16, 32, .08);
  font-family: var(--mono); font-size: 12px; line-height: 1.3;
}
.cmp-mark {
  position: relative; flex: none;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--ink);
}
.cmp-mark::after {
  content: ""; position: absolute; left: 6px; top: 4px;
  width: 4px; height: 8px;
  border: solid var(--mint); border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}

/* Pinned: the stage sticks for the height of the section and the track
   slides left as the reader scrolls through it. Only on wide, tall-enough
   screens, with motion allowed and the script running (it drives the slide). */
@media (min-width: 900px) and (min-height: 560px) and (prefers-reduced-motion: no-preference) {
  .js .how { position: relative; height: 320vh; }
  .js .how-stage {
    position: sticky; top: 0;
    height: 100vh;
    /* clip, not just hidden: a hidden box can still be scrolled sideways by
       find-in-page or a screen reader's scrollIntoView, which would knock
       the heading off and freeze the track. Older engines fall back to
       hidden, and js/landing.js puts any such scroll back. */
    overflow: hidden;
    overflow: clip;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-columns: minmax(0, 1fr);
    padding: clamp(80px, 10vh, 120px) 0 48px;
  }
  .js .how-count { display: block; }
  .js .how-track {
    display: flex; align-items: stretch;
    width: max-content; max-width: none;
    margin: 0;
    will-change: transform;
  }
  .js .step { flex: none; width: min(78vw, 520px); min-height: 0; }
  /* A pinned card is as tall as the screen allows, so its example gets a
     fixed box (the free row) and steps down to a shorter form when the
     screen is short, rather than pushing into the words below it. */
  .js .step-viz {
    align-self: stretch;
    container-type: size;
    display: grid; align-content: center;
  }
}
/* A short screen (most laptops once the browser's own bars are counted)
   gives the pinned cards less height: tighter chrome and type buy the
   example room. */
@media (min-width: 900px) and (min-height: 560px) and (max-height: 820px) and (prefers-reduced-motion: no-preference) {
  .js .how-stage { padding-bottom: 32px; }
  .js .how-track { padding-top: 28px; }
  .js .h2--how { font-size: clamp(36px, min(5vw, 7vh), 80px); }
  .js .step { gap: 18px; padding: clamp(24px, min(3vw, 4.4vh), 40px); }
  .js .step h3 { font-size: clamp(32px, min(3.6vw, 6.2vh), 56px); }
}
/* Shorter forms of each example, by the height its pinned card leaves it.
   Height queries only ever match on the pinned track: everywhere else the
   figure is an inline-size container and takes its natural height. Below
   the last step the example is left out and the card is words only. */
@container viz (max-height: 259px) {
  .viz-import .imp-field { display: none; }
  .imp-rows { gap: 5px; }
  .imp-rows li { padding-top: 7px; padding-bottom: 7px; }
  .imp-rows .imp-alt { margin-top: 0; }
}
@container viz (max-height: 172px) {
  .imp-rows li { padding-top: 5px; padding-bottom: 5px; }
  .step-viz figcaption { margin-top: 8px; }
}
@container viz (max-height: 160px) {
  .imp-rows li { padding-top: 4px; padding-bottom: 4px; }
}
@container viz (max-height: 164px) {
  .cells--16 .row { height: 20px; }
  .viz-label .moment { padding-top: 8px; padding-bottom: 8px; }
  .viz-compare .viz { gap: 10px; }
}
@container viz (max-height: 170px) {
  .viz-label .moment + .moment { display: none; }
}
@container viz (max-height: 144px) {
  .read-chips { display: none; }
}
@container viz (max-height: 150px) {
  .viz-import .viz, .viz-import figcaption { display: none; }
}
@container viz (max-height: 124px) {
  .viz-label .viz, .viz-label figcaption, .viz-compare .viz, .viz-compare figcaption { display: none; }
}
@container viz (max-height: 96px) {
  .viz-read .viz, .viz-read figcaption { display: none; }
}

/* ── 05 The readout ───────────────────────────────────────────────────── */
/* Part A: one panel per format behind a tab row. Without the script there
   is no tab row: the four panels stack, each under its own heading. */
.formats { display: grid; gap: 40px; }
.fmt-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
html:not(.js) .fmt-tabs { display: none; }
.fmt-tab {
  margin: 0; padding: 11px 20px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .14);
  background: transparent;
  font: inherit; font-size: 15px; font-weight: 400; line-height: 1.2;
  color: var(--fg-panel);
  cursor: pointer;
  transition: color .2s, background-color .2s, border-color .2s;
}
.fmt-tab:hover { border-color: var(--mint); color: var(--mint); }
.fmt-tab[aria-selected="true"] { background: var(--mint); border-color: var(--mint); color: var(--ink); font-weight: 500; }
/* Four pills do not fit one phone line; two by two reads as one control. */
@media (max-width: 519px) {
  .fmt-tabs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.fmt-panels { display: grid; gap: 96px; container: fmts / inline-size; }
/* Top-aligned, so every panel starts the same distance under the tabs. Two
   columns once each gets 440px beside the gap (the gap is 5vw there, about
   50px, hence 930px), one column below that. */
.fmt {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: start; align-content: start;
}
@container fmts (min-width: 930px) {
  .fmt { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.fmt-title { font-size: clamp(32px, 3vw, 44px); font-weight: 400; line-height: 1; letter-spacing: -.04em; }
/* With the script, the tab names each panel and its heading is for screen
   readers only. All four panels share one grid cell, so the area is as tall
   as the tallest and a tab change never moves what sits below it. On
   phones, where the panels stack and differ more, only the active one is
   laid out. */
.js .fmt-panels { gap: 0; }
.js .fmt { grid-area: 1 / 1; }
.js .fmt:not(.is-active) { visibility: hidden; }
.js .fmt.is-active { animation: fmt-in .45s var(--ease); }
.js .fmt-title {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@media (max-width: 899px) {
  .js .fmt:not(.is-active) { display: none; }
}
/* Stacked, the drawn example comes first, straight under the tabs, so a tap
   on a tab changes what is on screen; the list and the scores follow as its
   key. The figure holds nothing focusable, so focus order is unchanged.
   Without the script each panel keeps its heading on top. */
@container fmts (max-width: 929.98px) {
  .js .fmt-figure { order: -1; }
}
@keyframes fmt-in { from { opacity: 0; transform: translateY(10px); } }

.fmt-copy { display: grid; gap: 28px; align-content: start; }
.fmt-from { display: grid; gap: 8px; }
.fmt-k {
  font-family: var(--mono); font-size: 12px; line-height: 1.5;
  letter-spacing: .12em; text-transform: uppercase; color: var(--fg-meta);
}
.fmt-v { font-family: var(--mono); font-size: 13px; line-height: 1.6; color: var(--fg-panel); text-wrap: pretty; }
.fmt-scores { display: grid; gap: 12px; }
.spec-list { border-top: 1px solid var(--hair-2); }
.spec-list div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 13px 0; border-bottom: 1px solid var(--hair-2);
}
.spec-list dt { font-size: 17px; line-height: 1.4; color: var(--fg); }
.spec-list dd {
  font-family: var(--mono); font-size: 12px; line-height: 1.4;
  color: var(--fg-meta); white-space: nowrap; text-align: right;
}

/* The example readout panel, one per format. */
.fmt-panel {
  display: grid; gap: 20px;
  padding: clamp(20px, 2.4vw, 32px);
  border-radius: var(--r-card);
  background: var(--panel);
  border: 1px solid var(--hair);
  container: panel / inline-size;
  --dna-facts: #3987e5;
  --dna-fun: #d95926;
  --dna-feeling: #d55181;
  --dna-opinion: #9085e9;
  --dna-action: #e66767;
}
.panel-top {
  display: flex; justify-content: space-between; gap: 12px;
  font-family: var(--mono); font-size: 12px; line-height: 1.5;
  color: var(--fg-meta);
}
.panel-top span:first-child { overflow-wrap: anywhere; }
.panel-top .ok { color: var(--mint); }
.enc { display: grid; gap: 10px; }
.enc-label {
  display: flex; justify-content: space-between; gap: 12px;
  font-family: var(--mono); font-size: 11px; line-height: 1.4;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-meta);
}
.enc-label span:first-child { text-wrap: balance; }
.enc-label span + span { letter-spacing: .02em; text-transform: none; white-space: nowrap; }
.cells--20 .row { grid-template-columns: repeat(20, minmax(0, 1fr)); height: 26px; }
.cells--20 .row span { border-radius: 4px; }
.cells--20 .row:empty { --n: 20; }
.moments { display: grid; gap: 8px; }
.moment {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: 12px; align-items: center;
  padding: 11px 14px; border-radius: 14px;
  background: rgba(255, 255, 255, .04);
  font-size: 14px; line-height: 1.4;
}
.moment-t { font-family: var(--mono); color: var(--fg-meta); }
.moment .tag, .verdict-k {
  font-family: var(--mono); font-size: 12px; line-height: 1.2;
}
.moment .tag {
  padding: 4px 8px; border-radius: var(--r-chip);
  background: var(--tag); color: var(--ink);
}

/* Score bars: name and value on one line, a thin bar under them. */
.bars { display: grid; gap: 14px; }
/* Four bars show two by two, or in one column in a narrow panel, never
   three and a lone fourth. Under 360px a column could no longer hold
   "Share-worthiness" and its value on one line. */
.bars--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 28px; }
@container panel (max-width: 359px) {
  .bars--2 { grid-template-columns: minmax(0, 1fr); }
}
.bars li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline; gap: 7px 12px;
}
.bar-k { font-size: 14px; line-height: 1.3; color: var(--fg-panel); }
.bar-v { font-family: var(--mono); font-size: 12px; line-height: 1.3; color: var(--fg-meta); }
.bar {
  position: relative; grid-column: 1 / -1;
  height: 6px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .08);
  overflow: hidden;
}
.bar::before {
  content: ""; position: absolute; inset: 0 auto 0 0;
  width: calc(var(--v) * 10%);
  border-radius: inherit;
  background: var(--mint);
}

/* A drawn example beside its notes (image ad, landing page); stacked once
   the panel is narrow. */
.fmt-split {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 24px; align-items: center;
}
.fmt-side { display: grid; gap: 20px; align-content: center; }
@container panel (max-width: 379px) {
  .fmt-split { grid-template-columns: minmax(0, 1fr); }
  .ad-frame, .browser { width: min(100%, 240px); }
}
.callouts { display: grid; gap: 8px; }
.callouts li {
  display: grid; grid-template-columns: 12px minmax(0, 1fr);
  gap: 10px; align-items: start;
  padding: 10px 12px; border-radius: 12px;
  background: rgba(255, 255, 255, .04);
  font-size: 14px; line-height: 1.4; color: var(--fg);
  text-wrap: pretty;
}
.callouts li::before {
  content: ""; width: 12px; height: 12px; margin-top: 2px;
  border-radius: 3px; border: 1.5px dashed var(--mk);
}

/* Image ad: a 4:5 static ad, drawn. Type inside scales with the frame. */
.ad-frame {
  position: relative; display: block;
  aspect-ratio: 4 / 5;
  border-radius: 16px; overflow: hidden;
  background:
    radial-gradient(120% 80% at 85% 100%, rgba(20, 184, 166, .9), rgba(20, 184, 166, 0) 60%),
    linear-gradient(155deg, #a855f7 0%, #6366f1 62%, #4f46e5 100%);
  container-type: inline-size;
}
.ad-head {
  position: absolute; left: 9%; top: 8%; right: 22%;
  font-size: 20px; font-size: 12.5cqi; font-weight: 700;
  line-height: .95; letter-spacing: -.045em; color: var(--white);
  outline: 1.5px dashed var(--mint); outline-offset: 5px; border-radius: 3px;
}
.ad-product {
  position: absolute; right: 10%; bottom: 25%;
  width: 46%; aspect-ratio: 1;
  border-radius: 30%;
  background: rgba(255, 255, 255, .16);
  border: 1px solid rgba(255, 255, 255, .4);
  transform: rotate(-12deg);
}
.ad-product span {
  position: absolute; inset: 22%;
  border-radius: 50%;
  background: linear-gradient(160deg, #eceff7, #c9cfe0);
  box-shadow: 0 10px 24px rgba(11, 16, 32, .35);
}
.ad-cta {
  position: absolute; left: 9%; bottom: 8%;
  padding: 7px 14px; padding: 3cqi 6cqi;
  border-radius: var(--r-pill);
  background: var(--white); color: var(--ink);
  font-size: 13px; font-size: 6.5cqi; font-weight: 500; line-height: 1.1;
  outline: 1.5px dashed #a5b4fc; outline-offset: 4px;
}

/* Landing page: one desktop capture (1280 by 1600, so 4:5), with the fold. */
.browser {
  display: grid; grid-template-columns: minmax(0, 1fr);
  border-radius: 14px; overflow: hidden;
  border: 1px solid var(--hair-2);
  background: #0f1529;
  container: browser / inline-size;
}
.browser-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--hair);
}
.browser-dots { display: flex; gap: 4px; }
.browser-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--ch-visual); }
.browser-dots i:nth-child(2) { background: var(--ch-language); }
.browser-dots i:nth-child(3) { background: var(--ch-auditory); }
.browser-url {
  flex: 1; min-width: 0;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .06);
  font-family: var(--mono); font-size: 11px; line-height: 1.4;
  color: var(--fg-panel);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@container browser (max-width: 219px) {
  .browser-bar { gap: 6px; padding: 7px 8px; }
  .browser-dots i { width: 6px; height: 6px; }
  .browser-url { padding: 2px 7px; }
}
.page {
  position: relative; display: block;
  aspect-ratio: 4 / 5;
  background: var(--band);
  container-type: inline-size;
}
.page i { display: block; }
.pg-nav { position: absolute; left: 7%; right: 7%; top: 5%; display: flex; gap: 5%; align-items: center; }
.pg-nav i { height: 4cqi; width: 12%; border-radius: 2px; background: #c9cfe0; }
.pg-nav i:first-child { width: 22%; margin-right: auto; background: var(--ink); }
.pg-hero { position: absolute; left: 7%; right: 7%; top: 15%; display: grid; grid-template-columns: 1.15fr 1fr; gap: 6%; align-items: center; }
.pg-copy { display: grid; gap: 3.2cqi; justify-items: start; }
.pg-h { width: 100%; height: 6cqi; border-radius: 3px; background: var(--ink); }
.pg-h--short { width: 70%; }
.pg-sub { width: 88%; height: 3cqi; border-radius: 2px; background: #b9c0d4; margin-top: 1cqi; }
.pg-cta { width: 52%; height: 8cqi; border-radius: 999px; background: var(--indigo); margin-top: 2cqi; }
.pg-img { display: block; aspect-ratio: 5 / 4; border-radius: 10%; background: linear-gradient(150deg, #c084fc, #a5b4fc); }
.pg-fold {
  position: absolute; left: 0; right: 0; top: 54%;
  border-top: 1.5px dashed var(--indigo);
}
.pg-fold span {
  position: absolute; right: 5%; bottom: 4px;
  font-family: var(--mono); font-size: 11px; line-height: 1;
  color: var(--ink-meta);
}
.pg-below { position: absolute; left: 7%; right: 7%; top: 61%; display: grid; gap: 3.4cqi; opacity: .55; }
.pg-below i { height: 3cqi; border-radius: 2px; background: #b9c0d4; }
.pg-below i:nth-child(2) { width: 82%; }
.pg-below i:nth-child(3) { width: 64%; }
.pg-below .pg-form { height: 15cqi; width: 70%; margin-top: 2cqi; border-radius: 6px; background: transparent; border: 1.5px solid #9aa2bb; }

/* Copy: the caption, each phrase marked with its Language DNA style. A
   tint of the style colour on the panel leaves Feeling, Action and Fun (and
   Facts and Opinionated) the same plum or navy, so the fill is neutral and
   the full-strength colour carries the code, as a 3px line under the
   phrase and as the swatch on a small tag after it. The tag names the style
   in words, so nothing rests on colour alone (WCAG 1.4.1): it reads the same
   to a colour-blind reader, in forced colours and to a screen reader. The
   tag is an inline box with no space before it, so it never wraps away from
   its phrase onto a line of its own. */
.copy-text {
  font-size: clamp(17px, 1.35vw, 19px); line-height: 1.85; letter-spacing: -.01em;
  color: var(--fg);
  text-wrap: pretty;
}
.copy-text mark {
  padding: 1px 2px; border-radius: 3px;
  color: inherit;
  background: rgba(255, 255, 255, .06);
  box-shadow: inset 0 -3px 0 var(--c);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.dna-tag {
  margin-left: 6px;
  padding: 2px 6px 2px 5px;
  border-radius: 4px;
  border-left: 7px solid var(--c);
  background: rgba(255, 255, 255, .05);
  font-family: var(--mono); font-size: 11px; line-height: 1;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-panel);
  white-space: nowrap;
  vertical-align: 2px;
}
.fmt-panel .dna-legend { color: var(--fg-panel); }
/* Five legend keys show only as one row, 3 + 2, or one column: never a
   lone key on its own line. The side column is a container of its own,
   because the panel's container measures the whole panel. */
.fmt-side { container: side / inline-size; }
@container panel (min-width: 340px) and (max-width: 519px) {
  .fmt-panel .dna-legend { display: grid; grid-template-columns: repeat(3, max-content); column-gap: 14px; }
}
@container side (min-width: 270px) { .fmt-side .dna-legend { display: flex; } }
@container side (min-width: 340px) and (max-width: 499px) {
  .fmt-side .dna-legend { display: grid; grid-template-columns: repeat(3, max-content); column-gap: 14px; }
}
@container side (max-width: 269px) {
  .fmt-side .dna-legend { display: grid; grid-template-columns: max-content; }
}
/* The compact read in the image and page panels: a label row, the bar,
   and the legend with its shares. */
.dna--panel { gap: 10px; }
.dna--panel .dna-bar { height: 10px; }
.verdict {
  display: grid; gap: 6px;
  padding: 14px 16px; border-radius: 14px;
  background: rgba(255, 255, 255, .04);
  font-size: 15px; line-height: 1.45; color: var(--fg);
}
.verdict-k { letter-spacing: .1em; text-transform: uppercase; color: var(--lilac); }

/* Part B: what a team does with the readouts. */
.flow-block { display: grid; gap: 28px; margin-top: clamp(24px, 4vw, 56px); }
.flow {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 32px clamp(24px, 3vw, 48px);
}
@media (min-width: 640px) { .flow { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .flow { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.flow li {
  display: grid; gap: 12px; align-content: start;
  padding-top: 20px; border-top: 1px solid var(--hair-2);
}
.flow-n { font-family: var(--mono); font-size: 13px; line-height: 1.5; color: var(--fg-meta); }
.flow h4 { font-size: 24px; font-weight: 500; line-height: 1.15; letter-spacing: -.02em; }
.flow p { font-size: 16px; line-height: 1.55; color: var(--fg-body); text-wrap: pretty; }

@media (max-width: 759px) {
  .moment { grid-template-columns: 44px minmax(0, 1fr) auto; gap: 10px; font-size: 16px; }
  .moment-t { font-size: 13px; }
  .spec-list dt { font-size: 16px; }
  .enc-label, .browser-url, .pg-fold span { font-size: 12px; }
  .bar-k, .callouts li { font-size: 15px; }
}

/* ── 06 Method ────────────────────────────────────────────────────────── */
/* Three cards, never two and an orphan: one column on phones, three once
   each card gets 300px (a 932px grid, from 1013px), and in between two
   columns with the third card spanning both, its sketch beside its words. */
.method-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
@media (min-width: 670px) and (max-width: 1012px) {
  .method-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .method-card:last-child:nth-child(3) {
    grid-column: 1 / -1;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: 28px;
  }
  .method-card:last-child:nth-child(3) .method-viz { grid-row: 1 / span 3; align-self: center; margin-bottom: 0; }
}
@media (min-width: 1013px) {
  .method-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.method-card {
  display: grid; grid-template-rows: auto auto auto 1fr; gap: 14px;
  padding: 28px;
  border-radius: var(--r-card);
  background: var(--white);
  border: 1px solid var(--line-light);
}
.method-viz { width: 100%; max-width: 320px; height: auto; margin-bottom: 6px; }
.method-stat {
  font-family: var(--mono); font-size: 12px; line-height: 1.5; color: var(--ink-meta);
}
/* An interval or a sample size wraps as a whole, never as "48–" over "85%"
   or "n 12 vs" over "12". */
.method-stat .nb { white-space: nowrap; }
.method-card h3 {
  margin-top: 10px;
  font-size: clamp(24px, 2vw, 28px); font-weight: 500;
  line-height: 1.1; letter-spacing: -.02em;
}
.method-card p:last-child { font-size: 16px; line-height: 1.55; color: var(--ink-body); text-wrap: pretty; }

/* ── 07 Who it's for ──────────────────────────────────────────────────── */
.uses { border-top: 1px solid var(--hair-2); }
.use-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 24px; align-items: start;
  padding: clamp(28px, 3.4vw, 44px) 0;
  border-bottom: 1px solid var(--hair-2);
}
/* min-width 0 and overflow-wrap: with a reader's own wider letter and word
   spacing (WCAG 1.4.12), a lit "Researchers" no longer fits its cell and
   would run into the line beside it; this lets it break inside the cell
   instead. No hyphens: auto: browsers with an English dictionary (Safari,
   Firefox, Chrome on Mac and Android) would set "Creative agen- / cies" at
   normal spacing, which the headless Chromium in tests cannot show. */
.use-who { display: flex; align-items: baseline; gap: 18px; min-width: 0; }
.use-n { font-family: var(--mono); font-size: 13px; color: var(--fg-meta); }
.use-row h3 {
  min-width: 0;
  overflow-wrap: break-word;
  font-weight: 400;
  font-size: clamp(34px, 4.4vw, 68px);
  line-height: 1; letter-spacing: -.045em;
  color: var(--fg);
  transition: color .3s;
}
.use-row:hover h3, .use-row:focus-within h3, .use-row.is-active h3 {
  color: var(--mint); font-weight: 700;
}
.use-row > p {
  max-width: 40ch;
  font-size: 18px; line-height: 1.5; color: var(--fg-panel);
  text-wrap: pretty;
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips li {
  padding: 8px 12px; border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .14);
  font-size: 13px; line-height: 1.3; color: var(--fg-panel);
}

/* ── 08 Imports ───────────────────────────────────────────────────────── */
.imports-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr));
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.imports-copy { display: grid; gap: 22px; }
.h2--imports { font-size: clamp(44px, 5.4vw, 88px); }
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
}
.tiles li {
  display: grid; gap: 4px; align-content: start;
  padding: 16px;
  border-radius: var(--r-tile);
  background: var(--white);
  border: 1px solid var(--line-light);
}
.tile-name { font-weight: 500; line-height: 1.25; }
.tile-kind { font-family: var(--mono); font-size: 11px; line-height: 1.4; color: var(--ink-meta); }
.log-panel {
  border-radius: var(--r-card);
  background: var(--ground);
  color: #d6dbea;
  overflow: hidden;
}
.log-dots {
  display: flex; gap: 6px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--hair);
}
.log-dots span { width: 10px; height: 10px; border-radius: 50%; background: var(--ch-visual); }
.log-dots span:nth-child(2) { background: var(--ch-language); }
.log-dots span:nth-child(3) { background: var(--ch-auditory); }
/* The log is rows, not a <pre>: keyword, source, result. On a phone the
   result drops under its source instead of running off the panel. */
.log {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px;
  padding: 24px 22px;
  font-family: var(--mono); font-size: 13px; line-height: 1.7;
}
.log-row { display: grid; grid-template-columns: 8ch minmax(0, 1fr) auto; column-gap: 2ch; }
.log b { font-weight: 400; color: var(--mint); }
.log-out { color: var(--fg-body); text-align: right; }
.log-step span:first-child { padding-left: 2ch; white-space: nowrap; }
.log-step span:last-child { grid-column: 2 / -1; }
@media (max-width: 759px) {
  .tile-kind { font-size: 12px; }
  .log { font-size: 12px; padding: 20px 18px; }
}
@media (max-width: 479px) {
  .log { gap: 8px; line-height: 1.5; }
  .log-row { grid-template-columns: 8ch minmax(0, 1fr); }
  .log-out { grid-column: 2; text-align: left; }
}

/* ── 09 FAQ ───────────────────────────────────────────────────────────── */
.faq-inner { max-width: 1000px; margin: 0 auto; display: grid; gap: 40px; }
.qa-list { display: grid; gap: 8px; }
.qa { border-radius: var(--r-row); transition: background-color .3s; }
.qa[open] { background: var(--panel); }
.qa summary {
  display: flex; justify-content: space-between; align-items: center; gap: 20px;
  padding: 22px 24px;
  border-radius: var(--r-row);
  font-size: 20px; line-height: 1.3; letter-spacing: -.02em;
  cursor: pointer;
  list-style: none;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary:hover { color: var(--mint); }
.qa-icon {
  flex: none;
  display: grid; place-items: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--fg); color: var(--ink);
  font-family: var(--mono); font-size: 20px; line-height: 1;
  transition: background-color .3s;
}
.qa-icon::before { content: "+"; }
.qa[open] .qa-icon { background: var(--mint); }
.qa[open] .qa-icon::before { content: "\2212"; }
.qa-a {
  max-width: 64ch;
  padding: 0 24px 24px;
  font-size: 16px; line-height: 1.6; color: var(--fg-panel);
  text-wrap: pretty;
}
@media (max-width: 759px) {
  .qa summary { padding: 20px; font-size: 19px; }
  .qa-a { padding: 0 20px 22px; }
}

/* ── 10 Access band and footer ────────────────────────────────────────
   One indigo band in two boxes: the access section (inside <main>) and the
   site footer (outside it, so it stays the page's contentinfo). */
.access { padding: 0 var(--band-edge); }
.band {
  display: grid; gap: clamp(64px, 8vw, 120px);
  padding: clamp(80px, 12vw, 180px) var(--gutter) clamp(80px, 10vw, 140px);
  border-radius: var(--r-band) var(--r-band) 0 0;
  background: var(--cta-band);
  color: var(--white);
  --focus: var(--white);
}
.band-top { width: 100%; max-width: var(--max); margin: 0 auto; display: grid; gap: 36px; }
.h2--cta {
  font-size: clamp(56px, 10vw, 168px);
  line-height: .86; letter-spacing: -.055em;
}
.h2--cta .accent { color: var(--white); }
.band-row {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 24px 40px; flex-wrap: wrap;
  container-type: inline-size;
}
.band-lede { max-width: 46ch; font-size: 18px; line-height: 1.5; text-wrap: pretty; }
/* Flush right only while the row is one line: lede (46ch = 537px at 18px) +
   gap (40px) + actions (241px, the sign-in line) = 818px of row. Re-measure
   if that copy or those sizes change. */
.band-actions { display: grid; gap: 14px; justify-items: start; }
@container (min-width: 818px) {
  .band-actions { justify-items: end; }
}
.btn-navy {
  padding: 18px 30px; font-size: 16px;
  background: var(--ground); color: var(--white);
}
.btn-navy:hover { background: var(--white); color: var(--ink); }
.band-signin { font-size: 15px; line-height: 1.5; }
.band-signin a, .footer-links a { text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .45); text-underline-offset: 3px; }
.band a:not(.btn):hover, .site-footer a:hover { color: var(--white); text-decoration-color: var(--white); }
/* A numbered sequence: one column on phones, all three side by side from
   720px (199px columns at 720), never 01 02 over a lone 03. */
.band-cols {
  width: 100%; max-width: var(--max); margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 32px clamp(24px, 3vw, 48px);
}
@media (min-width: 720px) {
  .band-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.band-cols li {
  display: grid; gap: 12px; align-content: start;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, .3);
}
.band-n { font-family: var(--mono); font-size: 13px; line-height: 1.5; }
.band-cols h3 { font-size: 24px; font-weight: 500; line-height: 1.15; letter-spacing: -.02em; }
.band-cols p { font-size: 16px; line-height: 1.55; text-wrap: pretty; }

.site-footer {
  margin: 0 var(--band-edge) var(--band-edge);
  padding: 0 var(--gutter) 32px;
  border-radius: 0 0 var(--r-band) var(--r-band);
  background: var(--cta-band);
  color: var(--white);
  --focus: var(--white);
}
.footer-inner {
  max-width: var(--max); margin: 0 auto;
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px 20px; flex-wrap: wrap;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, .3);
  font-size: 13px; line-height: 1.5;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 4px 24px; }
.footer-links a { display: inline-block; padding: 4px 0; text-decoration: none; }

@media (max-width: 759px) {
  .footer-links { gap: 4px 20px; }
}

/* ── Motion ───────────────────────────────────────────────────────────── */
/* Reveal: the script marks only what starts below the fold, so nothing in
   the first screen is ever hidden. */
.js [data-reveal] {
  transition: opacity 1s var(--ease) var(--reveal-delay, 0ms),
              transform 1.1s var(--ease) var(--reveal-delay, 0ms);
}
.js [data-reveal].is-pending { opacity: 0; transform: translateY(32px); }

/* Play: a card's example runs once when the card comes into view (on the
   pinned track, when it slides in). The script marks it idle first; with no
   script, or with reduced motion, it is simply drawn at rest. */
/* Transitions run only on the way out of idle: going idle is instant, so a
   card is never caught half-way back to its start. */
.viz-import:not(.is-idle) :is(.imp-field, .imp-rows li) {
  transition: opacity .6s var(--ease) calc(var(--i, 0) * 130ms + 260ms),
              transform .7s var(--ease) calc(var(--i, 0) * 130ms + 260ms);
}
.imp-field { --i: -1.5; }
.js .viz-import.is-idle .imp-field { opacity: 0; }
.js .viz-import.is-idle .imp-rows li { opacity: 0; transform: translateX(-18px); }
/* The scan sweeps from the first second to "now" (62.5%, ten of sixteen);
   each column lights as the line passes it. The column index (--c) is set
   by the script that draws the cells. */
.viz-read:not(.is-idle) .read-scan { transition: left 1.5s linear .3s, opacity .3s .3s; }
.viz-read:not(.is-idle) .row span { transition: opacity .3s linear calc(var(--c, 0) * 150ms + 300ms); }
.js .viz-read.is-idle .read-scan { left: 0; opacity: .6; }
.js .viz-read.is-idle .row span:nth-child(-n+10) { opacity: .25; }

@media (prefers-reduced-motion: reduce) {
  .scan { animation: none; opacity: .7; }
  .js [data-reveal] { transition: none; }
  .js [data-reveal].is-pending { opacity: 1; transform: none; }
  .qa, .qa-icon, .use-row h3, .manifesto-text .w, .fmt-tab,
  .viz-import:not(.is-idle) :is(.imp-field, .imp-rows li),
  .viz-read:not(.is-idle) :is(.read-scan, .row span) { transition: none; }
  .js .viz-import.is-idle .imp-field, .js .viz-import.is-idle .imp-rows li,
  .js .viz-read.is-idle .row span { opacity: 1; transform: none; }
  .js .viz-read.is-idle .read-scan { left: 62.5%; opacity: 1; }
  .js .fmt.is-active { animation: none; }
}

/* ── Print ────────────────────────────────────────────────────────────── */
@media print {
  .nav, .skip-link, .scan, .fade, .how-count { display: none !important; }
  * { color: #0b1020 !important; }
  body, .band-dark, .band-light, .how, .band, .site-footer, .step, .cut,
  .fmt-panel, .log-panel, .qa[open], .method-card, .tiles li {
    background: #fff !important;
    border-color: #d7dbe8 !important;
  }
  .step, .cut, .fmt-panel, .log-panel { border: 1px solid #d7dbe8 !important; }
  /* Filled buttons print as outlined ones, or the dark label would sit on a
     dark pill when background graphics are on. */
  .btn-primary, .btn-navy { background: #fff !important; border: 1px solid #0b1020 !important; }
  .btn { break-inside: avoid; }
  /* An !important rule beats the script's inline dimming of unlit words. */
  .manifesto-text .w { opacity: 1 !important; }
  .js [data-reveal].is-pending { opacity: 1 !important; transform: none !important; }
  .strand { transform: translateX(-40px) !important; }
  .js .how { height: auto !important; }
  .js .how-stage { position: static !important; height: auto !important; overflow: visible !important; display: block !important; }
  .js .how-track { display: grid !important; width: auto !important; transform: none !important; }
  .js .step { width: auto !important; }
  .js .step-viz { container-type: inline-size !important; }
  /* Every format prints, each under its own heading; the tab row does not. */
  .fmt-tabs { display: none !important; }
  .js .fmt-panels { gap: 48px !important; }
  .js .fmt { grid-area: auto !important; display: grid !important; visibility: visible !important; animation: none !important; }
  .js .fmt-title { position: static !important; width: auto !important; height: auto !important; margin: 0 !important; clip: auto !important; overflow: visible !important; white-space: normal !important; }
  /* Each heading prints on top, so the example goes back under its list. */
  .js .fmt-figure { order: 0 !important; }
  .js .viz-import.is-idle .imp-field, .js .viz-import.is-idle .imp-rows li, .js .viz-read.is-idle .row span { opacity: 1 !important; transform: none !important; }
  .js .viz-read.is-idle .read-scan { left: 62.5% !important; }
  .hero { min-height: 0; }
  /* The drawings are drawn in backgrounds, which a browser leaves out of a
     print by default ("Background graphics" off): the High and Low dots
     would all print empty beside "10 of 12" and "3 of 12", and the strands,
     bars and swatches would be blank. The image ad would lose its frame,
     its gradient and its product, leaving a headline, a shadowed circle and
     an outlined button on white. These marks print as drawn. */
  .cmp-dots i.on, .cells .row span, .strand .row span, .row:empty, .dna-bar span,
  .dna-legend span::before, .dna-tag, .copy-text mark, .bar, .bar::before, .read-scan,
  .imp-rows li::before, .legend .key::before, .moment .tag, .cut-tag,
  .browser-dots i, .page, .page i, .pg-img,
  .ad-frame, .ad-product, .ad-product > span, .ad-cta {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  /* On paper the cards are white, so the marks drawn in white (the READ
     card's strand and scan line) and the bars' faint track take ink. */
  .viz-read .row span { background: rgba(147, 51, 234, var(--a, .4)) !important; }
  .viz-read .row:empty { --cell-fill: rgba(147, 51, 234, .42); }
  .read-scan { background: #0b1020 !important; }
  .bar { background: #e3e6f0 !important; }
  .bar::before { background: #14b8a6 !important; }
}

/* ── Forced colours (Windows high contrast) ─────────────────────────────
   The system palette replaces every background, so a mark drawn as one
   vanishes: the selected tab is left with only its weight, the High and
   Low dots all draw empty, the strands and DNA bars disappear. The
   selected tab takes the system highlight, the dots and bars draw in the
   text colour, and the drawings keep their own colours (each sits on the
   system canvas, dark or light, and stays visible on either). */
@media (forced-colors: active) {
  .fmt-tab[aria-selected="true"] {
    forced-color-adjust: none;
    background: Highlight; color: HighlightText; border-color: Highlight;
  }
  .cmp-dots i { border-color: CanvasText; }
  .cmp-dots i.on { forced-color-adjust: none; background: CanvasText; border-color: CanvasText; }
  .cells .row span, .strand .row span, .dna-bar span, .dna-legend span::before,
  .imp-rows li::before, .legend .key::before, .ad-frame, .browser {
    forced-color-adjust: none;
  }
  /* The READ card's strand is white at varying strength: in the text
     colour instead, at the same strengths, with the scan line. */
  .viz-read .row span {
    forced-color-adjust: none;
    background: color-mix(in srgb, CanvasText calc(var(--a, .4) * 100%), Canvas) !important;
  }
  .read-scan { forced-color-adjust: none; background: CanvasText; }
  .bar { border: 1px solid CanvasText; }
  .bar::before { forced-color-adjust: none; background: CanvasText; }
  .step, .fmt-panel, .log-panel { border: 1px solid CanvasText; }
}
