/* ═══════════════════════════════════════════════════════════════════════════════
   Plan2Ace landing stylesheet

   Structure, rhythm and card geometry are modelled on finozest home-one (measured,
   not copied: 1290px container, 130px section rhythm, 5px spacing base, 20px card
   radius, 8px buttons, weight 400 everywhere, hierarchy from size alone, and
   border-OR-shadow-OR-neither). Colour is entirely Plan2Ace: chroma arrives as
   light emerald tints carrying ink text, and brand emerald sits where the
   reference puts black.

   Heading face: Spline Sans throughout. The reference's display face is paid and
   unlicensable; what has to survive the substitution is the ~1.28 ratio spine
   (17 → 22 → 30 → 35 → 45 → 60 → 75), not the face.

   Scroll choreography is driven by three custom properties written by the inline
   script in index.html: --nav-p, --hero-p, --stage-p, plus the .over-hero class
   it sets while any part of the hero is still under the header. All geometry
   lives here.
   Every resting value below is the FINAL state, so a page with no script, a
   viewport under 992px, and prefers-reduced-motion all land on the same static
   layout, which is therefore the one that gets exercised constantly.
   ═══════════════════════════════════════════════════════════════════════════ */

@font-face{
  font-family:"Spline Sans";
  src:url("assets/splinesans.woff2") format("woff2");
  font-weight:300 700;
  font-display:swap;
  font-style:normal;
}

:root{
  /* Ink + paper */
  --ink:#141817;
  --muted:#565C5A;
  --paper:#F7F8F8;
  --surface:#FFFFFF;
  --sunken:#EEF0EF;
  --line:#DEE0DF;

  /* Night bands */
  --night:#0A0C0B;
  --night-card:#121614;
  --on-night:#F2F5F4;
  --on-night-muted:#AFB7B4;

  /* Emerald */
  --em-deep:#0C7A52;
  --em-deeper:#0A5C3C;
  --em-darkest:#06402B;
  --em-bright:#2BD17E;

  /* Luminance-matched tints. These carry ink text at 13:1 or better.
     L 0.53 / 0.88 / 0.69, matching the reference's three card fills exactly, but
     taken across three different hues so the stack doesn't read as one colour. */
  --tint-a:#7AD2AF;   /* emerald, L .53 */
  --tint-gold:#FFF1C6;/* gold,    L .88 */
  --tint-warm:#FFD097;/* warm,    L .69 */
  --tint-b:#E4F6EF;
  --tint-c:#AEE3CE;
  --gold:#FFDA63;
  --gold-pale:#FFF1C6;

  /* Scroll progress. Defaults are the resting/final state. */
  --nav-p:0;
  --hero-p:0;
  --stage-p:1;

  --head-h:64px;
  /* Every sticky layer clears the bar by this much, so nothing ever tucks under it. */
  --stick:calc(var(--head-h) + 14px);
}

*,*::before,*::after{box-sizing:border-box}

html{
  scroll-behavior:smooth;
  scroll-padding-top:88px;
  -webkit-text-size-adjust:100%;
  interpolate-size:allow-keywords;
}

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font:400 17px/27px "Spline Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

h1,h2,h3{font-weight:400;letter-spacing:normal;margin:0}
p,figure,blockquote{margin:0}
img,svg{display:block;max-width:100%}
ul,ol{margin:0;padding:0;list-style:none}
a{color:var(--em-deeper);text-underline-offset:3px}

/* Focus is specified, never removed. Emerald on light bands, bright emerald on
   night and deep-emerald bands where #0C7A52 would not be a visible ring. */
:focus-visible{outline:2px solid var(--em-deep);outline-offset:3px;border-radius:4px}
.night :focus-visible,.deep :focus-visible{outline-color:var(--em-bright)}

.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

.skip{
  position:absolute;left:16px;top:-100px;z-index:1000;
  background:var(--ink);color:#fff;padding:12px 18px;border-radius:8px;text-decoration:none;
  transition:top 140ms ease;
}
.skip:focus-visible{top:16px}

.wrap{max-width:1290px;margin-inline:auto;padding-inline:24px;width:100%}

.section{padding:130px 0}
.night{background:var(--night);color:var(--on-night)}
.night p{color:var(--on-night-muted)}
.sunken{background:var(--sunken)}
.deep{background:var(--em-darkest);color:#fff}

.lead{max-width:720px;margin-bottom:70px}
.lead.center{margin-inline:auto;text-align:center}
.lead h2{margin-bottom:20px}
.lead p{font-size:20px;line-height:32px}

h1{font-size:clamp(35px,4.4vw,60px);line-height:1.16}
h2{font-size:clamp(28px,3.2vw,45px);line-height:1.22}
h3{font-size:clamp(25px,2.4vw,35px);line-height:1.28}
.display{font-size:clamp(35px,5.4vw,75px);line-height:1.05}

/* Section reveals. Only armed inside .motion, so nothing is ever hidden by an
   animation that might not run. */
.motion .reveal{opacity:0;transform:translateY(12px);
  transition:opacity .6s ease,transform .6s cubic-bezier(.16,.84,.44,1)}
.motion .reveal.is-in{opacity:1;transform:none}


/* ── Buttons ─────────────────────────────────────────────────────────────────
   63px tall, 8px radius, 17/25 padding, 15px internal gap. Hover is a circular
   wipe flooding up from the bottom edge (truncated at scale 2.2, because full
   coverage lands by ~scale 2 and the rest is overshoot), plus a duplicate label sliding
   into place on text-only buttons. Press is a 90ms scale, so touch gets feedback
   where hover cannot reach.
   ponytail: the wipe ships on every button, the duplicate-label slide only on
   text-only ones. Duplicating the App Store lockup doubles its markup to buy an
   effect the glyph hides anyway. */
.btn{
  position:relative;isolation:isolate;overflow:hidden;
  display:inline-flex;align-items:center;gap:15px;
  padding:17px 25px;min-height:63px;
  border:1px solid rgba(20,24,23,.2);border-radius:8px;
  font-family:inherit;font-size:16px;line-height:27px;font-weight:400;
  text-decoration:none;cursor:pointer;
  transition:transform 90ms ease;
}
.btn:active{transform:scale(.985)}

.btn-wipe{
  position:absolute;left:50%;top:100%;width:130%;aspect-ratio:1;
  translate:-50% 0;border-radius:50%;
  transform:scale(0);transform-origin:50% 0;
  transition:transform 200ms ease-out;z-index:-1;
}
.btn:hover .btn-wipe{transform:scale(2.2)}

.btn-faces{position:relative;display:block;overflow:hidden;height:27px}
.btn-face{display:block;transition:transform 240ms cubic-bezier(.4,.1,.2,1)}
.btn-face-2{position:absolute;inset:0;transform:translateY(100%)}
.btn:hover .btn-face{transform:translateY(-100%)}
.btn:hover .btn-face-2{transform:translateY(0)}

.btn-primary{background:var(--em-deep);color:#fff;border-color:transparent}
.btn-primary .btn-wipe{background:var(--em-deeper)}

.btn-ghost{background:var(--surface);color:var(--ink)}
.btn-ghost .btn-wipe{background:var(--sunken)}

.btn-onlight{background:#fff;color:var(--ink);border-color:transparent}
.btn-onlight .btn-wipe{background:var(--tint-b)}

.btn-sm{min-height:46px;padding:9px 20px;gap:10px}
.btn-lg{min-height:70px;padding:18px 32px}

.apple{width:20px;height:26px;flex:0 0 auto;fill:currentColor}
.btn-lg .apple{width:24px;height:30px}
.arrow{width:18px;height:18px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

.store-label{display:block;text-align:left}
/* .82 measured 4.15:1 for this 12px line on the emerald primary, just under AA. */
.store-label small{display:block;font-size:12px;line-height:14px;opacity:.92}
.store-label b{display:block;font-weight:400;font-size:19px;line-height:24px}
.btn-lg .store-label b{font-size:22px;line-height:26px}

.cta-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:35px}
.cta-fine{margin-top:16px;font-size:15px;color:var(--muted)}
.cta-fine-dark{color:rgba(255,255,255,.82)}


/* ── Header ──────────────────────────────────────────────────────────────────
   Fixed, 64px, never changes height. Transparent at rest; the scrolled state is
   a shadow bloom. The paper veil under it is a deliberate departure from the
   reference (which stays transparent at every scroll position): this page has
   two night bands, and ink nav links over #0A0C0B would be unreadable. */
.head{position:fixed;inset:0 0 auto;height:var(--head-h);z-index:900}
/* Solid for the bar's own height, then a 10px fade. A gradient that starts fading
   inside the bar lets scrolling content half-show through it, which reads as the
   content colliding with the nav rather than passing behind it. */
.head-shadow{
  position:absolute;inset:0 0 -8px;pointer-events:none;
  background:linear-gradient(var(--paper) 0 92%,rgba(247,248,248,0));
  box-shadow:0 40px 80px rgba(20,24,23,.10);
  opacity:var(--nav-p);
}
.head-inner{
  position:relative;height:100%;
  max-width:1290px;margin-inline:auto;padding-inline:24px;
  display:flex;align-items:center;gap:16px;
}
.head-brand{display:flex;align-items:center;gap:9px;color:var(--ink);
  text-decoration:none;font-size:17px;min-height:44px;transition:color 160ms ease}
.head-brand img{border-radius:6px;width:24px;height:24px}
.head-nav{margin-left:auto;display:flex;gap:4px}
.head-nav a{
  padding:9px 12px;border-radius:6px;font-size:15px;font-weight:500;
  color:var(--muted);text-decoration:none;transition:color 160ms ease;
}
.head-nav a:hover{color:var(--ink)}
.head .btn{margin-left:6px}
/* 44px is the touch floor, and this button is the only header control on phones. */
.head .btn-sm{min-height:44px;padding:9px 17px;font-size:15px}


/* ── 1 · Hero ────────────────────────────────────────────────────────────────
   Paper, matching the app's own home screen. Resting layout: headline block,
   then a three-column row of cards. Inside .motion it becomes a 300vh stage:
   the headline dissolves in place over the first 420px, then the cards arrive
   as you scroll. */
.hero{position:relative;padding-top:calc(var(--head-h) + 28px);overflow:clip}
.hero::before{
  content:"";position:absolute;inset:-10% -10% auto -10%;height:70%;z-index:0;
  background:radial-gradient(52% 60% at 62% 8%,rgba(24,176,116,.16),transparent 70%),
             radial-gradient(38% 46% at 22% 0%,rgba(255,218,99,.14),transparent 72%);
  pointer-events:none;
}
.hero > *{position:relative}

/* ── Hero load choreography ───────────────────────────────────────────────────
   One sequence, once, on load: the exam date, then the week counting toward it
   one day at a time, then the sentence that explains what the week is for. It
   runs off the countdown because the countdown is the idea.

   Every keyframe has a `from` and no `to`, so the end state is each element's own
   resting style. Nothing here is what makes the hero visible: delete this block,
   or land in reduced-motion where the global rule collapses the durations, and
   the fold is already correct. `backwards` only borrows the start state during
   the delay. Total run is under 1.1s, because a landing page that makes you wait
   to read it has spent its first impression on itself. */
@keyframes rise{from{opacity:0;translate:0 14px}}
@keyframes rise-day{from{opacity:0;translate:0 18px;scale:.94}}

.strip-line{animation:rise .5s cubic-bezier(.16,.84,.44,1) backwards}
.arc li{animation:rise-day .5s cubic-bezier(.16,.84,.44,1) backwards}
.arc li:nth-child(1){animation-delay:.10s}
.arc li:nth-child(2){animation-delay:.16s}
.arc li:nth-child(3){animation-delay:.22s}
.arc li:nth-child(4){animation-delay:.28s}
.arc li:nth-child(5){animation-delay:.34s}
.arc li:nth-child(6){animation-delay:.40s}
/* Exam day arrives last and alone, which is the one beat worth holding. */
.arc li:nth-child(7){animation-delay:.52s;animation-duration:.6s}
.hero-head h1{animation:rise .6s cubic-bezier(.16,.84,.44,1) .40s backwards}
.hero-head .lede{animation:rise .6s cubic-bezier(.16,.84,.44,1) .48s backwards}
.hero-head .cta-row{animation:rise .6s cubic-bezier(.16,.84,.44,1) .56s backwards}
.hero-head .cta-fine{animation:rise .6s cubic-bezier(.16,.84,.44,1) .62s backwards}

.hero-head{text-align:center;z-index:1}
.hero-head h1{max-width:900px;margin:0 auto 20px}
.hero-head .lede{max-width:660px;margin:0 auto;color:var(--muted);font-size:19px;line-height:30px}
.hero-head .cta-row{justify-content:center}
.hero-head .cta-fine{text-align:center}

.motion .hero-head{
  position:sticky;top:var(--stick);
  transform:scale(calc(1 - .12 * var(--hero-p)));
  opacity:calc(1 - var(--hero-p));
}
/* Once dissolved it must stop catching clicks over the stage below it. */
.motion.hero-off .hero-head{visibility:hidden}

/* Exam strip: the positioning stated as an object before a word is read. */
.strip{margin-bottom:clamp(26px,3.2vh,38px)}
.strip-line{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:14px;
  margin-bottom:clamp(16px,2.2vh,24px)}
.strip-course{font-size:15px;color:var(--muted)}
.strip-date{
  display:inline-flex;align-items:center;gap:8px;
  background:var(--surface);border-radius:100px;padding:7px 16px 7px 13px;
  font-size:15px;box-shadow:0 12px 28px rgba(20,24,23,.06);
}
.strip-date svg{width:16px;height:16px;fill:none;stroke:var(--em-deep);stroke-width:1.7;
  stroke-linecap:round}

/* The countdown states the position before a word is read, then gets out of the
   way. It is a supporting object, not a display element: the headline owns the
   fold, so the numbers stay near body scale and the whole band sits well inside
   the measure of the text below it.

   The days used to hang along a valley. Seven different vertical offsets read as
   a broken baseline long before they read as a curve, and at phone widths, where
   the cells narrow to fit, it read as nothing but misalignment. Now: one row,
   with exam day the only thing lifted out of it.

   Every size is fluid, so the same rules hold from 320px to 1440px and the mobile
   block below has nothing left to override. */
.arc{
  position:relative;display:flex;justify-content:center;align-items:flex-end;
  gap:clamp(4px,.6vw,8px);max-width:560px;margin-inline:auto;
}
.arc li{
  position:relative;flex:1 1 0;min-width:0;
  display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:clamp(7px,.8vw,10px) clamp(2px,.5vw,7px) clamp(9px,.9vw,12px);
  border-radius:12px;color:var(--muted);
}
.arc small{font-size:clamp(9px,.7vw,10px);letter-spacing:.07em}
.arc b{font-weight:400;font-size:clamp(17px,1.6vw,22px);line-height:1.2;color:var(--ink)}
.arc .is-sel{background:var(--em-deep);color:rgba(255,255,255,.88)}
.arc .is-sel b{color:#fff}
/* The lift is the whole point of exam day, so it scales with everything else. */
.arc .is-exam{
  background:var(--gold);color:rgba(20,24,23,.74);
  transform:translateY(calc(-1 * clamp(7px,.8vw,10px)));
}
.arc .is-exam b{color:var(--ink)}

/* Stage */
.hero-stage{margin-top:80px;padding-bottom:60px}
.motion .hero-stage{height:300vh;margin-top:24px;padding-bottom:0}
.motion .stage{
  /* --stage-h is the usable height inside the pinned box; the phone is sized from
     it so the screens fill the viewport instead of floating in dead space. */
  --stage-h:calc(100vh - var(--stick) - 38px);
  position:sticky;top:var(--stick);z-index:2;
  height:calc(100vh - var(--stick) - 14px);min-height:520px;
  overflow:hidden;display:flex;align-items:center;padding-block:12px;
}
/* Wider middle column than the resting layout: the phone is the point of the stage,
   and the promise cards read fine one notch narrower. */
.motion .stage-grid{grid-template-columns:1fr 1.34fr 1fr}
/* The pinned box is a fixed slice of the viewport and clips what it can't hold, so
   the content is sized off viewport height, not off nothing. At 1100px+ tall these
   clamps all sit at their max and the layout is the full-size one; below that they
   shrink instead of running under the bar. */
/* Height-derived, not a vh guess: the width that makes a 290/628 screen plus its
   10px bezel exactly as tall as the box. Capped by the column, floored at 210px. */
.motion .phone{width:min(100%,400px,max(210px,calc((var(--stage-h) - 20px) * 290 / 628 + 20px)))}
.motion .promise,
.motion .daycard,
.motion .gridcard{padding:clamp(18px,2.6vh,30px)}
.motion .stage-col{gap:clamp(14px,3vh,30px)}
.motion .stage-right{gap:clamp(18px,3.4vh,40px)}
.motion .promise h2{font-size:clamp(18px,2.4vh,22px);line-height:1.4}
.motion .promise p{font-size:clamp(14px,1.8vh,16px);line-height:1.62}
/* The right column is the tallest of the three on short windows, because the heat grid's
   height follows its own width, so cap that too or it alone decides the overflow. */
.motion .card-label{margin-bottom:clamp(10px,1.8vh,18px)}
.motion .daycard figcaption,
.motion .gridcard figcaption{margin-top:clamp(9px,1.6vh,16px)}
.motion .grid84{max-width:clamp(210px,42vh,340px);margin-inline:auto}
.stage-grid{display:grid;gap:36px}

/* Progress → per-element entrance. --s/--e are the scroll window in stage
   progress; --o is a quadratic ease-out of it. Tuning is a number in the HTML. */
[data-in]{
  --p:clamp(0,calc((var(--stage-p) - var(--s)) / (var(--e) - var(--s))),1);
  --o:calc(1 - (1 - var(--p)) * (1 - var(--p)));
}
.motion .promise,
.motion .daycard,
.motion .gridcard{
  opacity:var(--p);
  transform:translateY(calc((1 - var(--o)) * 720px));
  will-change:transform,opacity;
}

.stage-col{display:flex;flex-direction:column;gap:30px}
.stage-right{gap:40px}

/* Three fills, three hues, one luminance rhythm. All-emerald read as one green
   block; these are the reference's own L 0.53 / 0.88 / 0.69 steps taken across the
   brand's emerald, gold and warm ramps instead of down a single one. Ink text sits
   at 13:1 or better on all three. The mark is bare: no chip, no circle behind it. */
.promise{border-radius:20px;padding:30px}
.promise-top{display:flex;justify-content:space-between;align-items:flex-start;
  gap:24px;margin-bottom:14px}
.promise h2{font-size:22px;line-height:30.8px;margin-top:-5px;max-width:215px}
.promise p{font-size:16px;line-height:26px;color:rgba(20,24,23,.74)}
.promise-mark{
  width:30px;height:31px;flex:0 0 auto;opacity:.5;
  fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;
}
.promise-1{background:var(--tint-a)}
.promise-2{background:var(--tint-gold)}
.promise-3{background:var(--tint-warm)}

/* Phone: the frame is CSS, not an asset. No notch, no hardware detail: it is a
   mask, not a product render. */
.phone{
  width:min(100%,320px);margin-inline:auto;
  padding:10px;border-radius:44px;background:var(--ink);
  box-shadow:0 37px 85px rgba(20,24,23,.20);
}
.phone-sm{width:min(100%,290px)}
/* On the night band an ink bezel vanishes into the background and the screen reads
   as a floating slab colliding with whatever is above it. Lift it until it reads as
   a frame. */
.night .phone{background:#2C3532;box-shadow:0 37px 85px rgba(0,0,0,.55)}
.phone-screens{position:relative;border-radius:34px;overflow:hidden;aspect-ratio:290/628}
.phone-screens > .shot{position:absolute;inset:0;height:100%}

/* Screenshot slots. div.shot is the placeholder; img.shot is the real thing.
   Both ship, so swapping one in is a single tag change and no CSS edit. */
.shot{width:100%;aspect-ratio:290/628;border-radius:inherit;display:block}
div.shot{
  background-color:var(--sunken);
  background-image:repeating-linear-gradient(-45deg,
    rgba(20,24,23,.028) 0 1px,transparent 1px 4px);
  box-shadow:inset 0 0 0 1px var(--line);
  display:grid;place-items:center;text-align:center;padding:16px;
}
div.shot::after{
  content:"Screenshot\A" attr(data-shot);
  white-space:pre-line;font-size:13px;line-height:1.4;color:#646C69;
}
img.shot{object-fit:cover}

.shot-2,.shot-3{opacity:0}
.motion .shot-2{opacity:1;transform:translateX(calc((1 - var(--o)) * 340px));will-change:transform}
.motion .shot-3{opacity:1;transform:translateY(calc((1 - var(--o)) * 700px));will-change:transform}

/* Right column */
.daycard,.gridcard{border-radius:20px;padding:30px}
.daycard{background:var(--sunken)}
.gridcard{background:var(--surface);box-shadow:0 30px 70px rgba(20,24,23,.08)}
.card-label{font-size:13px;color:var(--muted);margin-bottom:18px}
.day-list li{
  display:flex;justify-content:space-between;align-items:baseline;gap:20px;
  padding:11px 0;border-top:1px solid rgba(20,24,23,.09);font-size:16px;
}
.day-list li:first-child{border-top:0}
.day-list b{font-weight:400;font-size:14px;color:var(--muted);white-space:nowrap}
.daycard figcaption,.gridcard figcaption{margin-top:16px;font-size:13px;color:var(--muted)}

.grid84{display:grid;grid-template-columns:repeat(12,1fr);gap:4px}
.grid84 span{aspect-ratio:1;border-radius:3px;background:var(--line)}
.grid84 .g1{background:var(--tint-c)}
.grid84 .g2{background:#4FC191}
.grid84 .g3{background:var(--em-deep)}


/* ── 2 · Five ways to work it ────────────────────────────────────────────────
   Resting layout: five steps, each carrying its own phone. Inside .motion the
   phone pins beside the steps and its screen changes as each step reaches the
   middle of the viewport; the inline phones step aside. */
.sc{display:grid;gap:70px}
.sc-pin{display:none}
.sc-steps{display:grid;gap:90px}
.sc-step{max-width:640px}
/* Position in the five, not an editorial section number: it tells you how far
   through the pinned sequence you are. */
.step-n{font-size:14px;color:var(--em-bright);margin-bottom:14px}
/* The denominator recedes by hue, not by opacity. Dimming it stacked with the
   inactive-step dim and put it under 3:1. */
.step-n span[aria-hidden]{color:var(--on-night-muted)}
.sc-step h3{margin-bottom:16px}
.sc-step > p{font-size:18px;line-height:29px}
.sc-inline{margin:30px 0 0}
.sc-inline figcaption{margin-top:18px;font-size:15px;color:var(--on-night-muted);max-width:340px}
.sc-pin .shot{opacity:0;transition:opacity 450ms ease}
.sc-pin .shot.is-on{opacity:1}


/* ── 3 · Am I on track? ──────────────────────────────────────────────────────*/
.ready-grid{display:grid;gap:60px;align-items:center}
.ready-grid h2{margin-bottom:24px}
.ready-grid > div p + p{margin-top:18px}
.ready-grid > div p{font-size:18px;line-height:29px}

.gauge{background:var(--night-card);border-radius:20px;padding:40px}
.gauge-read{display:flex;align-items:baseline;gap:6px;color:var(--on-night)}
.gauge-read b{font-weight:400;font-size:clamp(50px,6vw,75px);line-height:1.05}
.gauge-pct{font-size:26px}
.gauge-band{margin-left:12px;font-size:17px;color:var(--on-night-muted)}
.gauge-track{position:relative;height:12px;border-radius:100px;background:#222926;margin:28px 0 20px}
.gauge-range{position:absolute;left:62%;width:12%;top:0;bottom:0;border-radius:100px;
  background:rgba(43,209,126,.28)}
.gauge-fill{position:absolute;left:0;top:0;bottom:0;width:68%;border-radius:100px;
  background:linear-gradient(90deg,var(--em-deep),var(--em-bright))}
.gauge figcaption{font-size:15px;color:var(--on-night-muted)}
.motion .gauge .gauge-fill{width:0;transition:width 1s cubic-bezier(.2,.8,.2,1) 120ms}
.motion .gauge.is-in .gauge-fill{width:68%}


/* ── 4 · Name your exam ──────────────────────────────────────────────────────*/
.covers{text-align:center}
.covers .display{max-width:14ch;margin:0 auto 30px}
.covers-lede{max-width:680px;margin:0 auto;color:var(--muted);font-size:19px;line-height:30px}
.pills{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin:45px 0 25px}
.pills li{
  background:var(--surface);border-radius:100px;padding:9px 22px;
  font-size:18px;line-height:28px;box-shadow:0 12px 28px rgba(20,24,23,.05);
}
.pills li:nth-child(1){background:var(--tint-b);box-shadow:none}
.pills li:nth-child(3){background:var(--gold-pale);box-shadow:none}
.pills li:nth-child(5){background:var(--tint-c);box-shadow:none}
.covers-note{max-width:560px;margin:0 auto;color:var(--muted);font-size:16px}


/* ── 5 · Maker note ──────────────────────────────────────────────────────────*/
.maker{margin:0 auto;max-width:860px;text-align:center}
.maker p{font-size:clamp(22px,2.4vw,30px);line-height:1.36}
.maker footer{display:flex;align-items:center;justify-content:center;gap:12px;
  margin-top:30px;font-size:16px;color:var(--muted)}
.maker footer img{border-radius:9px}
.maker footer b{font-weight:500;color:var(--ink)}


/* ── 6 · FAQ ─────────────────────────────────────────────────────────────────*/
/* One column. Two columns shared a grid row, so opening an item on the left grew
   the row and left a hole under the item on the right, and `:last-child` put the
   closing rule under one column only. An accordion reads vertically anyway. */
.faq{max-width:820px;margin-inline:auto}
.faq details{border-top:1px solid var(--line)}
.faq details:last-child{border-bottom:1px solid var(--line)}
.faq summary{
  display:flex;justify-content:space-between;align-items:center;gap:20px;
  padding:22px 4px;cursor:pointer;font-size:18px;line-height:28px;list-style:none;
  border-radius:6px;transition:color 120ms ease;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--em-deeper)}
.faq .chev{width:20px;height:20px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;
  transition:transform 180ms ease}
.faq details[open] .chev{transform:rotate(180deg)}
.faq details > p{padding:0 4px 26px;max-width:56ch;color:var(--muted)}
/* Chromium-only today; elsewhere the accordion snaps, which is the native behaviour. */
.faq details::details-content{
  block-size:0;overflow:hidden;
  transition:block-size 260ms ease,content-visibility 260ms allow-discrete;
}
.faq details[open]::details-content{block-size:auto}


/* ── 7 · Final CTA ───────────────────────────────────────────────────────────*/
.final{text-align:center;max-width:820px}
.final h2{margin-bottom:20px}
.final > p{font-size:19px;line-height:30px;color:rgba(255,255,255,.86)}
.final .btn{margin-top:35px}


/* ── Dock + footer ───────────────────────────────────────────────────────────*/
.dock{
  display:none;position:fixed;left:0;right:0;bottom:0;z-index:800;
  padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px));
  background:linear-gradient(rgba(247,248,248,0),var(--paper) 45%);
}
.dock .btn{width:100%;justify-content:center}
/* It arrives once the hero is fully behind you, not partway through it: the hero
   carries its own full-size CTA, and a paper dock over the drench reads as a
   second page sliding up from the bottom. */
.js .dock{transform:translateY(130%);transition:transform 300ms cubic-bezier(.2,.8,.2,1)}
.js:not(.over-hero) .dock{transform:none}

.foot{background:var(--surface);border-top:1px solid var(--line)}
.foot-inner{display:flex;flex-wrap:wrap;align-items:center;gap:20px 40px;padding-block:34px}
/* Everything clickable down here clears 44px. The footer is the one place on the
   page where the targets are small text on a phone, at the end of a long scroll. */
.foot-brand{display:flex;align-items:center;gap:10px;color:var(--ink);text-decoration:none;
  font-size:16px;min-height:44px}
.foot-brand img{border-radius:6px}
.foot-nav{display:flex;gap:12px;margin-left:auto}
.foot-nav a{color:var(--muted);text-decoration:none;font-size:15px;
  display:inline-flex;align-items:center;min-height:44px;padding-inline:8px}
.foot-nav a:hover{color:var(--ink);text-decoration:underline}
.foot-nav a:focus-visible{text-decoration:underline}
.foot-copy{font-size:15px;color:var(--muted)}


/* ── Responsive ──────────────────────────────────────────────────────────────*/
@media (min-width:768px){
  .stage-grid{grid-template-columns:1fr 1fr}
  .stage-mid{grid-column:span 2;order:-1}
  .sc-inline{display:grid;grid-template-columns:290px 1fr;gap:30px;align-items:center}
  .sc-inline figcaption{margin-top:0}
}

@media (min-width:992px){
  /* start, not center: the three columns are different heights, and centering each
     one independently floated the first left card above the phone and the first
     right card. One shared top edge across all three. */
  .stage-grid{grid-template-columns:1fr 1.08fr 1fr;gap:40px;align-items:start}
  .stage-mid{grid-column:auto;order:0}
  .ready-grid{grid-template-columns:1fr 1fr;gap:90px}
  .covers .display{max-width:18ch}
}

/* The pinned showcase exists only where the choreography does. Without .motion
   the inline phones carry the same screens and the same captions. */
.motion .sc{grid-template-columns:1fr 340px;gap:80px;align-items:start}
.motion .sc-pin{display:block;position:sticky;top:var(--stick);order:2;align-self:start}
.motion .sc-inline{display:none}
/* The steps column runs longer than the last step's copy so the pinned phone stays
   put through step 5 instead of bottoming out early and drifting up into the bar.
   The gap is the rhythm; the step boxes themselves are only as tall as they need
   to be, so short steps don't centre themselves inside a screen of empty band. */
.motion .sc-steps{gap:16vh;padding-bottom:22vh}
/* The inactive floor is a legibility number, not a taste one: at .32 the 18px
   body copy measured 1.95:1 on this band, below the 3:1 needed for *large* text.
   .68 measures 4.9:1, so a reader can work ahead of the pinned screen. The
   active step is separated by the marker turning full --em-bright as well, so
   the state is never carried by opacity alone. */
.motion .sc-step{min-height:0;display:flex;flex-direction:column;justify-content:flex-start;
  opacity:.68;transition:opacity 300ms ease}
.motion .sc-step.is-on{opacity:1}

@media (max-width:991px){
  .section{padding:100px 0}
  .lead{margin-bottom:50px}
  .hero{padding-top:calc(var(--head-h) + 20px)}
  .hero-stage{margin-top:60px}
  .stage-col{gap:20px}
  .sc-steps{gap:70px}
}

@media (max-width:767px){
  .head-nav{display:none}
  .head .btn{margin-left:auto}
  .section{padding:80px 0}
  .lead{margin-bottom:40px}
  /* Left-ranged on phones. A centred 6-line lede is a ragged block on both edges
     at this measure; the whole hero block moves together so the alignment stays
     one decision rather than a mix. */
  .hero-head,.hero-head .cta-fine{text-align:left}
  .hero-head h1,.hero-head .lede{margin-inline:0}
  .strip-line{justify-content:flex-start}
  .hero-head .cta-row{justify-content:stretch}
  .cta-row{flex-direction:column;align-items:stretch}
  .cta-row .btn{justify-content:center}
  .dock{display:block}
  .foot-inner{flex-direction:column;align-items:flex-start}
  .foot-nav{margin-left:0}
  main{padding-bottom:80px}
}

/* ── Reduced motion ──────────────────────────────────────────────────────────
   The script drops .motion under this query, so all scroll-linked and entrance
   motion is already gone. State-change transitions are deliberately kept and
   shortened: they say that something happened, and removing them removes
   information rather than motion. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  /* The delay has to go with the duration. The hero sequence fills `backwards`,
     so a surviving 0.6s delay would hold the headline at its start state, i.e.
     invisible, for 0.6s before snapping in. That is worse than the motion. */
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-delay:0s!important;
    animation-iteration-count:1!important;
  }
  .btn,.btn-wipe,.btn-face,.faq .chev,.faq summary,.head-nav a,.sc-pin .shot,.dock{
    transition-duration:120ms!important;
  }
}
