/* ═══════════════════════════════════════════════════════════════════════
   MOONDONUT — landing
   Plain CSS, no framework, no build step, no third-party origins.

   ART DIRECTION: this page commits to ONE environment — near-black through
   aubergine, warm cream type, gold used sparingly enough to stay precious.
   The application supports light and dark; the marketing page does not, on
   purpose: a single committed art direction beats two adequate ones, and
   every composition here is drawn for this ground.

   The token names and the base values come from the app's src/tokens.css
   (FROZEN 2026-08-20) and are COPIED, not imported — separate repo, separate
   Pages project. A token change is two edits; nothing keeps them in step.
   The extensions below (depth ramp, type scale, spacing rhythm, easings)
   belong to the landing only.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── faces ───────────────────────────────────────────────────────────── */

@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400;font-display:swap;
  src:url(assets/fonts/source-serif-4-latin-400.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:600;font-display:swap;
  src:url(assets/fonts/source-serif-4-latin-600.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400;font-display:swap;
  src:url(assets/fonts/source-serif-4-latin-ext-400.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:600;font-display:swap;
  src:url(assets/fonts/source-serif-4-latin-ext-600.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;src:url(assets/fonts/inter-latin-400.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* Inter 500 is declared but no rule on the site asks for it; the file stays
   because ogcard.html uses it for the wordmark. Measured with fonttest.js:
   of 11 font files on disk the browser requests 5. */
@font-face{font-family:"Inter";font-style:normal;font-weight:500;font-display:swap;src:url(assets/fonts/inter-latin-500.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";font-style:normal;font-weight:600;font-display:swap;src:url(assets/fonts/inter-latin-600.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;src:url(assets/fonts/inter-latin-ext-400.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Inter";font-style:normal;font-weight:600;font-display:swap;src:url(assets/fonts/inter-latin-ext-600.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;src:url(assets/fonts/jetbrains-mono-latin-400.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;src:url(assets/fonts/jetbrains-mono-latin-ext-400.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* ── tokens ──────────────────────────────────────────────────────────── */

:root{
  color-scheme:dark;

  /* depth ramp — five steps of one hue, not one flat purple */
  --ink-0:#08070c;
  --ink-1:#0d0b13;
  --ink-2:#12101c;
  --ink-3:#181425;
  --ink-4:#221c33;

  --cream:#f4f1ea;
  --warm:#b4aea3;
  --dim:#8b857b;
  /* --faint is used at 11px on the darkest ground; measured on the painted
     background, #645f70 came in at 3.2:1. Lifted until every label clears
     4.5:1 as normal-size text. */
  --faint:#8a8399;

  --gold:#e8c46e;
  --gold-2:#f3d78f;
  --gold-deep:#d4ad4a;
  --violet:#a99cf2;
  --violet-2:#7d6de0;

  --line:rgba(255,255,255,.07);
  --line-2:rgba(255,255,255,.13);
  --line-3:rgba(255,255,255,.22);

  --panel:rgba(24,20,37,.66);
  --panel-2:rgba(34,28,51,.58);

  --font-ui:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --font-serif:"Source Serif 4",Charter,"Iowan Old Style",Georgia,serif;

  /* type scale */
  --t-display:clamp(2.55rem,1.15rem + 5.1vw,5.25rem);
  --t-h2:clamp(1.95rem,1.2rem + 2.5vw,3.35rem);
  --t-big:clamp(1.3rem,1.08rem + .85vw,1.7rem);
  --t-lede:clamp(1.05rem,.98rem + .42vw,1.26rem);
  --t-body:1.0625rem;
  --t-small:.9375rem;
  --t-mono:.8125rem;
  --t-micro:.6875rem;

  /* spacing rhythm — 4-based, tiered by hierarchy */
  --s1:4px;  --s2:8px;  --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:72px; --s9:112px; --s10:160px;

  --gutter:clamp(20px,4vw,48px);
  --shell:76rem;
  --measure:33rem;
  --radius:3px;
  --radius-lg:6px;

  /* motion — distance-matched, never one duration for everything */
  --e-out:cubic-bezier(.22,.68,.28,1);
  --e-soft:cubic-bezier(.32,.72,.3,1);
  --d-fast:140ms;
  --d:260ms;
  --d-slow:520ms;
}

/* ── reset ───────────────────────────────────────────────────────────── */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip;scroll-padding-top:5rem}
body{
  margin:0;
  background:var(--ink-0);
  color:var(--cream);
  font-family:var(--font-ui);
  font-size:var(--t-body);
  line-height:1.6;
  font-feature-settings:"kern","liga","calt";
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:clip;
}
/* height:auto matters: without it an <img> keeps the HTML height attribute
   while CSS sets the width, which distorts the box and — with object-fit —
   silently magnifies the picture. The width/height attributes stay for CLS. */
img,svg,video{display:block;max-width:100%;height:auto}
h1,h2,p,ul,figure,pre{margin:0}
ul{padding:0;list-style:none}

::selection{background:rgba(169,156,242,.3);color:var(--cream)}

.skip{
  position:absolute;left:var(--s4);top:-100px;z-index:100;
  background:var(--gold);color:var(--ink-0);font-weight:600;
  padding:var(--s3) var(--s5);border-radius:var(--radius);
  text-decoration:none;transition:top var(--d) var(--e-out);
}
.skip:focus-visible{top:var(--s4)}

.shell{width:min(100% - var(--gutter)*2,var(--shell));margin-inline:auto}
/* Lucide, drawn at the app's own weight: 1.5 at 14px reads the same as
   the app's 2-at-24 once scaled. */
.sprite{position:absolute;width:0;height:0}
.ic{
  width:14px;height:14px;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.75;
  stroke-linecap:round;stroke-linejoin:round;
}
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* ── atmosphere ──────────────────────────────────────────────────────── */

.atmosphere{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
.field{position:absolute;border-radius:50%;filter:blur(20px)}
.field-violet{
  width:120vmax;height:90vmax;left:-30vmax;top:-46vmax;
  background:radial-gradient(closest-side,rgba(107,88,196,.30),rgba(107,88,196,.08) 55%,transparent 72%);
}
.field-gold{
  width:80vmax;height:60vmax;right:-26vmax;top:34vmax;
  background:radial-gradient(closest-side,rgba(232,196,110,.11),transparent 70%);
}
.vignette{
  position:absolute;inset:0;
  background:radial-gradient(120% 80% at 50% 30%,transparent 40%,rgba(4,3,8,.7) 100%);
}
/* barely-there grain: one tiny tile, no image request */
.grain{
  position:absolute;inset:-100%;opacity:.032;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── nav ─────────────────────────────────────────────────────────────── */

/* ── the header ───────────────────────────────────────────────────────
   Sticky, and transparent until it has something to sit over. The frosted
   panel arrives only once the page has scrolled — at rest the hero should
   run to the top edge without a bar drawn across it. */
.nav-sentinel{position:absolute;top:0;left:0;width:1px;height:1px}
.nav{
  position:sticky;top:0;z-index:40;
  padding:var(--s4) 0;
  transition:background var(--d) var(--e-out),
             border-color var(--d) var(--e-out),
             backdrop-filter var(--d) var(--e-out);
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  padding:var(--s2) 0;          /* the bar condenses once it is a bar */
  background:rgba(13,11,19,.62);
  border-bottom-color:var(--line);
  backdrop-filter:blur(16px) saturate(1.4);
  -webkit-backdrop-filter:blur(16px) saturate(1.4);
}
/* Frosted glass needs something behind it to frost. Where the browser has
   no backdrop-filter, fall back to an opaque-enough panel rather than a
   transparent bar with text scrolling through it. */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .nav.is-stuck{background:rgba(11,10,16,.94)}
}
.nav-inner{display:flex;align-items:center;justify-content:space-between;gap:var(--s5)}
.nav-actions{display:flex;align-items:center;gap:var(--s3)}

/* Compact single-line buttons, header only. `.btn.btn-sm` rather than
   `.btn-sm`: the base .btn rule is declared later in this file and its
   52px min-height would otherwise win on equal specificity. */
.btn.btn-sm{
  min-height:36px;padding:0 var(--s4);
  font-size:var(--t-small);font-weight:600;
  flex-direction:row;align-items:center;gap:0;
}
.btn.btn-sm.btn-download{box-shadow:0 1px 0 rgba(255,255,255,.3) inset}
.btn.btn-sm.btn-download:hover{box-shadow:0 1px 0 rgba(255,255,255,.4) inset,0 8px 22px -12px rgba(232,196,110,.6)}
.btn.btn-sm.btn-ghost{border-color:var(--line-2);color:var(--warm)}
.btn.btn-sm.btn-ghost:hover{color:var(--cream)}
.wordmark{
  display:inline-flex;align-items:center;gap:var(--s3);
  color:var(--cream);text-decoration:none;
  font-size:.9375rem;font-weight:600;letter-spacing:-.005em;
  padding:var(--s2) 0;
}
.wordmark img{width:28px;height:28px;transition:transform var(--d-slow) var(--e-soft)}
.wordmark:hover img{transform:rotate(28deg)}


/* ── shared type ─────────────────────────────────────────────────────── */

.eyebrow,.index,.panel-label,.mcol-label,.frag-name{
  font-family:var(--font-mono);
  font-size:var(--t-micro);
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--dim);
}
.index{color:var(--gold);margin-bottom:var(--s4)}

h1{
  font-family:var(--font-serif);
  font-size:var(--t-display);
  font-weight:600;
  line-height:.98;
  letter-spacing:-.028em;
  margin:var(--s5) 0 var(--s6);
}
h2{
  font-family:var(--font-serif);
  font-size:var(--t-h2);
  font-weight:600;
  line-height:1.02;
  letter-spacing:-.022em;
}
code{
  font-family:var(--font-mono);
  font-size:.85em;
  color:var(--gold);
  padding:.12em .3em;
  background:rgba(232,196,110,.08);
  border-radius:var(--radius);
}
.muted{color:var(--warm)}
.footnote{
  font-size:var(--t-small);color:var(--dim);
  padding-left:var(--s4);border-left:1px solid var(--line-2);
}
.footnote a{color:var(--violet)}

a{color:var(--violet)}
a:hover{color:var(--cream)}

/* ── buttons & demo links ────────────────────────────────────────────── */

.btn{
  --btn-bg:var(--gold);
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  min-height:52px;padding:0 var(--s6);
  background:var(--btn-bg);color:var(--ink-0);
  font-size:var(--t-small);font-weight:600;letter-spacing:.005em;
  text-decoration:none;border-radius:var(--radius);
  overflow:hidden;isolation:isolate;
  transition:background var(--d) var(--e-out),transform var(--d-fast) var(--e-out),box-shadow var(--d) var(--e-out);
  box-shadow:0 1px 0 rgba(255,255,255,.35) inset,0 10px 30px -12px rgba(232,196,110,.5);
}
.btn span{position:relative;z-index:1}
.btn:hover{--btn-bg:var(--gold-2);color:var(--ink-0);box-shadow:0 1px 0 rgba(255,255,255,.45) inset,0 14px 38px -12px rgba(232,196,110,.65)}
.btn:active{transform:translateY(1px);box-shadow:0 1px 0 rgba(255,255,255,.3) inset,0 6px 18px -10px rgba(232,196,110,.5)}

/* ── the button pair ──────────────────────────────────────────────────
   One solid, one outlined. Two lines each: what it does, then what you
   are actually getting — the second line is where the platform and the
   file type live, so nobody clicks without knowing which binary lands. */
.btn-download,.btn-ghost{
  flex-direction:column;align-items:flex-start;justify-content:center;
  gap:2px;min-height:60px;padding:var(--s3) var(--s5);text-align:left;
}
.btn-line{font-size:var(--t-small);font-weight:600;line-height:1.2}
.btn-sub{
  font-family:var(--font-mono);font-size:var(--t-micro);
  font-weight:400;letter-spacing:.06em;opacity:.72;line-height:1.2;
}
.btn-ghost{
  background:none;color:var(--cream);
  border:1px solid var(--line-3);
  box-shadow:none;
}
.btn-ghost:hover{
  background:rgba(255,255,255,.04);color:var(--cream);
  border-color:var(--border-strong,rgba(255,255,255,.3));
  box-shadow:none;
}
.btn-ghost:active{transform:translateY(1px);box-shadow:none}
.btn-ghost .btn-sub{opacity:.6}

.actions-note{
  margin:var(--s4) 0 var(--s5);font-size:var(--t-small);color:var(--dim);
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3);
}
.actions-note .dot{opacity:.5}
.all-platforms{
  display:inline-flex;align-items:center;min-height:44px;
  color:var(--warm);text-decoration:none;
}
.all-platforms span,.all-platforms{position:relative}
.all-platforms::after{
  content:"";position:absolute;left:0;right:0;bottom:12px;height:1px;
  background:var(--line-3);
}
.all-platforms:hover{color:var(--cream)}
.all-platforms:hover::after{background:var(--gold)}

/* ── the platform picker ── */
.dl-modal{
  width:min(100% - 2rem,30rem);padding:var(--s6);
  border:1px solid var(--line-2);border-radius:var(--radius-lg);
  background:linear-gradient(180deg,#171422,#0f0d16);
  color:var(--cream);box-shadow:0 40px 120px -30px rgba(0,0,0,.95);
}
.dl-modal::backdrop{background:rgba(4,3,8,.72);backdrop-filter:blur(3px)}
.dl-close-form{float:right;margin:calc(var(--s3)*-1) calc(var(--s3)*-1) 0 0}
.dl-close{
  width:44px;height:44px;border:0;border-radius:var(--radius);
  background:none;color:var(--dim);font-size:22px;line-height:1;cursor:pointer;
}
.dl-close:hover{color:var(--cream);background:var(--surface-hover,rgba(255,255,255,.05))}
.dl-modal h2{font-size:1.35rem;margin-bottom:var(--s2)}
.dl-meta{
  font-family:var(--font-mono);font-size:var(--t-micro);
  letter-spacing:.1em;text-transform:uppercase;color:var(--dim);
  margin-bottom:var(--s5);
}
.dl-list{margin-bottom:var(--s5)}
.dl-row{
  display:flex;align-items:baseline;gap:var(--s3);
  padding:var(--s4);margin-bottom:var(--s2);
  border:1px solid var(--line);border-radius:var(--radius);
  text-decoration:none;color:var(--cream);
  transition:border-color var(--d) var(--e-out),background var(--d) var(--e-out);
}
.dl-row:hover{border-color:var(--gold-deep);background:rgba(232,196,110,.06);color:var(--cream)}
.dl-os{font-size:var(--t-small);font-weight:600}
.dl-arch{font-size:var(--t-small);color:var(--warm)}
.dl-ext{
  margin-left:auto;font-family:var(--font-mono);
  font-size:var(--t-micro);color:var(--dim);
}
/* the one we think you want, marked rather than pre-clicked */
.dl-row.is-yours{border-color:rgba(232,196,110,.45);background:rgba(232,196,110,.07)}
.dl-row.is-yours .dl-ext::before{
  content:"yours";margin-right:var(--s3);color:var(--gold);letter-spacing:.1em;
}
.dl-note{
  font-size:var(--t-micro);color:var(--dim);line-height:1.55;
  margin:calc(var(--s2) * -1 + 0px) 0 var(--s3);padding:0 var(--s4) 0 var(--s4);
}
.dl-note strong{color:var(--warm);font-weight:600;white-space:nowrap}
.dl-alt,.dl-foot{font-size:var(--t-small);color:var(--dim);line-height:1.5}
.dl-alt{margin-bottom:var(--s4)}
.dl-foot a,.dl-alt a{color:var(--warm)}
.dl-foot a:hover,.dl-alt a:hover{color:var(--cream)}

.demo-link{
  display:inline-flex;align-items:center;gap:var(--s3);
  min-height:44px;margin-top:var(--s5);
  font-size:var(--t-small);font-weight:600;color:var(--cream);
  text-decoration:none;
}
.demo-link span{position:relative;padding-bottom:3px}
.demo-link span::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--line-3);
}
.demo-link span::before{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;z-index:1;
  background:var(--gold);transform:scaleX(0);transform-origin:right;
  transition:transform var(--d) var(--e-out);
}
.demo-link svg{width:20px;height:10px;stroke:var(--gold);stroke-width:1.5;fill:none;
  transition:transform var(--d) var(--e-out)}
.demo-link:hover{color:var(--cream)}
.demo-link:hover span::before{transform:scaleX(1);transform-origin:left}
.demo-link:hover svg{transform:translateX(4px)}

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

/* ══════════════════════════ HERO ══════════════════════════ */

.hero{position:relative;padding:var(--s6) 0 var(--s9)}
.hero-grid{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--s9) var(--s7);
  align-items:center;
}
.hero-copy{max-width:34rem}
.lede{font-size:var(--t-lede);color:var(--warm);max-width:30rem;line-height:1.55}
.actions{margin:var(--s7) 0 var(--s5)}
.promise{
  font-size:var(--t-small);color:var(--dim);max-width:32rem;line-height:1.55;
}
.promise strong{color:var(--warm);font-weight:600}

/* The one lunar gesture: a thin ring bleeding off the right edge. The
   wrapper clips it locally — a bleed must never widen the layout box, or
   the page needs document-level overflow rules to stay honest. */
.arc{position:absolute;inset:0;overflow:hidden;pointer-events:none;opacity:.85}
.arc svg{
  position:absolute;right:-22vw;top:-16vh;
  width:min(108vh,1240px);height:min(108vh,1240px);
}
.arc-ring{stroke:rgba(255,255,255,.075);stroke-width:1}
.arc-ring-2{stroke:rgba(255,255,255,.045)}
.arc-terminator{stroke:rgba(232,196,110,.4);stroke-width:1.25;stroke-linecap:round}

/* ── the composition stage ── */

.hero-stage{position:relative}
.stage{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--s4);
}
.panel{padding:var(--s4) var(--s5) var(--s5)}
/* Sources are working material: a hairline and the type, nothing more.
   Only the composed document gets a surface — it is the thing being made. */
/* An editor is a surface in a way a file list is not — but a quieter one
   than the composed document, which stays the artifact of the picture. */
.panel-source{
  border:1px solid var(--line);
  border-left:1px solid var(--gold-deep);
  border-radius:var(--radius-lg);
  overflow:hidden;
  background:linear-gradient(180deg,rgba(18,16,28,.6),rgba(13,11,19,.35));
}
.panel-doc{
  background:linear-gradient(168deg,rgba(34,28,51,.72),rgba(13,11,19,.55));
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  box-shadow:0 30px 90px -50px rgba(0,0,0,.9);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
}
.panel-label{margin-bottom:var(--s4);color:var(--faint)}

/* ── the hero's tree: the same rows as section 02, one size down ── */
.htree li{height:26px;font-size:13px}
.htree .ic{width:13px;height:13px}
.htree .tr.f1{padding-left:calc(var(--s2) + 13px + var(--s4))}
.htree .tr.f0{padding-left:calc(var(--s2) + 13px + var(--s2))}
.htree .tr.f1::before{left:calc(var(--s2) + 6px)}
.tree-rows b{margin-left:auto;padding-left:var(--s3);font-weight:400;
  color:var(--gold);font-size:var(--t-micro);opacity:.9}
.tr[data-src]{transition:color var(--d) var(--e-out)}
.tr[data-src] .ic{transition:color var(--d) var(--e-out)}

/* ── the source pane: an editor, not a code block ──
   Gutter with line numbers and a bookmark mark, a band behind the
   directive lines, and a caret on the last one. */
/* The editor's text is sized to ITS OWN PANE, not to the viewport. The
   longest line — `@include chapters/03-the-scarecrow.md` — is 37 monospace
   characters, so it needs about 22.2x the font size in width, plus ~92px
   of gutter and padding. Sizing in cqi makes that fit at every pane width
   the layout produces instead of being sliced at a few of them. */
.panel-source{container-type:inline-size}
.editor{
  font-family:var(--font-mono);
  font-size:clamp(10px,calc(4.3cqi - 4.2px),13px);
  line-height:1.75;color:var(--warm);
  margin-left:calc(var(--s5)*-1);margin-right:calc(var(--s5)*-1);
}
.ed-line{display:flex;align-items:baseline;min-height:1.75em;padding:1px 0}
.ed-num{
  flex:none;width:var(--s6);padding-right:var(--s3);
  text-align:right;color:var(--faint);font-size:var(--t-micro);
  user-select:none;position:relative;
}
.ed-mark{
  position:absolute;right:var(--s2);top:.05em;
  width:13px;height:13px;border-radius:50%;
  border:1px solid var(--violet);color:var(--violet);
  font-style:normal;font-size:9px;line-height:11px;text-align:center;
}
.ed-line code{
  font-family:inherit;font-size:inherit;background:none;padding:0;
  color:var(--warm);white-space:pre;
}
.ed-dir{background:rgba(255,255,255,.028)}
.ed-dir code .d{color:var(--gold);font-weight:400}
.s-h{color:var(--cream)}
.s-q{color:var(--dim)}
.caret{
  display:inline-block;width:2px;height:1.05em;margin-left:1px;
  background:var(--gold);vertical-align:-2px;
}

.doc-page{font-family:var(--font-serif);font-size:.95rem;line-height:1.5}
.doc-title{
  font-family:var(--font-serif);font-size:1.55rem;font-weight:600;
  line-height:1.05;letter-spacing:-.02em;color:var(--cream);
}
.doc-by{font-size:.8rem;color:var(--dim);margin-top:var(--s2);font-style:italic}
.doc-rule{height:1px;background:var(--line-2);margin:var(--s4) 0 var(--s5)}
.doc-part{margin-bottom:var(--s5)}
.doc-h{
  font-family:var(--font-serif);font-size:.9rem;font-weight:600;
  color:var(--cream);margin-bottom:var(--s3);letter-spacing:-.005em;
}
.doc-l{
  display:block;height:5px;border-radius:1px;margin-bottom:6px;
  background:linear-gradient(90deg,rgba(255,255,255,.13),rgba(255,255,255,.05));
}
.doc-l.short{width:58%}

/* The loop: three sources become one book. 9s, transform + opacity only.

   THE INVARIANT, and it is the whole point of the illustration: an
   `@include` line and the chapter it pulls in are ONE PAIR. They appear
   together and they leave together. Three files, one document — if a line
   is up while its chapter is missing, the picture is saying something
   false. So a pair shares one cycle and one delay; only the MOTION differs
   (the line fades, the chapter rises into place), never the timing.

   The pairs are staggered against each other, not within themselves. */
@media (prefers-reduced-motion:no-preference){
  .inc,.doc-part,.caret{will-change:opacity,transform}

  /* Same timing function as well as the same keyframes: a different easing
     curve would make the two opacities differ mid-fade, which is a smaller
     version of the same lie. The pair is told apart by DISTANCE (the line
     nudges 6px, the chapter rises 14px), never by timing. */
  .inc{animation:pair-line 9s var(--e-soft) infinite}
  .doc-part{animation:pair-part 9s var(--e-soft) infinite}
  .tr[data-src]{animation:lit 9s steps(1,end) infinite}

  /* one delay per PAIR — the tree row lights with them */
  .inc[data-inc="1"],.doc-part[data-part="1"],.tr[data-src="1"]{animation-delay:0s}
  .inc[data-inc="2"],.doc-part[data-part="2"],.tr[data-src="2"]{animation-delay:.6s}
  .inc[data-inc="3"],.doc-part[data-part="3"],.tr[data-src="3"]{animation-delay:1.2s}

  .caret{animation:blink 1.1s steps(1,end) infinite}
}

/* Identical opacity percentages in both keyframe sets. If these two ever
   drift apart, the pair breaks — that is the bug this replaced. */
@keyframes pair-line{
  0%,4%{opacity:0;transform:translateY(6px)}
  11%,92%{opacity:1;transform:none}
  97%,100%{opacity:0;transform:translateY(-4px)}
}
@keyframes pair-part{
  0%,4%{opacity:0;transform:translateY(14px)}
  11%,92%{opacity:1;transform:none}
  97%,100%{opacity:0;transform:translateY(-6px)}
}
@keyframes lit{
  0%,4%{color:var(--warm)}
  11%,92%{color:var(--gold)}
  97%,100%{color:var(--warm)}
}
@keyframes blink{0%,50%{opacity:1}51%,100%{opacity:0}}

/* ══════════════════════════ SECTIONS ══════════════════════════ */

.claim{position:relative;padding:clamp(72px,8.5vw,132px) 0}
.claim-head h2{margin-top:var(--s3)}

/* 01 — the wire */
.claim-top{margin-bottom:var(--s9)}
.claim-01 .claim-head{margin-bottom:var(--s6)}
.claim-lead{max-width:var(--measure)}
.claim-lead p{margin-bottom:var(--s4)}

.wires{position:relative}
.wire-stack{display:grid}
.wire{
  grid-area:1/1;
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--s6);
  align-items:center;
  transition:opacity var(--d) var(--e-soft),transform var(--d) var(--e-soft),
             visibility 0s linear var(--d);
}
/* only the chosen example is visible AND exposed — see the note on the
   folder switcher below for why visibility rather than opacity alone */
.wire-docs,.wire-proposal{opacity:0;transform:translateY(6px);visibility:hidden;pointer-events:none}
/* NOTE: these selectors target the EXAMPLE (.wire-book / .wire-docs /
   .wire-proposal). The composed-document column inside each example is
   .wire-result — it used to be called .wire-book too, and selecting
   Documentation then hid that example's own composed document, because
   `visibility` inherits and the class matched both. One name, one thing. */
#wire-book:checked ~ .wire-stack .wire-docs,
#wire-book:checked ~ .wire-stack .wire-proposal,
#wire-docs:checked ~ .wire-stack .wire-proposal,
#wire-proposal:checked ~ .wire-stack .wire-docs{
  opacity:0;transform:translateY(6px);visibility:hidden;pointer-events:none;
}
#wire-docs:checked ~ .wire-stack > .wire-book,
#wire-proposal:checked ~ .wire-stack > .wire-book{
  opacity:0;transform:translateY(-6px);visibility:hidden;pointer-events:none;
}
#wire-docs:checked ~ .wire-stack .wire-docs,
#wire-proposal:checked ~ .wire-stack .wire-proposal{
  opacity:1;transform:none;visibility:visible;pointer-events:auto;
  transition:opacity var(--d) var(--e-soft),transform var(--d) var(--e-soft),
             visibility 0s linear 0s;
}
.wires .toggle{margin-top:var(--s6)}
.wire-join,.wire-arrow{display:none}
.wire-arrow svg{width:100%;height:12px}
.arrowhead{stroke:rgba(232,196,110,.5);stroke-width:1.25;fill:none;stroke-linecap:round}

/* The book is the payoff, so it is the only surface in this row. */
.book-out{
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:linear-gradient(168deg,rgba(34,28,51,.7),rgba(13,11,19,.5));
  box-shadow:0 26px 70px -46px rgba(0,0,0,.9);
  padding:var(--s5);
  margin-top:var(--s3);
}
.book-title{
  font-family:var(--font-serif);font-size:1.15rem;font-weight:600;
  line-height:1.1;letter-spacing:-.018em;color:var(--cream);
}
.book-rule{height:1px;background:var(--line-2);margin:var(--s4) 0}
.book-ch{
  font-family:var(--font-serif);font-size:.82rem;font-weight:600;
  color:var(--cream);margin:var(--s4) 0 var(--s3);letter-spacing:-.004em;
}
.book-out .fl{max-width:none}
.frag{
  border-left:1px solid var(--line-2);
  padding:var(--s3) 0 var(--s4) var(--s5);
  transition:border-color var(--d) var(--e-out);
}
.wire-sources{display:grid;gap:var(--s6)}
.wire:hover .frag{border-left-color:var(--gold-deep)}
.frag-name{margin-bottom:var(--s3);color:var(--warm);letter-spacing:.08em;overflow-wrap:anywhere}
.fl{display:block;height:4px;border-radius:1px;margin-bottom:7px;max-width:22rem;
  background:linear-gradient(90deg,rgba(255,255,255,.12),rgba(255,255,255,.03))}
.fl.short{width:11rem}
.frag-out{
  border-left:1px solid var(--gold);
  padding:var(--s5) var(--s5) var(--s5) var(--s6);
  background:linear-gradient(90deg,rgba(232,196,110,.05),transparent 70%);
}
.frag-dir{
  font-family:var(--font-mono);font-size:var(--t-mono);
  color:var(--warm);line-height:1.9;
  overflow-wrap:anywhere;
}
.frag-dir b{color:var(--gold);font-weight:400}

/* ══════ the product, as itself ══════ */

.product{padding:clamp(56px,6vw,96px) 0 clamp(72px,8.5vw,132px)}
.product-head{
  display:flex;flex-wrap:wrap;gap:var(--s4) var(--s7);
  align-items:baseline;margin-bottom:var(--s7);
}
.product-head p:last-child{color:var(--warm);max-width:34rem;font-size:var(--t-small)}
/* The still is a window that already carries its own 1px border and its
   own ~14px corner, edge to edge. So the frame here adds NO border of its
   own — two borders a pixel apart read as a doubled edge — and its radius
   is set a hair rounder than the window's so the container arc never cuts
   across it. Mobile crops the corners away entirely (object-fit), so it
   keeps the small radius and the frame defines the shape there. */
.product-shot{
  position:relative;
  width:min(100% - var(--gutter)*2,116rem);margin-inline:auto;
  border-radius:15px;
  overflow:hidden;background:var(--ink-1);
  box-shadow:0 40px 120px -40px rgba(0,0,0,.9);
}
.product-shot img,.product-shot video{width:100%;height:auto;display:block}
/* The still is 3454x2164 (1.596) and the box takes its aspect from the
   image itself — no crop, no letterbox, and the width/height attributes
   reserve the right space before it loads. */

/* 02 — the folder outlives the app */
.claim-02 .quiet-head{margin-bottom:var(--s8);max-width:30rem}
.quiet-grid{
  display:grid;grid-template-columns:minmax(0,1fr);
  gap:var(--s8) var(--s9);align-items:start;
}
.quiet-copy p{margin-bottom:var(--s5)}
.quiet-copy .big{
  font-family:var(--font-serif);font-size:var(--t-big);
  line-height:1.28;letter-spacing:-.014em;color:var(--cream);
}
.quiet-copy p{max-width:30rem}

/* ── one folder, two views ──────────────────────────────────────────
   Both views stack in ONE grid cell, so the panel is as tall as the taller
   of them and nothing on the page moves when you switch. The rows are
   identical in both; only the chrome differs. */
.switcher{position:relative}
.views{
  /* minmax(0,1fr) not 1fr: a grid item's default min-width:auto lets
     nowrap content push the track wider than the panel, which clips the
     filenames instead of truncating them. */
  grid-template-columns:minmax(0,1fr);
  display:grid;
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:linear-gradient(180deg,rgba(18,16,28,.72),rgba(13,11,19,.45));
  overflow:hidden;
}
/* The inactive view is hidden with `visibility`, not opacity alone: an
   opacity:0 element is still read out, so a screen reader would announce
   all eighteen rows and hear the same folder twice. visibility keeps the
   box in the grid (so the panel height stays put) while taking it out of
   the accessibility tree and the tab order. The 0s transition is delayed
   by the fade duration when hiding, and immediate when showing. */
.view{
  grid-area:1/1;padding:var(--s5);min-width:0;
  transition:opacity var(--d) var(--e-soft),transform var(--d) var(--e-soft),
             visibility 0s linear 0s;
}
.view[hidden-state],
.view-fs{
  opacity:0;transform:translateY(6px);visibility:hidden;pointer-events:none;
  transition:opacity var(--d) var(--e-soft),transform var(--d) var(--e-soft),
             visibility 0s linear var(--d);
}
#view-fs:checked ~ .views .view-app{
  opacity:0;transform:translateY(-6px);visibility:hidden;pointer-events:none;
  transition:opacity var(--d) var(--e-soft),transform var(--d) var(--e-soft),
             visibility 0s linear var(--d);
}
#view-fs:checked ~ .views .view-fs{
  opacity:1;transform:none;visibility:visible;pointer-events:auto;
  transition:opacity var(--d) var(--e-soft),transform var(--d) var(--e-soft),
             visibility 0s linear 0s;
}

/* ── the Moondonut tree ── */
.tree-head{
  display:flex;align-items:center;
  font-family:var(--font-mono);font-size:var(--t-micro);
  letter-spacing:.14em;text-transform:uppercase;color:var(--warm);
  padding:0 var(--s2) var(--s4);
}
.plus{
  margin-left:auto;width:11px;height:11px;position:relative;opacity:.5;
}
.plus::before,.plus::after{
  content:"";position:absolute;background:var(--dim);
  left:50%;top:50%;transform:translate(-50%,-50%);
}
.plus::before{width:11px;height:1px}
.plus::after{width:1px;height:11px}

.tree-rows,.fx-rows{min-width:0}
.tree-rows li{
  display:flex;align-items:center;gap:var(--s2);
  font-size:var(--t-small);color:var(--warm);
  height:28px;padding:0 var(--s2);border-radius:var(--radius);
  white-space:nowrap;
}
.tree-rows .ic{color:var(--dim)}
.tree-rows .tw{color:var(--faint);width:12px;height:12px}
.tw-gap{width:12px;flex:none}
/* the indent ladder: a hairline per level, the way a tree draws depth */
.tr.d0{padding-left:var(--s2)}
.tr.f0{padding-left:calc(var(--s2) + 12px + var(--s2))}
.tr.f1{padding-left:calc(var(--s2) + 12px + var(--s5))}
.tr.f1,.tr.f0{position:relative}
.tr.f1::before{
  content:"";position:absolute;left:calc(var(--s2) + 5px);top:0;bottom:0;
  width:1px;background:var(--line);
}
/* A file that IS a composition is gold in the app's tree — that is what
   marks book.md out, not a selection. */
.tree-rows .is-sel{color:var(--gold-2)}
.tree-rows .is-sel .ic{color:var(--gold)}

/* ── the actual folder: a dark macOS list view ──
   Deliberately NOT in the page's palette. It is the operating system, not
   our surface, and the shift in material is half the argument. */
.view-fs{padding:0;background:#1e1e20;border-radius:var(--radius-lg);overflow:hidden}
.fx-titlebar{
  display:flex;align-items:center;gap:var(--s4);
  height:44px;padding:0 var(--s4);
  background:linear-gradient(180deg,#3a3a3c,#323234);
  border-bottom:1px solid #101011;
}
/* Traffic lights: the clearest possible signal that this is a window of
   the operating system rather than a surface of ours. */
.fx-lights{
  width:52px;height:12px;flex:none;position:relative;
}
.fx-lights::before{
  content:"";position:absolute;left:0;top:0;width:12px;height:12px;
  border-radius:50%;background:#ff5f57;
  box-shadow:20px 0 0 #febc2e,40px 0 0 #28c840;
}
.fx-nav{
  width:34px;height:14px;flex:none;position:relative;opacity:.5;
}
.fx-nav::before,.fx-nav::after{
  content:"";position:absolute;top:3px;width:6px;height:6px;
  border-top:1.5px solid #d8d8da;border-right:1.5px solid #d8d8da;
}
.fx-nav::before{left:2px;transform:rotate(-135deg)}
.fx-nav::after{left:18px;transform:rotate(45deg)}
.fx-title{
  font-family:var(--font-ui);font-size:13px;font-weight:600;color:#f2f2f4;
  letter-spacing:-.01em;
}
.fx-colhead{
  display:flex;align-items:center;
  height:24px;padding:0 var(--s4);
  background:#2b2b2d;border-bottom:1px solid #38383a;
  font-family:var(--font-ui);font-size:11px;color:#a8a8ad;
}
.fx-colhead em{margin-left:auto;font-style:normal}
.fx-rows li{
  display:flex;align-items:center;gap:var(--s2);
  height:24px;padding:0 var(--s4);
  font-family:var(--font-ui);font-size:12.5px;color:#eaeaec;
  white-space:nowrap;
}
.fx-rows li:nth-child(odd){background:#252527}
.fx-rows em{margin-left:auto;font-style:normal;color:#8e8e93;font-size:11px}
.fx-gap{width:12px;flex:none}
.fx-tw{
  width:12px;height:12px;flex:none;position:relative;
}
.fx-tw::after{
  content:"";position:absolute;left:2px;top:50%;
  width:0;height:0;border-left:4px solid #9a9a9f;
  border-top:3px solid transparent;border-bottom:3px solid transparent;
  transform:translateY(-50%) rotate(90deg);
}
.fx.f0{padding-left:calc(var(--s4) + 12px + var(--s2))}
.fx.f1{padding-left:calc(var(--s4) + 12px + var(--s5))}
.fx-dir{
  width:15px;height:12px;flex:none;border-radius:2px;
  background:linear-gradient(180deg,#7cb8f0,#4f92d8);
  box-shadow:0 -3px 0 -1px #6aa9e6 inset;
}
.fx-doc{
  width:12px;height:15px;flex:none;border-radius:2px;
  background:#f2f2f4;color:#4a4a4f;
  font-family:var(--font-ui);font-size:8px;font-weight:700;
  display:flex;align-items:center;justify-content:center;
}
.fx-img{
  width:14px;height:11px;flex:none;border-radius:2px;
  background:linear-gradient(140deg,#b9c7a8,#8a9c78 55%,#6f7f62);
  border:1px solid #d6d6d8;
}

/* the switch */
.toggle{
  display:inline-flex;margin-top:var(--s4);
  border:1px solid var(--line-2);border-radius:var(--radius);
  padding:3px;gap:3px;background:rgba(255,255,255,.02);
}
.toggle label{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 var(--s5);border-radius:2px;cursor:pointer;
  font-family:var(--font-mono);font-size:var(--t-micro);
  letter-spacing:.12em;text-transform:uppercase;color:var(--dim);
  transition:color var(--d) var(--e-out),background var(--d) var(--e-out);
  user-select:none;
}
.toggle label:hover{color:var(--warm)}
#view-app:checked ~ .toggle label[for="view-app"],
#view-fs:checked  ~ .toggle label[for="view-fs"]{
  background:rgba(232,196,110,.13);color:var(--gold-2);
}
/* the inputs are visually hidden, so the ring has to land on the label */
#view-app:focus-visible ~ .toggle label[for="view-app"],
#view-fs:focus-visible  ~ .toggle label[for="view-fs"]{
  outline:2px solid var(--gold);outline-offset:2px;
}
.switch-caption{
  margin-top:var(--s4);font-size:var(--t-small);color:var(--dim);
  max-width:30rem;line-height:1.5;
}
.switch-caption em{font-style:italic;color:var(--warm)}

/* 03 — the mask */
.split{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s8) var(--s9);align-items:start}
.split-copy{max-width:var(--measure)}
.split-copy h2{margin-bottom:var(--s5)}
.split-copy p{margin-bottom:var(--s4)}

.mask-fig{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5)}
.mcol-label{margin-bottom:var(--s4);color:var(--dim)}
.mcol-out .mcol-label{color:var(--gold)}
.mstack li{
  font-family:var(--font-mono);font-size:var(--t-mono);
  color:var(--warm);padding:var(--s3) var(--s4);min-height:44px;display:flex;align-items:center;
  border:1px solid var(--line);border-radius:var(--radius);
  margin-bottom:var(--s2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:opacity var(--d) var(--e-out);
}
.m-part{padding-left:var(--s6);color:var(--dim)}
.m-ctx{border-color:rgba(232,196,110,.45);color:var(--gold-2);background:rgba(232,196,110,.09)}
.m-gone{
  opacity:.34;border-style:dashed;border-color:var(--line);
  color:var(--faint);background:none;position:relative;
}
.m-gone::after{
  content:"";position:absolute;left:var(--s4);right:var(--s4);top:50%;
  height:1px;background:currentColor;
}
/* Forced colours throws away the opacity, the dashed border and the painted
   rule above — every distinction this figure is made of. text-decoration is
   one of the few properties the mode keeps, so the exclusion survives it. */
@media (forced-colors:active){
  .m-gone{opacity:1;text-decoration:line-through}
  .m-gone::after{display:none}
}

/* ══════ close ══════ */

.close{padding:clamp(80px,9vw,144px) 0 clamp(72px,8vw,112px);text-align:center}
.close-line{
  font-family:var(--font-serif);
  font-size:clamp(2.4rem,1rem + 5vw,4.6rem);
  font-weight:600;line-height:1;letter-spacing:-.03em;
  margin-bottom:var(--s8);
}
.close-line .line span{color:var(--cream)}
.close-line .line:last-child span{color:var(--gold)}
.close-actions{display:flex;flex-direction:column;align-items:center;gap:var(--s5)}
.close-actions .promise{text-align:center;max-width:30rem}

/* ══════ footer ══════ */

footer{border-top:1px solid var(--line);padding:var(--s7) 0 var(--s8)}
.footer-inner{display:flex;flex-wrap:wrap;gap:var(--s4) var(--s7);
  align-items:baseline;justify-content:space-between}
.foot-mark{font-size:var(--t-small);color:var(--dim)}
.foot-links{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s6)}
.foot-links a{
  font-size:var(--t-small);color:var(--warm);text-decoration:none;
  padding:var(--s2) 0;position:relative;
}
.foot-links a::after{
  content:"";position:absolute;left:0;right:0;bottom:4px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:right;
  transition:transform var(--d) var(--e-out);
}
.foot-links a:hover{color:var(--cream)}
.foot-links a:hover::after{transform:scaleX(1);transform-origin:left}

/* ══════ reveal system ══════ */

.reveal{opacity:0;transform:translateY(12px);
  transition:opacity 420ms var(--e-out),transform 420ms var(--e-out)}
.reveal.is-in{opacity:1;transform:none}

.reveal-mask .line{display:block;overflow:hidden}
.reveal-mask .line>span{
  display:block;transform:translateY(105%);
  transition:transform 700ms var(--e-soft);
}
.reveal-mask.is-in .line>span{transform:none}
.reveal-mask.is-in .line:nth-child(2)>span{transition-delay:80ms}
.reveal-mask.is-in .line:nth-child(3)>span{transition-delay:160ms}

/* The stagger lives HERE, not in a style attribute on each path. Under the
   deployed CSP (style-src 'self', no 'unsafe-inline') an inline style is
   refused, var(--i) is then invalid, and all three threads drew at once —
   a bug that could not appear locally, because a plain static server sends
   no CSP. csptest.js serves the real _headers policy and catches it. */
.thread{stroke:var(--line-3);stroke-width:1;
  stroke-dasharray:260;stroke-dashoffset:260;
  transition:stroke-dashoffset 900ms var(--e-soft),stroke 600ms var(--e-out);}
.thread-1{transition-delay:0ms}
.thread-2{transition-delay:140ms}
.thread-3{transition-delay:280ms}
.is-in .thread{stroke-dashoffset:0;stroke:rgba(232,196,110,.42)}

/* ══════════════════════════ RESPONSIVE ══════════════════════════
   Mobile is designed, not collapsed: the compositions keep their story
   and only lose overlap and parallax. ═════════════════════════════ */

@media (min-width:48rem){          /* 768 */
  .stage{grid-template-columns:1fr 1fr;gap:var(--s5)}
  .panel-doc{grid-column:2;grid-row:1/span 2}
  .wire{
    grid-template-columns:
      minmax(0,.62fr) 84px minmax(0,.92fr) 56px minmax(0,.78fr);
    gap:var(--s4);
  }
  .wire-join,.wire-arrow{display:block}
  .wire-join svg{width:100%;height:300px}
  .mask-fig{gap:var(--s6)}
  .close-actions{flex-direction:column}
}

@media (min-width:64rem){          /* 1024 */
  .hero{padding:var(--s7) 0 var(--s9)}
  .quiet-grid{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}
  .split{grid-template-columns:minmax(0,1fr) minmax(0,1.1fr)}
  .claim-top{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    gap:var(--s7) var(--s8);align-items:start;
  }
  .claim-01 .claim-head{margin-bottom:0}
}

/* The hero goes side-by-side only at 80rem, and not a pixel sooner.
   Below that the copy column would leave the composition about 440px, and
   `@include chapters/03-the-scarecrow.md` does not fit in 440px beside a
   gutter and a composed document — it just gets sliced. Stacked, the
   composition has the whole shell and every line reads. */
@media (min-width:80rem){          /* 1280 */
  /* 28rem, not 26: the display face needs it — "documents" at 5.25rem is
     wider than a 26rem column and gets sliced. The composition can afford
     the space now that the editor sizes its own text to its pane. */
  .hero-grid{grid-template-columns:minmax(0,28rem) minmax(0,1fr);gap:var(--s7)}

  /* Side by side, not overlapping: both are surfaces now, and a source
     pane sitting ON the composed document hides the payoff. */
  .stage{grid-template-columns:minmax(0,.95fr) minmax(0,1fr);gap:0}
  .panel-tree{z-index:2;position:relative;margin-right:var(--s5);padding-left:0}
  .panel-source{
    grid-column:1;grid-row:2;margin-top:var(--s3);
    margin-right:var(--s5);
    z-index:3;position:relative;
  }
  .panel-doc{
    grid-column:2;grid-row:1/span 2;margin-top:var(--s7);
    z-index:1;position:relative;padding:var(--s6) var(--s6) var(--s7);
  }
}

@media (min-width:90rem){          /* 1440 */
  :root{--shell:82rem}
  .panel-doc{margin-top:var(--s9)}
}

@media (max-width:47.99rem){
  /* One action in the header on a phone. "Open in browser" is the first
     thing in the hero anyway, so repeating it here only costs width. */
  .nav-actions .btn-ghost{display:none}
  .nav{padding:var(--s3) 0}
  .btn.btn-sm{min-height:34px;padding:0 var(--s3);font-size:13px}

  /* Narrow panels truncate long filenames rather than running past the
     edge — the app's own tree does exactly this. The Finder's date column
     goes; on a phone the name is the whole point. */
  .tree-rows li span,.fx-rows li span{
    overflow:hidden;text-overflow:ellipsis;min-width:0;
  }
  .tree-rows li,.fx-rows li{min-width:0}
  .fx-rows em,.fx-colhead em{display:none}
  .tree-rows,.fx-rows{min-width:0}
.tree-rows li{font-size:13px}
  .fx-rows li{font-size:12px}

  /* Full width, equal halves, and tighter tracking so neither label wraps —
     a segmented control that breaks onto two lines stops reading as a switch. */
  .toggle{display:flex;width:100%}
  .toggle label{flex:1;padding:0 var(--s3);letter-spacing:.07em}

  /* A whole IDE window at 348px wide is a postage stamp — 3454px of dense
     UI reduced ten times over. So the phone gets a CROP instead of the
     window: a taller box holding the split boundary, where the source pane
     meets the composed document. The @include story is already told, in
     real text, by the composition above. */
  /* A 4:5 crop of a 16:10 source shows the full height and half the
     width; 40% centres that half on the split boundary, so the @include
     lines and the composed document are both in frame. */
  .product-shot img{aspect-ratio:4/5;object-fit:cover;object-position:40% 50%}
  .product-shot{border-radius:var(--radius-lg);border:1px solid var(--line-2)}

  .hero{padding:var(--s6) 0 var(--s8)}
  h1{margin:var(--s4) 0 var(--s5)}
  .claim,.product{padding:var(--s8) 0}
  .close{padding:var(--s8) 0 var(--s7)}
  .actions{margin:var(--s6) 0 var(--s4)}
  .btn{width:100%}
  .arc{opacity:.55}
  .arc svg{right:-58vw;top:-4vh;width:150vw;height:150vw}
  .mask-fig{grid-template-columns:1fr;gap:var(--s6)}
  .footer-inner{flex-direction:column;align-items:flex-start;gap:var(--s5)}
  .foot-links{flex-direction:column;gap:var(--s2)}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{opacity:1;transform:none}
  .reveal-mask .line>span{transform:none}
  .thread{stroke-dashoffset:0;stroke:rgba(232,196,110,.42)}
}


/* ══════ document pages: /sync and /terms ══════
   Same system, editorial measure, no compositions. */
.doc{padding:var(--s7) 0 var(--s9);max-width:var(--measure)}
.doc h1{
  font-size:clamp(1.9rem,1.3rem + 1.9vw,2.9rem);
  line-height:1.05;margin:0 0 var(--s5);
}
.doc h2{
  font-size:clamp(1.15rem,1.02rem + .5vw,1.4rem);
  margin:var(--s8) 0 var(--s4);
}
.doc p,.doc li{color:var(--warm);margin-bottom:var(--s4)}
.doc p em{color:var(--dim);font-style:normal;font-family:var(--font-mono);
  font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase}
.doc ul{margin:0 0 var(--s5)}
.doc li{padding-left:var(--s5);position:relative}
.doc li::before{content:"";position:absolute;left:0;top:.72em;
  width:10px;height:1px;background:var(--gold-deep)}
.doc strong{color:var(--cream);font-weight:600}
/* The sub-pages' prose links, and the one link in their header, were never
   given a colour — so they fell back to the user agent's blue and purple, the
   two colours this page has no place for. Anything the eye reads as a link
   here is gold, like the directives. */
.doc a{color:var(--gold-2);text-decoration:none;
  border-bottom:1px solid rgba(232,196,110,.34);
  transition:color var(--d) var(--e-out),border-color var(--d) var(--e-out)}
.doc a:hover{color:var(--cream);border-color:var(--gold)}
.nav-link{font-size:var(--t-small);color:var(--warm);text-decoration:none;
  transition:color var(--d) var(--e-out)}
.nav-link:hover{color:var(--cream)}

.doc .back{margin-top:var(--s8);font-size:var(--t-small)}
.doc .back a{color:var(--warm);text-decoration:none;border-bottom:1px solid var(--line-2)}
.doc .back a:hover{color:var(--cream);border-color:var(--gold)}
