/* The Flashpoint Stack.
   Layout copied from Linear: near-black ground, centered hero, a small dim
   eyebrow over a large tight headline, two or three short lines under it, and
   a great deal of space. No glow, no tint bands, no animation, no rail.
   Red is the accent; it appears on one button and on the free markers. */

@font-face{font-family:Inter;src:url(fonts/inter-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:Inter;src:url(fonts/inter-500.woff2) format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:Inter;src:url(fonts/inter-600.woff2) format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:PlexM;src:url(fonts/plex-mono-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:PlexM;src:url(fonts/plex-mono-500.woff2) format('woff2');font-weight:500;font-display:swap}

:root{
  color-scheme:dark;
  --bg:#08090A;
  --surface:#0F1011;
  --raise:#151617;
  --line:#1F2023;
  --hair:#161719;
  --fg:#F7F8F8;
  --dim:#8A8F98;
  --red:#FF2D0A;
  --sans:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --mono:PlexM,ui-monospace,SFMono-Regular,Menlo,'Liberation Mono',monospace;
  --page:1000px;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;background:var(--bg)}
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
  font-feature-settings:'cv11','ss01'}
a{color:inherit;text-decoration:none}
p{margin:0}
:focus-visible{outline:2px solid var(--red);outline-offset:3px}
.wrap{max-width:var(--page);margin:0 auto;padding-inline:24px}

/* ------------------------------------------------------------------- nav */
.nav{position:sticky;top:0;z-index:10;background:rgba(8,9,10,.82);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.nav .wrap{display:flex;align-items:center;gap:24px;height:56px}
.brand{display:flex;align-items:center;gap:9px;font-weight:500;font-size:14.5px;
  letter-spacing:-.01em}
.brand img{height:17px;width:auto;display:block}
.nav .links{display:flex;gap:22px;margin-inline:auto;font-size:13.5px;color:var(--dim)}
.nav .links a:hover{color:var(--fg)}
.nav .links a[aria-current]{color:var(--fg)}

/* ------------------------------------------------------ centered hero */
.hero{text-align:center;padding-block:clamp(70px,10vw,124px) clamp(16px,2vw,26px)}
.eyebrow{font-size:13px;color:var(--dim);letter-spacing:.02em;margin-bottom:22px}
h1{margin:0;font-weight:600;letter-spacing:-.035em;line-height:1.04;
  font-size:clamp(38px,6.2vw,72px);max-width:17ch;margin-inline:auto;
  text-wrap:balance}
.lede{margin:22px auto 0;max-width:42ch;text-wrap:balance;color:var(--dim);font-size:17px;line-height:1.62}
.hero .cta{margin-top:32px;display:flex;gap:10px;justify-content:center;flex-wrap:wrap}


/* ------------------------------------------------------ the rolling word
   The last word of the headline cycles through what the library actually
   does. Each word is a real stage of the process, not a synonym list.

   Pure CSS: a column of words inside a one-line window. The first word is
   repeated at the end so the jump back to the top lands on an identical
   frame and is invisible. The window sizes itself to the widest word, and
   since the word ends the sentence the spare space falls off the end of
   the line where nobody sees it. */
.roll{display:inline-block;overflow:hidden;height:1.30em;margin-bottom:-.26em;vertical-align:bottom}
.roll .track{display:flex;flex-direction:column;animation:roll 16.8s infinite}
.roll em{font-style:normal;color:var(--red);line-height:1.30;height:1.30em;white-space:nowrap;display:block}
@keyframes roll{
  0.00%, 12.29% { transform:translateY(-0.00em) }
  14.29%, 26.57% { transform:translateY(-1.30em) }
  28.57%, 40.86% { transform:translateY(-2.60em) }
  42.86%, 55.14% { transform:translateY(-3.90em) }
  57.14%, 69.43% { transform:translateY(-5.20em) }
  71.43%, 83.71% { transform:translateY(-6.50em) }
  100% { transform:translateY(-7.80em) }
}
/* the animated copy is hidden from assistive tech; this is what it reads */
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}

/* ----------------------------------------------------------------- button */
.btn{display:inline-flex;align-items:center;gap:8px;height:38px;padding-inline:17px;
  border-radius:6px;font-size:13.5px;font-weight:500;border:1px solid var(--line);
  color:var(--fg);transition:background .14s,border-color .14s,color .14s}
.btn:hover{background:var(--raise);border-color:#2C2E31}
.btn.key{background:var(--red);border-color:var(--red);color:#fff}
.btn.key:hover{background:#FF4622;border-color:#FF4622}

/* -------------------------------------------------- the output it returns */
.panel{max-width:640px;margin:0 auto;background:var(--surface);
  border:1px solid var(--line);border-radius:10px;overflow:hidden;text-align:left}
.panel .bar{display:flex;align-items:center;gap:9px;padding:11px 16px;
  border-bottom:1px solid var(--line);font-family:var(--mono);font-size:12px}
.panel .bar .dot{width:6px;height:6px;border-radius:50%;background:var(--red);flex:none}
.panel .bar .meta{margin-left:auto;color:var(--dim)}
.panel dl{margin:0;padding:4px 16px 8px}
.panel .fld{display:grid;grid-template-columns:104px minmax(0,1fr);gap:14px;
  padding-block:11px;border-bottom:1px solid var(--hair)}
.panel .fld:last-child{border-bottom:0}
.panel dt{margin:0;font-family:var(--mono);font-size:11px;color:var(--dim);padding-top:2px}
.panel dd{margin:0;font-size:14px;line-height:1.55}
.panel .src{display:block;margin-top:2px;font-family:var(--mono);font-size:11px;color:var(--dim)}
.caption{margin:14px auto 0;max-width:640px;font-size:12.5px;color:var(--dim);text-align:center}

/* --------------------------------------------------------------- sections */
.sec{padding-block:clamp(56px,8vw,104px);border-top:1px solid var(--line)}
h2{margin:0 0 10px;font-weight:600;font-size:clamp(24px,3vw,34px);
  letter-spacing:-.03em;line-height:1.12}
.sec .head{text-align:center;margin-bottom:40px}
.sec .head p{color:var(--dim);max-width:46ch;margin-inline:auto;font-size:16px}

/* ---------------------------------------------------------------- figures */
.figs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:24px;text-align:center}
.figs b{display:block;font-weight:600;font-size:30px;letter-spacing:-.03em;line-height:1}
.figs span{display:block;margin-top:6px;font-size:13.5px;color:var(--dim)}

/* ------------------------------------------------------------------ tiers */
.tiers{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.tier{border:1px solid var(--line);border-radius:10px;padding:24px;background:var(--surface)}
.tier .t{font-size:13.5px;color:var(--dim)}
.tier .amt{font-weight:600;font-size:30px;letter-spacing:-.03em;margin:8px 0 20px;line-height:1}
.tier ul{list-style:none;margin:0;padding:0}
.tier li{font-size:14px;color:var(--dim);padding-block:7px;border-bottom:1px solid var(--hair)}
.tier li:last-child{border-bottom:0}
.tier li code{font-family:var(--mono);font-size:12.5px;color:var(--fg)}

/* ------------------------------------------------------------------- rows */
.grp{margin-bottom:38px}
.grp h3{margin:0 0 2px;font-size:14px;font-weight:500;letter-spacing:-.01em}
.grp .n{font-family:var(--mono);font-size:11.5px;color:var(--dim);margin-bottom:10px;display:block}
.rows{border-top:1px solid var(--line)}
.row{display:grid;grid-template-columns:30px 160px minmax(0,1fr) 38px;gap:10px 18px;
  align-items:baseline;padding-block:12px;border-bottom:1px solid var(--hair)}
.row code{font-family:var(--mono);font-size:13px;color:var(--fg)}
.row .d{font-size:14px;color:var(--dim)}
.row .f{font-family:var(--mono);font-size:11px;color:var(--red);text-align:right}

/* ---------------------------------------------------------------- filter */
.filter{display:flex;align-items:center;gap:14px;font-size:13.5px;color:var(--dim);
  padding-bottom:22px}
.sw{display:inline-flex;align-items:center;gap:8px;cursor:pointer;color:var(--fg)}
.sw input{position:absolute;opacity:0;width:0;height:0}
.sw .box{width:14px;height:14px;border:1px solid #34363A;border-radius:4px;position:relative;
  display:inline-block;transition:.12s}
.sw input:checked + .box{background:var(--red);border-color:var(--red)}
.sw input:checked + .box::after{content:"";position:absolute;left:4px;top:1px;width:4px;height:8px;
  border:solid #fff;border-width:0 1.5px 1.5px 0;transform:rotate(42deg)}
.sw input:focus-visible + .box{outline:2px solid var(--red);outline-offset:2px}

/* ------------------------------------------------------------------ steps */
.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px}
.steps div{border-top:1px solid var(--line);padding-top:14px}
.steps b{display:block;font-family:var(--mono);font-size:11.5px;color:var(--red);margin-bottom:7px}
.steps p{font-size:14px;color:var(--dim)}
.steps strong{display:block;color:var(--fg);font-weight:500;font-size:14px;margin-bottom:3px}

/* ------------------------------------------------------------------ cards */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.card{border:1px solid var(--line);border-radius:10px;padding:20px;background:var(--surface)}
.card h3{margin:0 0 8px;font-size:14px;font-weight:500}
.card p{font-size:13.5px;color:var(--dim)}
pre{font-family:var(--mono);font-size:12px;line-height:1.65;margin:12px 0 0;padding:11px 12px;
  background:var(--bg);border:1px solid var(--line);border-radius:6px;
  white-space:pre-wrap;overflow-wrap:anywhere;color:var(--fg)}

/* -------------------------------------------------------------------- faq */
.faq{max-width:640px;margin-inline:auto}
.faq div{padding-block:16px;border-bottom:1px solid var(--hair)}
.faq h3{margin:0 0 4px;font-size:14.5px;font-weight:500}
.faq p{font-size:14px;color:var(--dim)}

/* ----------------------------------------------------------------- footer */
footer{border-top:1px solid var(--line);padding-block:28px 40px;font-size:13px;color:var(--dim)}
footer .fl{display:flex;flex-wrap:wrap;gap:14px 26px;align-items:baseline}
footer a:hover{color:var(--fg)}
footer .disc{max-width:76ch;margin-top:12px;font-size:12px;line-height:1.6}

@media (max-width:860px){
  .figs{grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}
  .tiers,.cards,.steps{grid-template-columns:1fr}
}
@media (max-width:640px){
  .nav .links{gap:16px;font-size:13px}
  .row{grid-template-columns:minmax(0,1fr) 38px;gap:2px 12px}
  .row .d{grid-column:1/-1}
  .row .d{grid-column:1/-1}
  .panel .fld{grid-template-columns:minmax(0,1fr);gap:2px}
  .hero{padding-block:64px 44px}
}

/* ==========================================================================
   GRAPHICS, EXPLAINERS, MOTION
   ========================================================================== */

/* ------------------------------------------- hero, text over the diagram
   The diagram is wide, so it sits under the copy at full width rather than
   squeezed into a column. */
.hero .t{text-align:left}
.hero h1{margin-inline:0;max-width:15ch}
.hero .lede{margin-inline:0;text-align:left;max-width:44ch}
.hero .cta{justify-content:flex-start}

/* ------------------------------------------------------- the molten core */
.corewrap{position:relative;display:flex;justify-content:center;
  margin-top:clamp(8px,1.5vw,20px);padding-inline:16px}
.core{width:100%;height:auto;display:block}
.core.wide{max-width:1180px}
.core.tall{display:none;max-width:400px}
@media (max-width:860px){
  .core.wide{display:none}
  .core.tall{display:block}
}
.core{max-width:100%;height:auto;display:block}
.core .dotstep{animation:dotstep 21s steps(60) infinite}
@keyframes dotstep{to{transform:rotate(360deg)}}
.core .ember{animation:ember 5s ease-in-out infinite}
@keyframes ember{0%,100%{opacity:.75}50%{opacity:1}}
.core .spark{animation:spark 9s ease-in-out infinite}
@keyframes spark{0%,100%{transform:rotate(0) scale(1)}50%{transform:rotate(45deg) scale(1.08)}}
/* a pulse runs the wire: in first, then out, so the eye follows the work */
.core .pulse{stroke-dasharray:26 460;stroke-dashoffset:486;
  animation:pulse 3.4s cubic-bezier(.5,0,.5,1) infinite}
.core .pulse.out{animation-delay:1.2s}
@keyframes pulse{0%{stroke-dashoffset:486}55%,100%{stroke-dashoffset:0}}
@keyframes spin{to{transform:rotate(360deg)}}

/* labels naming what goes in and what comes out */

/* --------------------------------------------------- how it works, 3 steps
   Greptile's pattern: one panel per step, each with its own diagram, and a
   number because these really are in order. */
.steps3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.step{position:relative;border:1px solid var(--line);border-radius:10px;
  background:var(--surface);padding:18px 18px 20px}
.step .dia{width:100%;height:auto;display:block;margin-bottom:16px}
.step .no{font-family:var(--mono);font-size:11px;color:var(--red);
  letter-spacing:.1em;display:block;margin-bottom:6px}
.step h3{margin:0 0 5px;font-size:15px;font-weight:500}
.step p{font-size:13.5px;color:var(--dim)}
.mono{font-family:var(--mono)}

/* the caret blinks, and the scan line crosses the filings, once each */
.caret{animation:blink 1.1s steps(2) infinite}
@keyframes blink{50%{opacity:0}}
.scan{animation:scan 3.4s cubic-bezier(.4,0,.6,1) infinite}
@keyframes scan{0%{transform:translateY(0)}45%{transform:translateY(80px)}
  55%{transform:translateY(80px)}100%{transform:translateY(0)}}

/* ------------------------------------------------------------ the thread */
.threadwrap{border:1px solid var(--line);border-radius:10px;background:var(--surface);
  padding:14px 16px 10px;overflow-x:auto}
.thread{width:100%;min-width:720px;height:auto;display:block}

/* ---------------------------------------------------- scroll reveal
   One orchestrated reveal, fired once per element, never replayed. */
.js .reveal{opacity:0;transform:translateY(14px);
  transition:opacity .6s cubic-bezier(.2,.7,.3,1),transform .6s cubic-bezier(.2,.7,.3,1)}
.js .reveal.on{opacity:1;transform:none}
.js .steps3 .reveal:nth-child(2){transition-delay:.09s}
.js .steps3 .reveal:nth-child(3){transition-delay:.18s}

/* skill rows answer the pointer */
.row{transition:background .12s}
.row:hover{background:var(--surface)}

@media (max-width:900px){
  .split{grid-template-columns:1fr;gap:36px}
  .split .t{text-align:center}
  .split h1,.split .lede{margin-inline:auto}
  .split .lede{text-align:center}
  .split .cta{justify-content:center}
  .steps3{grid-template-columns:1fr}
}

/* Motion is a preference, not a default. */
@media (prefers-reduced-motion:reduce){
  .core .dotstep,.core .ember,.core .spark,.core .pulse,
  .caret,.scan,.roll .track{animation:none}
  .core .pulse{stroke-dasharray:none;stroke-dashoffset:0}
  .core feTurbulence animate{display:none}
  .js .reveal{opacity:1;transform:none;transition:none}
}

/* ==========================================================================
   THE GATE, FREE ROWS, AND SKILL PAGES
   ========================================================================== */

/* ------------------------------------------------------------- free rows */
.frows{border-top:1px solid var(--line)}
.frow{display:grid;grid-template-columns:186px minmax(0,1fr) auto;gap:10px 24px;
  align-items:baseline;padding:14px 10px 14px 0;border-bottom:1px solid var(--hair);
  transition:background .12s}
.frow:hover{background:var(--surface)}
.frow code{font-family:var(--mono);font-size:13px;color:var(--fg)}
.frow .d{font-size:14px;color:var(--dim)}
.frow .go{font-size:13px;color:var(--dim);white-space:nowrap}
.frow:hover .go{color:var(--red)}

/* ------------------------------------------------------------------ gate
   Headspace's redeem layout inside Overmind's corner-bracket frame. The
   brackets are four spans rather than a border, so the frame reads as an
   instrument panel rather than a card. */
.gate-wrap{max-width:620px;margin-inline:auto}
.gate-panel{position:relative;border:1px solid var(--line);background:var(--surface);
  padding:36px 34px 30px;text-align:center}
.gate-panel .br{position:absolute;width:11px;height:11px;border:1px solid var(--red)}
.gate-panel .tl{top:-1px;left:-1px;border-right:0;border-bottom:0}
.gate-panel .tr{top:-1px;right:-1px;border-left:0;border-bottom:0}
.gate-panel .bl{bottom:-1px;left:-1px;border-right:0;border-top:0}
.gate-panel .br2{bottom:-1px;right:-1px;border-left:0;border-top:0}
.gate-eyebrow{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--red);margin-bottom:12px}
.gate-h{font-size:clamp(21px,2.5vw,27px);letter-spacing:-.03em;margin:0 0 10px}
.gate-sub{color:var(--dim);font-size:14.5px;max-width:42ch;margin:0 auto 24px}
#gate{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
#gate input{flex:1 1 240px;max-width:300px;height:38px;padding-inline:13px;
  background:var(--bg);border:1px solid #2A2D31;border-radius:6px;color:var(--fg);
  font-family:var(--mono);font-size:13.5px;letter-spacing:.08em}
#gate input::placeholder{color:#5E646C;letter-spacing:0;font-family:var(--sans)}
#gate input:focus{outline:none;border-color:var(--red)}
#gate.bad input{border-color:var(--red);animation:shake .32s}
#gate.ok input{border-color:#2E7D4F}
@keyframes shake{25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
.gate-note{min-height:1.3em;margin-top:12px;font-size:13px;color:var(--dim)}
#gate.bad ~ .gate-note{color:var(--red)}
#gate.ok ~ .gate-note{color:#5FBE8A}
.gate-foot{margin-top:20px;padding-top:18px;border-top:1px solid var(--hair);
  display:flex;gap:8px;justify-content:center;flex-wrap:wrap;font-size:13.5px;
  color:var(--dim)}
.gate-link{color:var(--fg);border-bottom:1px solid var(--red);padding-bottom:1px}
.gate-link:hover{color:var(--red)}

/* Unlocked is the highest-intent moment on the site, so it gets a panel
   with the next action in it rather than a line of text in an empty band. */
.gate-open{display:none;text-align:center;border:1px solid #3A3120;border-radius:10px;
  background:linear-gradient(180deg, rgba(245,166,35,.05), transparent 60%), var(--surface);
  padding:32px 30px 26px}
.gate-tick{display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;border-radius:50%;margin-bottom:14px;
  color:#0B0C0D;background:#F5A623}
.gate-open .gate-h{margin-bottom:8px}
.gate-open .gate-sub{margin-bottom:22px}
.gate-acts{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.relock{margin-top:20px;padding-top:16px;border-top:1px solid var(--hair);
  font-size:13px;color:var(--dim)}
.relock a{border-bottom:1px solid var(--line)}
.relock a:hover{color:var(--fg)}
.unlocked .gate-panel{display:none}
.unlocked .gate-open{display:block}
.unlocked .paidnote{display:none}

/* paid downloads stay inert until the code is in */
a.paid{opacity:.45;pointer-events:none}
.unlocked a.paid{opacity:1;pointer-events:auto}
.lockdot{display:inline-block;width:5px;height:5px;border-radius:50%;
  background:#3A3F45}
.unlocked .lockdot{background:var(--red)}
.paidnote{margin-top:16px;font-size:13.5px;color:var(--dim)}

/* ------------------------------------------------------------ skill page */
.skillhead{padding-block:clamp(44px,6vw,76px) clamp(30px,4vw,44px)}
.back{font-size:13px;color:var(--dim)}
.back:hover{color:var(--fg)}
.stitle{display:flex;align-items:center;gap:12px;margin-top:20px;flex-wrap:wrap}
.stitle h1{margin:0;font-size:clamp(28px,4vw,44px);letter-spacing:-.03em;max-width:none}
.stitle code{font-family:var(--mono);font-weight:600}
.pill{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;padding:4px 9px;border-radius:999px;border:1px solid}
.pill.free{color:var(--red);border-color:var(--red)}
.pill.paid{color:var(--dim);border-color:#2A2D31}
.skillhead .lede{margin:16px 0 0;text-align:left;margin-inline:0;max-width:58ch}
.smeta{display:flex;gap:18px;flex-wrap:wrap;margin-top:16px;
  font-family:var(--mono);font-size:11.5px;color:var(--dim)}
.skillhead .cta{margin-top:26px;display:flex;gap:10px;flex-wrap:wrap}
.sgrid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:40px}
.when{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.when li{padding-block:11px;border-bottom:1px solid var(--hair);font-size:14.5px;
  color:var(--dim)}
.facts{margin:0;border-top:1px solid var(--line)}
.fact{padding-block:13px;border-bottom:1px solid var(--hair)}
.fact dt{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--dim);margin-bottom:4px}
.fact dd{margin:0;font-size:14.5px}

@media (max-width:760px){
  .sgrid{grid-template-columns:1fr;gap:30px}
  .frow{grid-template-columns:minmax(0,1fr) auto;gap:3px 12px}
  .frow .d{grid-column:1/-1}
  .gate-panel{padding:28px 20px 24px}
}
@media (prefers-reduced-motion:reduce){#gate.bad input{animation:none}}

/* ==========================================================================
   SKILL SIGILS
   One mark per skill. The archetype is the stage, the detail is a hash of
   the skill's name. Animated at full size on the skill's own page; still in
   the catalogue, because sixty moving marks in a list is noise.
   ========================================================================== */
.sig{display:block}
.sigcell{display:flex;align-items:center}
.sigcell .sig{opacity:.75;transition:opacity .14s}
.row:hover .sigcell .sig{opacity:1}
.shead{display:grid;grid-template-columns:minmax(0,1fr) 200px;gap:40px;align-items:start}
.sigbig{justify-self:end;border:1px solid var(--line);border-radius:10px;
  background:var(--surface);padding:14px}

@media (prefers-reduced-motion:no-preference){
  .sig:not(.still) .drop{animation:sigdrop 2.6s ease-in infinite}
  @keyframes sigdrop{0%{transform:translateY(0);opacity:0}
    12%{opacity:1}55%{transform:translateY(46px);opacity:1}
    70%{transform:translateY(56px);opacity:0}100%{transform:translateY(56px);opacity:0}}

  .sig:not(.still) .scanbar{animation:sigscan 3s cubic-bezier(.4,0,.6,1) infinite}
  @keyframes sigscan{0%,100%{transform:translateY(0)}50%{transform:translateY(64px)}}

  .sig:not(.still) .arc{animation:sigarc 3.2s cubic-bezier(.3,.8,.3,1) infinite}
  @keyframes sigarc{0%{stroke-dashoffset:107}55%,100%{}}

  .sig:not(.still) .trace{stroke-dasharray:200;animation:sigdraw 3.4s ease-in-out infinite}
  @keyframes sigdraw{0%{stroke-dashoffset:200}45%,100%{stroke-dashoffset:0}}

  .sig:not(.still) .pt{animation:sigpt 3.2s ease-out infinite}
  @keyframes sigpt{0%{opacity:0;transform:translateY(6px)}
    20%,90%{opacity:1;transform:none}100%{opacity:0}}

  .sig:not(.still) .hot{transform-origin:60px 60px;
    animation:sighot 2.8s ease-in-out infinite}
  @keyframes sighot{0%,100%{transform:scale(1);opacity:1}
    50%{transform:scale(1.16);opacity:.82}}
}

@media (max-width:820px){
  .shead{grid-template-columns:1fr;gap:26px}
  .sigbig{justify-self:start}
  .sigcell{display:none}
}

/* ==========================================================================
   BACKGROUND
   Three fixed layers. The grid is the graph paper the rest of the design
   borrows from. A brighter band of the same grid sweeps across it, which is
   the scan line from the research diagrams repeated at page scale, so the
   motion is the system restated rather than a new effect. The grain is the
   same feTurbulence the ignition core uses, and it kills the banding that
   large flat blacks show on cheap panels.
   ========================================================================== */
:root{
  --grid: repeating-linear-gradient(to right, rgba(255,255,255,.018) 0 1px, transparent 1px 56px),
          repeating-linear-gradient(to bottom, rgba(255,255,255,.018) 0 1px, transparent 1px 56px);
  --grid-fade: radial-gradient(135% 105% at 50% 0%, #000 22%, rgba(0,0,0,.72) 62%, transparent 98%);
}

html::before,
body::before,
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:0}

/* the grid */
body::before{
  background-image:var(--grid);
  -webkit-mask-image:var(--grid-fade);
  mask-image:var(--grid-fade);
}

/* the scan: the same grid, brighter, behind a band that crosses the page.
   One mask layer, not two composited: the downward fade is a background
   layer painted in the page colour over the lines, which is simpler and
   does not depend on mask-composite. */
body::after{
  background-image:
    linear-gradient(to bottom, transparent 30%, rgba(8,9,10,.55) 70%, #08090A 96%),
    repeating-linear-gradient(to right, rgba(255,110,70,.34) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(to bottom, rgba(255,110,70,.34) 0 1px, transparent 1px 56px);
  -webkit-mask-image:linear-gradient(100deg, transparent 0%, #000 45%, #000 55%, transparent 100%);
  mask-image:linear-gradient(100deg, transparent 0%, #000 45%, #000 55%, transparent 100%);
  -webkit-mask-size:55% 100%;   mask-size:55% 100%;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:-60% 0;  mask-position:-60% 0;
  opacity:.30;
}

@media (prefers-reduced-motion:no-preference){
  body::after{animation:gridscan 13s linear infinite}
  @keyframes gridscan{
    from{-webkit-mask-position:-60% 0; mask-position:-60% 0}
    to  {-webkit-mask-position:160% 0; mask-position:160% 0}
  }
}
@media (prefers-reduced-motion:reduce){ body::after{opacity:0} }

/* the grain */
html::before{
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%22160%22%3E%3Cfilter%20id%3D%22n%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%220.8%22%20numOctaves%3D%223%22%20stitchTiles%3D%22stitch%22%2F%3E%3CfeColorMatrix%20type%3D%22saturate%22%20values%3D%220%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22160%22%20height%3D%22160%22%20filter%3D%22url%28%23n%29%22%20opacity%3D%220.5%22%2F%3E%3C%2Fsvg%3E");
  background-size:160px 160px;
  opacity:.04;
  mix-blend-mode:screen;
}

/* everything real sits above the three layers */
.nav,main,footer{position:relative;z-index:1}

/* ==========================================================================
   THE CATALOGUE AS RAILS
   One horizontal rail per stage. Cards snap, swipe on touch, and take arrows
   on a pointer. The scroller bleeds to the window edge but its padding lines
   the first card up with the headline above it.
   ========================================================================== */
.bar{position:sticky;top:56px;z-index:5;background:rgba(8,9,10,.9);
  backdrop-filter:blur(12px);border-block:1px solid var(--line)}
.barrow{display:flex;align-items:center;gap:16px;padding-block:11px;flex-wrap:wrap;
  font-size:13px;color:var(--dim)}
.chips{display:flex;gap:6px;margin-left:auto;flex-wrap:wrap}
.chip{font-family:var(--mono);font-size:11.5px;padding:4px 10px;border-radius:999px;
  border:1px solid var(--line);color:var(--dim);transition:.14s}
.chip:hover{color:var(--fg);border-color:#3A3F45}
.chip.here{color:var(--red);border-color:var(--red)}

.rails{padding-block:12px 40px}
.rail{padding-block:22px}
.railhead{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  padding-bottom:12px}
.railtitle h3{margin:0 0 2px;font-size:16px;font-weight:500;letter-spacing:-.015em}
.railtitle .n{font-family:var(--mono);font-size:11.5px;color:var(--dim)}
.railtitle .sep{opacity:.5}
.railnav{display:none;gap:6px}
.rn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;
  border-radius:50%;border:1px solid var(--line);background:transparent;color:var(--dim);
  cursor:pointer;transition:.14s}
.rn:hover{color:var(--fg);border-color:#3A3F45;background:var(--surface)}
.rail[data-pos="start"] .railnav,
.rail[data-pos="mid"] .railnav,
.rail[data-pos="end"] .railnav{display:flex}
.rail[data-pos="start"] .rn[data-dir="-1"],
.rail[data-pos="end"]   .rn[data-dir="1"]{opacity:.3;pointer-events:none}

.scroller{
  overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;
  padding-inline:max(24px, calc((100vw - 1000px) / 2 + 24px));
  /* the snapport is defined by scroll-padding, not padding: without this the
     browser rests one card in, because snap-align:start targets the scrollport
     edge rather than the padded content edge */
  scroll-padding-inline:max(24px, calc((100vw - 1000px) / 2 + 24px));
  padding-block:4px 10px;
}
.scroller::-webkit-scrollbar{display:none}
.scroller:focus-visible{outline:2px solid var(--red);outline-offset:-2px}
.track{display:flex;gap:14px;width:max-content}

/* the edge fade only appears on the side that has more to show */
.rail[data-pos="mid"] .scroller,
.rail[data-pos="end"] .scroller{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 72px, #000 100%);
  mask-image:linear-gradient(to right, transparent 0, #000 72px, #000 100%);
}
.rail[data-pos="start"] .scroller,
.rail[data-pos="mid"] .scroller{
  -webkit-mask-image:linear-gradient(to left, transparent 0, #000 72px, #000 100%);
  mask-image:linear-gradient(to left, transparent 0, #000 72px, #000 100%);
}
.rail[data-pos="mid"] .scroller{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 72px,
    #000 calc(100% - 72px), transparent 100%);
  mask-image:linear-gradient(to right, transparent 0, #000 72px,
    #000 calc(100% - 72px), transparent 100%);
}

.card{
  scroll-snap-align:start;flex:0 0 auto;width:244px;
  display:flex;flex-direction:column;gap:0;
  border:1px solid var(--line);border-radius:12px;background:var(--surface);
  padding:16px 16px 14px;transition:border-color .15s, background .15s, transform .15s;
}
.card:hover{border-color:#3A3F45;background:#14171A;transform:translateY(-2px)}
.card:focus-visible{outline:2px solid var(--red);outline-offset:2px}
.cardmark{display:flex;justify-content:center;padding:6px 0 12px}
.cardmark .sig{opacity:.8;transition:opacity .15s}
.card:hover .cardmark .sig{opacity:1}
.cardname code{font-family:var(--mono);font-size:13px;color:var(--fg);letter-spacing:-.01em}
.carddesc{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;margin-top:6px;font-size:13px;line-height:1.5;color:var(--dim);
  min-height:calc(3 * 1.5 * 13px)}
.cardfoot{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-top:12px;padding-top:10px;border-top:1px solid var(--hair)}
.cardtime{font-family:var(--mono);font-size:10.5px;color:var(--dim);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tierdot{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  padding:3px 8px;border-radius:999px;border:1px solid;white-space:nowrap}
.tierdot.free{color:var(--red);border-color:var(--red)}
.tierdot.paid{color:var(--dim);border-color:#2A2F36}

/* the mark comes alive on the card you are pointing at, not on all sixty */
@media (prefers-reduced-motion:no-preference){
  .card:hover .sig.still .drop{animation:sigdrop 2.6s ease-in infinite}
  .card:hover .sig.still .scanbar{animation:sigscan 3s cubic-bezier(.4,0,.6,1) infinite}
  .card:hover .sig.still .trace{stroke-dasharray:200;animation:sigdraw 3.4s ease-in-out infinite}
  .card:hover .sig.still .pt{animation:sigpt 3.2s ease-out infinite}
  .card:hover .sig.still .hot{transform-origin:60px 60px;animation:sighot 2.8s ease-in-out infinite}
  .scroller{scroll-behavior:smooth}
}

@media (max-width:640px){
  .bar{top:52px}
  .chips{margin-left:0;width:100%;overflow-x:auto;flex-wrap:nowrap;padding-bottom:2px}
  .chips::-webkit-scrollbar{display:none}
  .railnav{display:none}
  .card{width:210px}
}
