*,*::before,*::after{box-sizing:border-box}
/* The header is sticky, so a jump to a section has to stop clear of it or the heading lands
   underneath the menu. */
html{scroll-behavior:smooth;scroll-padding-top:76px}
:root{
  --ground:#0B1220; --panel:#131C2E; --panel-2:#0F1626; --line:#24304A;
  --text:#E9EEF9; --muted:#93A1BE;
  --machine:#2FD9C3; --human:#FF9E6B; --warn:#F5C451;   /* peach, not CAP's gold and not a red that reads "error" */
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
}
body{margin:0;background:var(--ground);color:var(--text);font-family:var(--sans);
  font-size:19.8px;line-height:1.65;-webkit-font-smoothing:antialiased}
.wrap{width:100%;padding:0 clamp(18px,4vw,56px)}
.inner{max-width:1240px;margin:0 auto}
a{color:var(--machine)}
h1,h2,h3{text-wrap:balance}

/* ---- header ------------------------------------------------------------- */
header.site{position:sticky;top:0;z-index:40;background:rgba(11,18,32,.92);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
header.site .inner{display:flex;align-items:center;gap:26px;
  min-height:58px;flex-wrap:wrap;padding:8px 0}
.brand{font-family:var(--mono);font-size:17.6px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text);text-decoration:none;font-weight:600;white-space:nowrap}
.brand b{color:var(--machine);font-weight:600}
header.site nav{display:flex;gap:20px;flex-wrap:wrap;margin-left:auto;align-items:center}
header.site nav a{font-family:var(--mono);font-size:15.4px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted);text-decoration:none}
header.site nav a:hover,header.site nav a:focus-visible{color:var(--text)}
/* Mobile menu: a checkbox and a label, no JavaScript. On a phone the row of links plus the quote
   button wrapped the header onto two lines. Dom, 2026-08-18: "menu should get to a burger". */
.navtoggle{position:absolute;width:1px;height:1px;opacity:0}
.burger{display:none;margin-left:auto;width:44px;height:36px;cursor:pointer;
  flex-direction:column;align-items:center;justify-content:center;gap:5px;
  border:1px solid var(--line)}
.burger span{display:block;width:18px;height:2px;background:var(--text)}
.navtoggle:focus-visible + .burger{outline:2px solid var(--machine);outline-offset:2px}
.btn{display:inline-block;font-family:var(--mono);font-size:15.95px;letter-spacing:.1em;
  text-transform:uppercase;text-decoration:none;padding:10px 18px;border:1px solid var(--machine);
  color:var(--machine);background:transparent;cursor:pointer;font-weight:600}
.btn:hover,.btn:focus-visible{background:var(--machine);color:var(--ground)}
.btn.solid{background:var(--machine);color:var(--ground)}
.btn.solid:hover,.btn.solid:focus-visible{background:var(--text);border-color:var(--text)}
.btn.ghost{border-color:var(--line);color:var(--text)}
.btn.ghost:hover,.btn.ghost:focus-visible{border-color:var(--text);background:transparent;color:var(--text)}

/* ---- generic section ---------------------------------------------------- */
/* TWO COLUMNS: the heading is a fixed label rail on the left, content takes the rest. A single
   centred column left half of a 1440px screen empty, and widening the paragraphs instead would
   push line length past readable. This uses the width without hurting the measure. */
section.blk{padding:clamp(46px,6vw,86px) 0;border-bottom:1px solid var(--line)}
section.blk:last-of-type{border-bottom:none}
section.blk .inner{display:grid;grid-template-columns:minmax(170px,230px) minmax(0,1fr);
  gap:clamp(24px,4.5vw,72px);align-items:start}
section.blk .inner > .content{min-width:0}
section.blk.wide .inner{display:block}
.eyebrow{font-family:var(--mono);font-size:14.85px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--machine);margin:0 0 16px}
h1{font-size:clamp(36.3px,4.6vw,63.8px);line-height:1.05;letter-spacing:-.028em;font-weight:700;
  margin:0 0 20px;max-width:19ch}
h2{font-family:var(--mono);font-size:clamp(16.5px,1.3vw,18.7px);letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--text);margin:0;
  padding-top:12px;border-top:2px solid var(--machine)}
h3{font-size:20.9px;font-weight:650;letter-spacing:-.008em;margin:0}
p{margin:0 0 16px;max-width:74ch;color:var(--muted)}
p:last-child{margin-bottom:0}
.sub{font-size:clamp(20.9px,1.9vw,25.3px);line-height:1.5;color:var(--text);max-width:62ch;
  margin:0 0 28px;font-weight:400}
/* With no buttons under it the sub IS the end of the hero, so it stops there. */
.hero .sub:last-child{margin-bottom:0}
.intro{max-width:74ch;margin:0 0 30px}
.ctarow{display:flex;gap:12px;flex-wrap:wrap}

/* ---- hero --------------------------------------------------------------- */
/* Dom, 2026-08-18: a dot grid across the top of the page, the lattice that reads as a technical
   product surface. It sits UNDER the glow: layer one is the light, layer two is the grid, and the
   ground colour is painted behind both. Rule 46's carve-out - this is lighting behind the text,
   never the text itself. */
/* compact: the quote page, where the form matters more than the headline */
section.hero.compact{padding:clamp(26px,3.2vw,42px) 0 clamp(20px,2.6vw,32px)}
section.hero.compact h1{font-size:clamp(35.2px,4.4vw,59.4px)}
section.hero.compact .sub{margin-bottom:0}
section.blk.tight{padding:clamp(26px,3vw,44px) 0}
section.hero{position:relative;overflow:hidden;
  padding:clamp(30px,3.4vw,52px) 0 clamp(20px,2.4vw,34px);
  border-bottom:1px solid var(--line);background-color:var(--ground);
  background-image:radial-gradient(120% 90% at 12% 0%,rgba(47,217,195,.10),transparent 62%)}

/* ---- brand hero (home only) --------------------------------------------- */
/* Dom, 2026-08-16: centred, the company name first, "run by humans" then "powered by AI" under it,
   and the block taller than the rest. The two lines carry the same warm/cool coding as the pipeline
   stages, so the whole positioning is legible from colour before a word is read. */
section.brandhero{position:relative;overflow:hidden;
  min-height:min(84vh,860px);display:flex;align-items:center;
  padding:clamp(60px,9vw,120px) 0;border-bottom:1px solid var(--line);
  background-color:var(--ground);
  background-image:radial-gradient(110% 80% at 50% 0%,rgba(47,217,195,.13),transparent 66%)}
/* The dot lattice is its own layer so it can FADE OUT before it reaches the type. Painted flat
   across the whole hero it sat behind the headline and read as dirt on the screen. It is strongest
   at the top edge and gone by the middle, which is where the eye reads it as a surface rather than
   a texture over the words. */
section.brandhero::before,section.hero::before{content:"";position:absolute;inset:0;
  pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px,rgba(255,255,255,.20) .9px,transparent 1.1px);
  background-size:24px 24px;
  -webkit-mask-image:linear-gradient(#000 0%,#000 66%,rgba(0,0,0,0) 96%);
  mask-image:linear-gradient(#000 0%,#000 66%,rgba(0,0,0,0) 96%)}
section.brandhero .wrap,section.hero .wrap{position:relative;z-index:1}
section.brandhero .inner{display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:0}
/* Dom, 2026-08-16: the name in the same monospace as the two lines under it, not the sans. It also
   matches the wordmark in the header, so the brand reads as one thing. Mono is wider per character
   than the sans, so the size steps down and the tracking goes positive to suit the face. */
section.brandhero .name{font-family:var(--mono);font-size:clamp(29.7px,6.3vw,90.2px);line-height:1.04;
  font-weight:700;letter-spacing:.06em;text-transform:uppercase;margin:0;max-width:none;
  color:var(--text)}
section.brandhero .lines{display:flex;flex-direction:column;gap:7px;margin:26px 0 0}
section.brandhero .lines span{font-family:var(--mono);font-weight:600;
  font-size:clamp(18.7px,2.3vw,31.9px);letter-spacing:.17em;text-transform:uppercase;line-height:1.25}
section.brandhero .lines .human{color:var(--human)}
section.brandhero .lines .machine{color:var(--machine)}
section.brandhero .sub{margin:38px 0 0;max-width:56ch;color:var(--muted);
  font-size:clamp(19.8px,1.75vw,23.65px)}
section.brandhero .ctarow{margin-top:34px;justify-content:center}

/* ---- cards -------------------------------------------------------------- */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:14px}
.card{background:var(--panel);border:1px solid var(--line);padding:20px 22px 22px;
  display:flex;flex-direction:column;gap:9px}
.card .meta{font-family:var(--mono);font-size:14.85px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--machine)}
.card p{margin:0;font-size:18.7px}

/* ---- steps -------------------------------------------------------------- */
ol.steps{list-style:none;counter-reset:s;margin:0;padding:0;display:flex;flex-direction:column}
ol.steps li{counter-increment:s;display:grid;grid-template-columns:74px 1fr;gap:22px;
  padding:20px 0;border-top:1px solid var(--line)}
ol.steps li:first-child{border-top:none;padding-top:0}
ol.steps .num{font-family:var(--mono);font-size:15.4px;letter-spacing:.1em;padding-top:3px;
  color:var(--text)}
ol.steps .body{display:flex;flex-direction:column;gap:7px}
ol.steps p{margin:0;font-size:19.25px}
/* the hybrid pair: what the processing does, what the person decides, in the same stage */
ol.steps .duo{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
  gap:14px 26px;margin-top:9px;padding-top:14px;border-top:1px solid var(--line)}
ol.steps .duo div{display:flex;flex-direction:column;gap:5px}
ol.steps .who{font-family:var(--mono);font-size:13.75px;letter-spacing:.16em;text-transform:uppercase}
ol.steps .who.m{color:var(--machine)}
ol.steps .who.h{color:var(--human)}
ol.steps .duo p{font-size:18.15px;color:var(--muted)}

/* ---- feature (the reveal) ----------------------------------------------- */
section.feature{background:var(--panel-2)}
section.feature h2{border-top-color:var(--human);color:var(--human)}
section.feature .ctarow{margin-top:8px}
section.feature .btn{border-color:var(--human);color:var(--human)}
section.feature .btn:hover,section.feature .btn:focus-visible{background:var(--human);color:var(--ground)}

/* ---- split -------------------------------------------------------------- */
.split{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:16px}
.col{background:var(--panel);border:1px solid var(--line);padding:22px}
.col .head{font-family:var(--mono);font-size:15.4px;letter-spacing:.13em;text-transform:uppercase;
  margin:0 0 16px;padding-bottom:12px;border-bottom:1px solid var(--line)}
.col.machine .head{color:var(--machine);border-bottom-color:var(--machine)}
.col.human .head{color:var(--human);border-bottom-color:var(--human)}
.col ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:12px}
.col li{display:grid;grid-template-columns:9px 1fr;gap:13px;font-size:18.7px;color:var(--muted)}
.col li::before{content:"";width:6px;height:6px;margin-top:9px}
.col.machine li::before{background:var(--machine)}
.col.human li::before{background:var(--human)}

/* ---- table -------------------------------------------------------------- */
.scroller{overflow-x:auto;border:1px solid var(--line);background:var(--panel)}
table{width:100%;border-collapse:collapse;font-size:18.15px;min-width:620px}
thead th{text-align:left;font-family:var(--mono);font-size:14.3px;letter-spacing:.13em;
  text-transform:uppercase;font-weight:500;color:var(--muted);padding:13px 16px;
  background:var(--panel-2);border-bottom:1px solid var(--line);white-space:nowrap}
tbody td{padding:12px 16px;border-bottom:1px solid var(--line);color:var(--muted);
  vertical-align:top;font-variant-numeric:tabular-nums}
tbody tr:last-child td{border-bottom:none}
tbody td:first-child{color:var(--text);font-weight:600}
tbody td:nth-child(2){font-family:var(--mono);color:var(--machine);white-space:nowrap}

/* ---- faq ---------------------------------------------------------------- */
.faq{display:flex;flex-direction:column}
.faq .qa{padding:22px 0;border-top:1px solid var(--line)}
.faq .qa:first-child{border-top:none;padding-top:0}
.faq h3{margin:0 0 8px}
.faq p{margin:0;font-size:19.25px}

/* ---- cta band ----------------------------------------------------------- */
section.cta{background:var(--panel-2)}
section.cta .inner{display:flex;gap:22px;align-items:center;justify-content:space-between;
  flex-wrap:wrap}
section.cta .line{font-size:clamp(22px,2.2vw,28.6px);color:var(--text);margin:0;max-width:34ch;
  font-weight:600;letter-spacing:-.015em}

/* ---- form --------------------------------------------------------------- */
/* Two fields to a row on a wide screen, so the whole form is visible without scrolling. Dom,
   2026-08-18, on the quote page: "save space here so we have the full form on page". */
form.quote{display:grid;grid-template-columns:1fr 1fr;gap:16px 22px;max-width:820px}
form.quote .field.wide,form.quote .small,form.quote .send{grid-column:1 / -1}
@media (max-width:640px){form.quote{grid-template-columns:1fr}}
.field{display:flex;flex-direction:column;gap:7px}
.field label{font-family:var(--mono);font-size:14.85px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--machine)}
.field .hint{font-size:16.5px;color:var(--muted);margin:0;min-height:19px}
/* The boxes sit at the BOTTOM of their row, not under their own hint. A hint that wraps onto a
   second line ("Vimeo, YouTube unlisted, Drive, Dropbox, anything we can watch") pushed its box
   down while the box beside it stayed up, and the whole form read as crooked. Dom, 2026-08-19.
   A reserved min-height on the hint only ever fixed the no-hint case, never the wrapping one. */
.field input,.field textarea{margin-top:auto}
.field input,.field textarea{background:var(--panel);border:1px solid var(--line);color:var(--text);
  font-family:var(--sans);font-size:19.8px;padding:12px 14px;width:100%}
.field input:focus,.field textarea:focus{outline:2px solid var(--machine);outline-offset:1px;
  border-color:var(--machine)}
.field textarea{min-height:92px;resize:vertical}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
form.quote .small{font-size:17.05px;color:var(--muted);margin:0}

/* ---- the frame and its tracks ------------------------------------------- */
.plate{aspect-ratio:16/9;border:1px solid var(--line);overflow:hidden;background:#000;
  margin:0 0 18px}
.plate .film{width:100%;height:100%;object-fit:cover;display:block}
/* Roomier than it needs to be on purpose: the rows have to cross the trigger line one at a time or
   they all arrive together and it stops being a thing you scroll. */
.tracks{display:grid;gap:14px}
/* The name sits ABOVE its waveform, not in a column beside it. Beside it, the label column pushed
   every waveform 120px in from the left while the picture above still started at the edge, and the
   two never lined up. Dom, 2026-08-19: "that is not centred." One left edge for the picture and all
   five tracks, one right edge, nothing to notice. */
.track{display:block;position:relative}
.tname{display:block;margin:0 0 4px;font-family:var(--mono);font-size:14.3px;letter-spacing:.16em;
  text-transform:uppercase}
.tname.machine{color:var(--machine)}
.tname.human{color:var(--human)}
.wave{width:100%;height:30px;display:block}
.wave.machine polygon{fill:var(--machine)}
.wave.human polygon{fill:var(--human)}
.caption{font-size:15.4px;color:var(--muted);margin:8px 0 0;max-width:90ch}
.hint-line{font-family:var(--mono);font-size:14.3px;color:var(--machine);margin:14px 0 0}

/* ---- listening ---------------------------------------------------------- */
/* The screenshot runs 25 percent wider than the text column (Dom, 2026-08-19). It is the one thing
   on the software page that has to be read, and at column width the track names in it are guesswork.
   The wrap's own padding still keeps it inside the window on a narrow screen. */
section.shotwrap{padding:clamp(16px,1.6vw,24px) 0 clamp(26px,3vw,44px)}
section.shotwrap .inner{max-width:1550px}
.shot{border:1px solid var(--line);overflow:hidden;background:#000}
.shot img{width:100%;height:auto;display:block}
.plate{position:relative}
/* SILENT IS A STATE NOBODY NOTICES, and a big play button over the film is worse. Dom, 2026-08-19:
   "not this ... something like a spectrum moving is enough to make understand there is sound going
   on, and a line cursor on top of the audio tracks." So: a small pill in the corner, filled in the
   accent so it reads as a control rather than a caption, carrying a play triangle when it is quiet
   and four dancing bars when it is not. The proof that sound is running is the movement, not a
   label: the bars, and a playhead crossing all five waveforms. */
.soundbtn{position:absolute;right:14px;bottom:14px;display:flex;align-items:center;gap:10px;
  background:var(--machine);border:0;color:var(--ground);cursor:pointer;padding:9px 15px;
  font-family:var(--mono);font-size:14.3px;letter-spacing:.12em;text-transform:uppercase}
.soundbtn:hover,.soundbtn:focus-visible{background:var(--text)}
.soundbtn .bars{display:flex;align-items:flex-end;gap:2.5px;height:15px}
.soundbtn .bars i{width:2.5px;height:100%;background:currentColor;
  animation:bar .9s ease-in-out infinite alternate;transform-origin:bottom}
.soundbtn .bars i:nth-child(2){animation-duration:.62s}
.soundbtn .bars i:nth-child(3){animation-duration:1.15s}
.soundbtn .bars i:nth-child(4){animation-duration:.78s}
@keyframes bar{from{transform:scaleY(.18)}to{transform:scaleY(1)}}
.soundbtn .lbl.on{display:none}
.soundbtn.on{background:var(--panel-2);color:var(--machine);box-shadow:inset 0 0 0 1px var(--machine)}
.soundbtn.on:hover,.soundbtn.on:focus-visible{background:var(--panel)}
.soundbtn.on .lbl.on{display:inline}
.soundbtn.on .lbl.off{display:none}
.hint-line .when-off{display:block}
.hint-line .when-on{display:none}
.layers.playing .hint-line .when-off{display:none}
.layers.playing .hint-line .when-on{display:block}

/* The playhead. One per track, driven by that track's own position, so a 22 second bed and a 52
   second music cue each read true instead of sharing an invented clock. */
.wavewrap{position:relative;display:block}
.cursor{position:absolute;top:-3px;bottom:-3px;left:0;width:2px;background:var(--text)}
/* It stays visible on a muted row: the row is still under the same picture, and a playhead that
   disappears where a track goes quiet reads as the page breaking. */
.track.off .cursor{background:var(--line)}

.track{background:none;border:0;padding:0;width:100%;text-align:left;font:inherit;color:inherit;
  cursor:pointer;display:block}
.tag{display:none;margin-left:10px}
/* A one-time invitation to try a solo, and then to come back to the mix. It blinks five times and
   then holds, and it is gone for good the moment somebody has done both. Dom, 2026-08-19: "we need
   something that blinks next to the tracks with an arrow that invites to put in solo and then click
   back to full mix, only one time, so the audience understand that." The blink is a hard on and off
   (steps), never a fade to grey, so what you read is always full strength (Rule 46). */
.nudge{margin-left:14px;color:var(--human);text-transform:none;letter-spacing:.02em;
  font-size:13.2px;display:none}
.nudge .n2{display:none}
/* One cue at a time, in the order somebody actually does it: press play, then solo a track, then
   come back to the mix. The play cue points UP at the button on the corner of the picture, which is
   directly above the right hand end of this first row. */
.cue-play{position:absolute;right:0;top:0;color:var(--human);font-size:13.2px;
  text-transform:uppercase;letter-spacing:.12em;animation:blink 1.15s steps(1) infinite}
.layers.playing .cue-play{display:none}
/* In full mix the invitation is on EVERY row, because every one of them can be soloed and that is
   the thing to understand (Dom, 2026-08-19). Only the first row blinks: five blinking lines is a
   fairground. Once a track is soloed the cue collapses to that one row, and the whole of it goes
   yellow, tag and arrow and words together, because leaving the solo is a different action. */
/* THE CUE TRAVELS: one row at a time, top to bottom, on a loop. Five of them blinking together is
   a Christmas tree (Dom, 2026-08-19), and one line moving down the stack says "any of these" better
   than five saying it at once. Each row gets the same animation with its slot delayed by a fifth of
   the cycle, so exactly one is lit at any moment. */
.layers.playing .nudge{display:inline;opacity:0;animation:chase 5.75s steps(1) infinite}
.layers.playing .track:nth-child(1) .nudge{animation-delay:0s}
.layers.playing .track:nth-child(2) .nudge{animation-delay:1.15s}
.layers.playing .track:nth-child(3) .nudge{animation-delay:2.3s}
.layers.playing .track:nth-child(4) .nudge{animation-delay:3.45s}
.layers.playing .track:nth-child(5) .nudge{animation-delay:4.6s}
@keyframes chase{0%{opacity:1}20%,100%{opacity:0}}
.layers.soloed .nudge{display:none;animation:none;opacity:1}
.layers.soloed .track.solo .nudge{display:inline;color:var(--warn)}
.tag{color:var(--warn)}
.layers.soloed .nudge .n1{display:none}
.layers.soloed .nudge .n2{display:inline;color:var(--warn)}
/* Going back to the full mix is a DIFFERENT action, so it is a different colour (Dom, 2026-08-19).
   And the cue does not disappear afterwards: in full mix it goes back to inviting a solo, which is
   how somebody works out they can try every track. It just stops blinking once they have been round
   once, so it reads as a label rather than an alarm. */
.nudge .n2{color:var(--warn)}
.soundbtn:not(.on){animation:blink 1.15s steps(1) infinite}
@keyframes blink{0%,49%{opacity:1}50%,99%{opacity:0}100%{opacity:1}}
@media (max-width:640px){.nudge{display:block;margin:4px 0 0}}
.track.solo .tag{display:inline}
/* Not playing changes COLOUR, it never fades: the waveform drops to the structural grey and the
   name to the muted token, both full strength (Rule 46). */
.track.off polygon{fill:var(--line)}
.track.off .tname{color:var(--muted)}
@media (max-width:640px){
  .tname{font-size:12.65px;letter-spacing:.12em}
  .wave{height:34px}
}

/* ---- footer ------------------------------------------------------------- */
footer.site{border-top:1px solid var(--line);padding:34px 0 44px;background:var(--panel-2)}
footer.site .inner{display:flex;gap:24px;justify-content:space-between;flex-wrap:wrap}
footer.site p{font-family:var(--mono);font-size:15.4px;color:var(--muted);margin:0 0 6px;max-width:52ch}
footer.site a{color:var(--muted);text-decoration:none;font-family:var(--mono);font-size:15.4px}
footer.site a:hover,footer.site a:focus-visible{color:var(--text)}
footer.site .links{display:flex;flex-direction:column;gap:6px}

:focus-visible{outline:2px solid var(--machine);outline-offset:2px}

/* ---- scroll reveal ------------------------------------------------------
   Dom, 2026-08-19: "modules that when you scroll, they appear piece by piece."
   Sections are the modules; the items inside one ride in behind it on a fixed CSS delay, so only
   the section is ever observed and there is no nested-fade timing to get wrong.
   The hiding is scoped to html.js, set by an inline script in the head. Without that a browser
   with JavaScript off would render a page of invisible text, which is the classic way this effect
   takes a whole site down. Safari on this Mac has no scroll-driven CSS animations, so it is an
   IntersectionObserver, about ten lines, and nothing else on the page needs JS.
   It is a scroll sweep and NOT an IntersectionObserver, which is what this was first: an
   observer only reports a CHANGE in intersection, so a section that was below the fold at
   load and above it after a jump never changes state and never fires. It stays invisible
   for the rest of the visit. That is not only a test artifact: Safari restores scroll
   position on a reload and on back, so everything above the restored point is blank.
   Comparing a rectangle against the viewport has no state to miss. */
html.js .reveal{opacity:0;transform:translateY(22px);
  transition:opacity .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}
html.js .reveal.in{opacity:1;transform:none}
html.js .reveal .stagger{opacity:0;transform:translateY(15px);
  transition:opacity .55s ease .05s,transform .55s ease .05s}
html.js .reveal.in .stagger{opacity:1;transform:none}
html.js .reveal.in .stagger:nth-child(2){transition-delay:.10s}
html.js .reveal.in .stagger:nth-child(3){transition-delay:.19s}
html.js .reveal.in .stagger:nth-child(4){transition-delay:.28s}
html.js .reveal.in .stagger:nth-child(5){transition-delay:.36s}
html.js .reveal.in .stagger:nth-child(6){transition-delay:.43s}
html.js .reveal.in .stagger:nth-child(7){transition-delay:.49s}
html.js .reveal.in .stagger:nth-child(8){transition-delay:.54s}
/* THE WHOLE ROW SLIDES IN, label and waveform together, from outside the block. Dom, 2026-08-19:
   "is not the waveform that slides, is the block." An earlier version drew the waveform in from
   left to right while the row sat still, which reads as a progress bar, not as a track being
   dropped into the mix.

   THE CLIPPING EDGE IS THE WINDOW, NOT THE COLUMN. Clipping at the track list made the rows appear
   out of thin air a few pixels from where they stop, which Dom saw immediately: "they seem boxed."
   The whole section clips instead, and the section runs the full width of the window, so a row
   travels in from off the screen. */
/* No label rail on this one: it is the wide variant, so the heading sits above and the picture and
   the five tracks are one column centred in the page. With the rail the whole block sat 150px right
   of the middle of the window, which is what Dom was pointing at with "centered like I show you". */
section.layers{overflow:hidden}
section.layers h2{margin-bottom:16px}
section.layers .intro{max-width:76ch;margin-bottom:0}
/* The demo is 20 percent narrower than the rest of the site, on purpose: it has to fit on one
   screen when somebody clicks How it works, and the picture is what sets the height. Narrowing the
   whole column keeps the frame and the five tracks on the same left and right edge (Dom, 2026-08-19:
   "this part must be 20% smaller so fit the page when I click how it works"). */
section.layers .inner{max-width:880px}
section.layers{padding:12px 0 clamp(26px,3vw,44px)}
/* Slower and shorter than it was. Dom, 2026-08-19: "the sliding of the tracks to the left and right
   are so fast; they must be way smaller." 115% of the row in 0.9s was a swoosh; 62% over 1.6s on a
   soft ease is a glide, and it still starts outside the picture's edge. */
html.js .track.froml{transform:translateX(-88%)}
html.js .track.fromr{transform:translateX(88%)}
html.js .track{opacity:0;transition:opacity 1s ease,transform 2.4s cubic-bezier(.22,.86,.24,1)}
html.js .track.in{opacity:1;transform:none}
html.js .plate{opacity:0;transform:scale(.985);
  transition:opacity .8s ease,transform 1.1s cubic-bezier(.16,.84,.28,1)}
html.js .plate.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{transition:none!important}
  html.js .reveal,html.js .reveal .stagger,html.js .plate{opacity:1;transform:none}
  /* THE TRACK SLIDE KEEPS RUNNING under Reduce Motion. It is not decoration, it is the thing the
     section demonstrates, and Dom asked for it twice on a Mac that has Reduce Motion switched on:
     "where is all the animation", then "that movement must be very slow and visible". The fades on
     everything else still honour the setting. */
  html.js .track{transition:opacity 1s ease,
    transform 2.4s cubic-bezier(.22,.86,.24,1)!important}}
@media (max-width:900px){
  section.blk .inner{display:block}
  h2{margin-bottom:22px}
  header.site .inner{position:relative;flex-wrap:nowrap}
  .burger{display:flex}
  header.site nav{display:none;position:absolute;top:calc(100% + 9px);left:0;right:0;
    flex-direction:column;align-items:stretch;gap:0;padding:6px 0;
    background:var(--panel);border:1px solid var(--line)}
  header.site nav a{padding:14px 20px;font-size:16.5px}
  header.site nav a.btn{margin:8px 20px 12px;text-align:center}
  .navtoggle:checked ~ nav{display:flex}
}
@media (max-width:640px){
  ol.steps li{grid-template-columns:1fr;gap:8px}
  section.cta .inner{align-items:flex-start}
}
