/* ══════════════════════════════════════════════════════════════════════════
   EXAMAKER — PRODUCTION STYLESHEET
   Shared by the landing page and the For Schools page.

   MOBILE FIRST. The base rules are the phone layout; wider screens add
   complexity back at 600 / 900 / 1100. Most traffic is a phone.
   One max-width:599px block exists, for the sample-paper carousel only: it
   has to break OUT of the content column on a phone, which cannot be
   expressed as something a wider screen adds.

   Every token below is lifted verbatim from examaker-frontend/app/globals.css
   so this and the real app cannot drift. When porting into Next.js these
   become Tailwind theme values that already exist — do not redefine them.

   PORTING MAP
     nav / drawer          → components/layout/Navbar.tsx (already exists)
     footer                → components/layout/Footer.tsx (already exists)
     .btn                  → components/ui/button.tsx, brand+primary variant
     .hero* .deck          → app/(public-pages)/components/Hero.tsx
     .slide .cnav .dots    → components/paper-preview/PaperPageCarousel.tsx
     .appframe and below   → new marketing components; mirror the real sheets
   ══════════════════════════════════════════════════════════════════════════ */
/* ── Cascade layer ──────────────────────────────────────────────────────────
   Everything below lives in @layer marketing.
   Standalone, this changes nothing: one layer with nothing competing behaves
   exactly as unlayered CSS did.
   Inside the Next app it is load-bearing. This sheet has element-level rules
   (h1, h2, p, a, img), Tailwind v4 puts every utility in @layer utilities, and
   an UNLAYERED rule beats every LAYERED one regardless of specificity. So on
   the pages that load both — pricing, terms, privacy and the rest — `h1{margin:0}`
   here was silently beating `mb-8` there, and `h1{font-size:34px}` was beating
   `text-3xl`, which is why those headings ran together. Being in a layer that
   the app orders before `utilities` puts it back the way anyone would expect:
   element rules lose to utilities.
   The app declares the order in app/globals.css. Keep the two in step. */
@layer marketing {

:root{
  --gm-25:#fcfcfd; --gm-50:#f8fafc; --gm-100:#eef2f6; --gm-200:#e3e8ef;
  --gm-300:#cdd5df; --gm-400:#9aa4b2; --gm-500:#697586; --gm-600:#4b5565;
  --gm-700:#364152; --gm-800:#202939; --gm-900:#121926; --gm-950:#0d121c;
  --blue-25:#f5faff; --blue-50:#eff8ff; --blue-100:#d1e9ff; --blue-200:#b2ddff;
  --blue-300:#84caff;
  --blue-500:#2e90fa; --blue-600:#1570ef; --blue-800:#1849a9; --blue-900:#194185; --blue-950:#102a56;
  --brand:#2065F5; --brand-lite:#6194FF;
  --su-50:#ecfdf3; --su-100:#dcfae6; --su-500:#17b26a; --su-600:#079455; --su-700:#067647;
  --wa-50:#fffaeb; --wa-100:#fef0c7; --wa-500:#f79009; --wa-700:#b54708;
  --er-50:#fef3f2; --er-500:#f04438; --er-600:#d92d20;
  --grad-premium:linear-gradient(-90deg,#4B65F0 0%,#AC4CC0 49.58%,#EB6659 100%);
  --grad-brand:linear-gradient(90deg,#2065F5 0%,#6194FF 100%);
  --sh-xs:0 1px 2px 0 rgba(23,23,23,.05);
  --sh-sm:0 1px 2px 0 rgba(23,23,23,.06),0 1px 3px 0 rgba(23,23,23,.1);
  --sh-md:0 2px 4px -2px rgba(23,23,23,.06),0 4px 8px -2px rgba(23,23,23,.1);
  --sh-lg:0 4px 6px -2px rgba(16,24,40,.03),0 12px 16px -4px rgba(16,24,40,.08);
  --sh-xl:0 8px 8px -4px rgba(23,23,23,.03),0 20px 24px -4px rgba(23,23,23,.08);
  --sh-2xl:0 24px 48px -12px rgba(23,23,23,.18);
  --ease-ios:cubic-bezier(.32,.72,0,1);
  --gutter:16px; --maxw:1240px; --navh:56px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;background:#fff;color:var(--gm-900);
  font-family:"Outfit","Inter",system-ui,-apple-system,sans-serif;
  font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased;overflow-x:hidden;
  padding-bottom:calc(68px + env(safe-area-inset-bottom));
}
/* height:auto is load-bearing — images carry width/height attributes for layout
   stability, and without this their intrinsic height wins and they blow up. */
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
button{font:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
section{position:relative}
::selection{background:var(--blue-100)}

/* ══════════════════════════════════════════════════════════════════════════
   SEMANTIC RESETS
   The markup uses real elements — lists for lists, a description list for the
   stat strip, figure/blockquote for quotes, a real button for each swap
   candidate — so screen readers and crawlers get the right structure. Those
   elements carry browser defaults (bullets, dd indents, button chrome) that
   have to be cleared here rather than by reaching for divs.
   ══════════════════════════════════════════════════════════════════════════ */
.reassure,.pillrow,.streamkey,.patgrid,.fgrid,.rail,.riskrow,.plist,
.roi-out,.statstrip{list-style:none;margin:0;padding:0}
.statstrip dd,.roi-out dd,.roi-out dt,.statstrip dt{margin:0}
.reassure li,.riskrow li,.streamkey li{display:flex;align-items:center;gap:6px}
.patgrid li,.fgrid li,.rail > li{display:flex}
.patgrid li,.fgrid li{flex-direction:column}
.rail > li{flex-direction:column}
.fgrid li{flex-direction:row}
figure{margin:0}
blockquote{margin:0}

/* Each swap candidate is a real <button>, so clear the UA chrome and let its
   own .cand rules do the work. */
button.cand{font:inherit;color:inherit;text-align:left;width:100%;appearance:none;
  -webkit-appearance:none}
button.cand .badgerow{display:flex}
button.cand .candbody{display:block}

/* Elements that were divs and are now spans still need to lay out as blocks. */
.unittab{display:block}
.unitcard > span:first-child{display:block}
.unitcard .ue,.unitcard .un{display:block}
.metarow{display:flex}
.seccard .inp,.partrow .inp{display:block}
.seg > span{padding:6px 10px;border-radius:999px;font-size:12px;font-weight:700;
  color:#4a5568;display:inline-flex;align-items:center;gap:4px}
.seg > span.on{background:var(--blue-600);color:#fff}
.tcard .who > span{display:flex;flex-direction:column;min-width:0}
.tcard .nm,.tcard .rl{display:block}
.pcard .tag,.ctrl-copy .t,.demo-cta .t,.fgroup .gh,.patcard .pt{
  font-weight:700}
.fgroup .gh{font-size:10.5px}
.patcard .pt{font-size:15px;display:flex;align-items:center;gap:9px}
.ctrl-copy .t{font-size:18px;letter-spacing:-.02em}
.demo-cta .t{font-size:17px;letter-spacing:-.015em}

/* Footer column headings are <h2> now (they sit inside <nav> landmarks). */
footer nav h2{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--gm-500);margin:0 0 10px}

/* The FAQ question is a <button> inside an <h3>. */
.fitem h3{margin:0;font-size:inherit;font-weight:inherit;letter-spacing:normal}

/* The hero deck is focusable, so it needs a visible ring of its own. */
.deck:focus-visible{outline:2px solid var(--brand);outline-offset:6px;border-radius:12px}
.viewport:focus-visible{outline:2px solid #fff;outline-offset:-4px}


h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.022em;line-height:1.12;
  text-wrap:balance}
/* leads are longer, so pretty (last line only) beats balance for them */
.sec-head .lead{text-wrap:pretty}
h1{font-size:34px;letter-spacing:-.032em}
h2{font-size:25px}
h3{font-size:17px;letter-spacing:-.012em}
p{margin:0}
.lead{font-size:15.5px;color:var(--gm-600);line-height:1.6}
.muted{color:var(--gm-500)}
.small{font-size:13px}
.tiny{font-size:11.5px}
.ta-font{font-family:"Noto Sans Tamil","Outfit",sans-serif}

/* ── Eyebrow ────────────────────────────────────────────────────────────── */
.eyebrow{
  display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:999px;
  border:1px solid var(--blue-100);background:var(--blue-25);
  font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--blue-800);
}
.eyebrow.grad{border-color:rgba(75,101,240,.28);
  background:linear-gradient(-90deg,rgba(75,101,240,.09),rgba(172,76,192,.09),rgba(235,102,89,.09))}
.eyebrow.grad .t{background:var(--grad-premium);-webkit-background-clip:text;background-clip:text;color:transparent}
.eyebrow .dot{width:5px;height:5px;border-radius:50%;background:var(--su-500);flex:none}

/* ── The signature button. Do not restyle; this is the app's key control. ── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:50px;padding:0 20px 4px;border-radius:10px;
  font-weight:600;font-size:16px;line-height:1;text-align:center;
  border:1px solid var(--blue-600);background:var(--grad-brand);color:#fff;
  box-shadow:inset 0 -5px 0 0 rgba(5,0,92,.32);
  transition:filter .15s,transform .06s,box-shadow .06s;
}
.btn:active{box-shadow:none;transform:translateY(2px)}
.btn.sm{min-height:40px;font-size:14px;padding:0 14px 3px;border-radius:9px}
.btn.ghost{background:#fff;color:var(--gm-700);border:1px solid var(--gm-300);box-shadow:inset 0 -3px 0 0 var(--gm-200)}
.btn.ghost:active{box-shadow:none;transform:translateY(2px)}
.btn.onblue{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.45);color:#fff;
  box-shadow:inset 0 -3px 0 0 rgba(0,0,0,.14)}
.btn.block{width:100%}
.arrow{font-size:1.05em;line-height:1;transform:translateY(-1px)}
@media(hover:hover){ .btn:hover{filter:brightness(1.08)} }

.install{
  display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:999px;
  background:linear-gradient(#202939,#202939) padding-box,
             linear-gradient(to right,#F06A59,#B5179E,#4B65F0) border-box;
  border:3px solid transparent;color:#fff;font-weight:700;font-size:11.5px;white-space:nowrap;
  transition:filter .15s,transform .06s;
}
.install:active{transform:scale(.95)}

/* ── Top bar + nav ──────────────────────────────────────────────────────── */
/* The announcement bar carries the brand's premium gradient. The link is white
   and underlined so it stays legible across all three stops of it. */
.topbar{background:var(--grad-premium);color:#fff;font-size:13px;font-weight:600;
  text-align:center;padding:9px 14px;line-height:1.4}
.topbar b{font-weight:700}
.topbar .link{color:#fff;font-weight:700;white-space:nowrap;
  text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1.5px}
.topbar .link:hover{text-decoration-thickness:2.5px}
.nav{position:sticky;top:0;z-index:60;background:rgba(255,255,255,.92);
  backdrop-filter:saturate(180%) blur(12px);border-bottom:1px solid var(--gm-200)}
.nav .inner{height:var(--navh);display:flex;align-items:center;justify-content:space-between;gap:10px}
.nav .logo{height:30px;width:auto}
.navlinks{display:none}
.navright{display:flex;align-items:center;gap:8px}
.burger{width:40px;height:40px;border-radius:9px;border:1px solid var(--gm-300);background:var(--gm-100);
  box-shadow:inset 0 -3px 0 0 var(--gm-300);display:flex;align-items:center;justify-content:center;
  color:var(--gm-700);flex:none}
.burger:active{box-shadow:none;transform:translateY(2px)}
.drawer{display:none;border-bottom:1px solid var(--gm-200);background:#fff;padding:8px var(--gutter) 16px}
.drawer.open{display:block;animation:drop .22s var(--ease-ios)}
@keyframes drop{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.drawer a.dl{display:block;padding:13px 4px;font-size:15.5px;font-weight:500;color:var(--gm-700);
  border-bottom:1px solid var(--gm-100)}
.drawer .acts{display:grid;gap:9px;margin-top:14px}
.drawer .login{display:flex;align-items:center;justify-content:center;min-height:48px;
  border:1px solid var(--gm-700);border-radius:10px;font-weight:600;color:var(--gm-700)}

/* ── Sections ───────────────────────────────────────────────────────────── */
.sec{padding:52px 0}
.sec.tight{padding:40px 0}
.sec-head{max-width:720px;margin:0 auto 24px;text-align:center}
.sec-head .lead{margin-inline:auto}
.sec-head h2{margin:13px 0 11px}
.sec-head h2::after,h2.ruled::after{
  content:"";display:block;width:44px;height:5px;margin:14px auto 0;
  border-top:2.5px solid var(--brand);border-bottom:1.5px solid var(--blue-200);
}
h2.ruled::after{margin-left:0;margin-right:auto}
.on-dark .sec-head h2::after,.on-dark h2.ruled::after{
  border-top-color:rgba(255,255,255,.85);border-bottom-color:rgba(255,255,255,.3)}

/* ── The teacher's pen. Used sparingly. ─────────────────────────────────── */
.handnote{font-family:"Caveat","Outfit",cursive;font-weight:700;font-size:19px;line-height:1.25;
  color:#e9655c;display:inline-block;transform:rotate(-1.6deg)}
.handnote.on-dark{color:#ffd8a8}
.handnote svg{display:inline-block;vertical-align:-2px;margin-right:4px}

/* ══════════════════════════════════════════════════════════════════════════
   HERO — full-bleed background, masked to nothing at every edge so there is
   no panel border and therefore no bleed seam at any viewport width. The
   content still rides the same container as every other section.
   ══════════════════════════════════════════════════════════════════════════ */
.hero{padding:26px 0 0;overflow:hidden}
.hero-bg{
  position:absolute;inset:-1px 0 0;z-index:0;pointer-events:none;
  background:
    radial-gradient(95% 70% at 50% -12%, rgba(32,101,245,.11), transparent 62%),
    radial-gradient(60% 55% at 90% 8%,  rgba(172,76,192,.10), transparent 70%),
    radial-gradient(55% 45% at 4% 88%,  rgba(23,178,106,.07), transparent 72%);
}
.hero-bg::after{
  content:"";position:absolute;inset:0;
  /* 1.25px rather than 1px, at the same 16px pitch: enough to register as a
     texture, not enough to become a pattern you look at. 1.35 was too
     heavy, 1.15 too faint. The fractional radius anti-aliases, which is
     what keeps the dots soft rather than printed. */
  background-image:radial-gradient(#cbd5e1 1.25px,transparent 1.25px);
  background-size:16px 16px;opacity:.64;
  -webkit-mask-image:radial-gradient(125% 88% at 50% 26%,#000 42%,transparent 80%);
          mask-image:radial-gradient(125% 88% at 50% 26%,#000 42%,transparent 80%);
}
.hero-inner{position:relative;z-index:2;padding-top:12px;padding-bottom:6px}
.hero h1{margin:0 0 20px}
/* One column reads better centred; from 900px the deck sits beside the copy
   and a centred ragged edge against it looks accidental, so it reverts. */
.hero-inner>div:first-child{text-align:center}
.hero .lead{margin-inline:auto}
/* left-aligned on every width: a checklist is scanned down its tick column,
   so centring the block would cost more than the symmetry buys */
.reassure{text-align:left}
.reassure li:first-child{grid-column:1 / -1}
.schoolcard{text-align:left}
.h1-ink{position:relative;display:inline-block;color:var(--brand);white-space:nowrap}
/* The live hero's marker, sized in em so it tracks the headline at every
   breakpoint: 2.232em x .304em at -.214em resolves to exactly 125x17 at -12px
   on the 56px desktop headline, which is the live spec. A fixed 125px made it
   WIDER than the word it underlines on a phone, where "minutes" is 116px. */
.h1-ink svg{position:absolute;right:0;left:auto;bottom:-.214em;
  width:2.232em;height:.304em;overflow:visible}
.cta-row{display:grid;gap:10px}
.schoolpath{
  display:inline-flex;align-items:center;gap:7px;margin-top:16px;
  font-size:13.5px;font-weight:600;color:var(--blue-800);
}
.schoolpath .ic{width:22px;height:22px;border-radius:7px;background:var(--blue-50);
  border:1px solid var(--blue-100);display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;flex:none}
.schoolpath u{text-decoration:none;border-bottom:1.5px solid var(--blue-300);padding-bottom:1px}
/* 1 + 2 on a phone: the first point carries the offer and gets its own
   row, the other two pair off underneath, which balances better than a
   three-deep stack or a ragged 2+1. */
.reassure{display:grid;grid-template-columns:1fr 1fr;gap:9px 14px;margin-top:20px;
  font-size:12.5px;color:var(--gm-600);font-weight:500}
.reassure span{display:flex;align-items:center;gap:6px}
.tick{width:16px;height:16px;border-radius:50%;background:var(--su-50);color:var(--su-600);
  display:inline-flex;align-items:center;justify-content:center;font-size:9.5px;font-weight:800;flex:none}

/* ── The paper deck: one document, three pages, cycling ─────────────────── */
/* the AI sparkle sits 44px above the deck's own box, so the top margin has
   to clear that as well as give the deck air */
.deck{position:relative;z-index:1;margin:56px auto 40px;width:min(72vw,248px);aspect-ratio:880/1247}
.deck .pg{
  position:absolute;inset:0;background:#fff;border:1px solid var(--gm-200);border-radius:9px;
  overflow:hidden;transform-origin:50% 90%;
  transition:transform .9s var(--ease-ios),opacity .9s ease,box-shadow .9s ease;
  will-change:transform,opacity;
}
.deck .pg img{width:100%;height:100%;object-fit:cover;object-position:top center}
/* Two shadows per sheet, not one: a wide soft cast for depth and a tight
   contact shadow so the page still reads as resting on something. The back
   two fan wider and turn further than the front, which is what makes a stack
   of paper look handled rather than stacked by a machine. */
.deck .pg[data-slot="0"]{transform:rotate(-1.8deg) translate(0,0) scale(1);opacity:1;z-index:3;
  box-shadow:0 48px 80px -28px rgba(16,24,40,.40),0 14px 26px -12px rgba(16,24,40,.20)}
.deck .pg[data-slot="1"]{transform:rotate(8deg) translate(13%,-5.5%) scale(.945);opacity:.88;z-index:2;
  box-shadow:0 38px 62px -26px rgba(16,24,40,.34),0 10px 20px -12px rgba(16,24,40,.16)}
.deck .pg[data-slot="2"]{transform:rotate(-11.5deg) translate(-14%,-9%) scale(.9);opacity:.72;z-index:1;
  box-shadow:0 30px 52px -26px rgba(16,24,40,.30),0 8px 16px -10px rgba(16,24,40,.14)}
.float-chip{
  position:absolute;z-index:6;display:inline-flex;align-items:center;gap:6px;
  padding:7px 11px;border-radius:999px;background:#fff;border:1px solid var(--gm-200);
  box-shadow:var(--sh-lg);font-size:11.5px;font-weight:600;color:var(--gm-800);white-space:nowrap;
}
.chip-school{top:-15px;left:14px;max-width:calc(100% - 28px)}
.float-chip .ic{width:16px;height:16px;border-radius:5px;display:inline-flex;align-items:center;
  justify-content:center;font-size:9px;color:#fff;flex:none}
.chip-a{top:4%;left:-14%} .chip-b{bottom:20%;right:-16%} .chip-c{display:none}
@media(prefers-reduced-motion:no-preference){
  .float-chip{animation:bobchip 5.5s ease-in-out infinite}
  .chip-b{animation-delay:-2.2s} .chip-c{animation-delay:-3.6s}
  @keyframes bobchip{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
}

/* ── Stat strip ─────────────────────────────────────────────────────────── */
.statstrip{position:relative;z-index:2;display:grid;grid-template-columns:1fr 1fr;
  margin-top:30px;border-top:1px solid var(--gm-200);border-bottom:1px solid var(--gm-200)}
.statstrip div{padding:14px 10px;text-align:center;border-left:1px solid var(--gm-200)}
.statstrip div:nth-child(odd){border-left:0}
.statstrip div:nth-child(n+3){border-top:1px solid var(--gm-200)}
.statstrip .n{font-size:20px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.statstrip .l{font-size:10px;font-weight:600;color:var(--gm-500);letter-spacing:.04em;
  text-transform:uppercase;margin-top:2px}

/* ── Coverage ───────────────────────────────────────────────────────────── */
.coverage{padding:26px 0 0}
.cov-card{border:1px solid var(--gm-200);border-radius:14px;padding:16px 0 16px 16px;background:#fff}
.cov-head{display:grid;gap:7px;margin-bottom:13px;padding-right:16px}
.cov-head .kv{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.cov-head .k{font-size:10.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--gm-500);flex:none}
.cov-head .v{font-size:14px;font-weight:600}
.pillrow{display:flex;gap:7px;overflow-x:auto;padding-right:16px;
  scroll-snap-type:x proximity;scrollbar-width:none}
.pillrow::-webkit-scrollbar{display:none}
.pill{padding:7px 13px;border-radius:999px;border:1px solid var(--gm-200);background:var(--gm-25);
  font-size:13px;font-weight:500;color:var(--gm-700);white-space:nowrap;flex:none;scroll-snap-align:start}
.swipehint{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--gm-400);
  margin-top:10px;font-weight:500}

/* ── Proof carousel ─────────────────────────────────────────────────────── */
.proof{background:linear-gradient(180deg,#0d121c 0%,#102a56 52%,#1849a9 100%);color:#fff;overflow:hidden}
/* The CTA is the last thing in this section and carries its own weight, so
   it does not need a full section's padding under it. Two classes, not one:
   the .sec padding shorthand is restated in the 600/900/1100 blocks further
   down, and at equal specificity those would win on source order. */
.sec.proof{padding-bottom:38px}
.proof h2{color:#fff} .proof .lead{color:rgba(255,255,255,.72)}
.proof .eyebrow{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.22);color:#fff}
.subjtabs{display:flex;gap:8px;margin:0 0 14px;padding:2px 0;
  overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
  /* the row scrolls on a phone; the fade tells you so without a scrollbar */
  mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%)}
.subjtabs::-webkit-scrollbar{display:none}
.subjtabs button{flex:none;padding:10px 15px;border-radius:999px;
  border:1px solid rgba(255,255,255,.26);background:rgba(255,255,255,.08);
  color:rgba(255,255,255,.86);font:inherit;font-size:13px;font-weight:600;
  white-space:nowrap;cursor:pointer;
  transition:background .2s,color .2s,border-color .2s}
.subjtabs button:hover{background:rgba(255,255,255,.16)}
.subjtabs button[aria-selected="true"]{background:#fff;color:var(--gm-900);
  border-color:#fff;box-shadow:0 4px 12px -2px rgba(0,0,0,.35)}
@media(min-width:600px){
  .subjtabs{justify-content:center;mask-image:none;flex-wrap:wrap;overflow:visible}
}

/* 720px is the standard head width and it forced this title onto two lines at
   38 characters. The dark section is full-bleed, so a wider head costs nothing
   and buys the single line. It still wraps on a phone, which no width can fix
   at 358px. */
.proof .sec-head{max-width:860px}
/* the heading wants the width; the lead does not — 70ch reads better and
   balances the two lines instead of leaving a stub on the second */
.proof .sec-head .lead{max-width:620px;margin-inline:auto;text-wrap:balance}

@media(max-width:599px){
  /* Escape the content column so the neighbouring page is clipped by the screen
     edge rather than by a line 16px inside the layout. 100vw is safe here
     because a phone has no classic scrollbar to inflate it. */
  .viewport{width:100vw;margin-inline:calc(50% - 50vw)}
}

.carousel-outer{position:relative;user-select:none}
.viewport{position:relative;height:452px;display:flex;align-items:center;overflow:hidden;
  touch-action:pan-y;cursor:grab}
.viewport.drag{cursor:grabbing}
/* Pinned near the top rather than vertically centred, so the extra height
   the viewport carries lands BELOW the page, where the drop shadow needs
   it. Centring split that room evenly and the shadow — offset 26px down —
   ran straight into the overflow:hidden edge and sheared off flat. */
.track-anchor{position:absolute;left:50%;top:18px;height:max-content}
.track{display:flex;align-items:center;gap:22px;width:max-content}
.slide{flex:none;background:#fff;border:1px solid rgba(255,255,255,.18);border-radius:9px;
  overflow:hidden;position:relative;
  transition:opacity .5s ease,transform .5s ease,box-shadow .5s ease}
.slide.active{opacity:1;transform:scale(1);box-shadow:0 20px 44px -14px rgba(0,0,0,.55);z-index:4}
.slide.idle{opacity:.32;transform:scale(.86);box-shadow:var(--sh-md)}
/* scale away from the active page so the facing edge stays put */
.slide.idle.far{opacity:0}  /* a neighbouring page from a DIFFERENT paper: keep the slot, show nothing */
.slide.idle.before{transform-origin:right center}
.slide.idle.after{transform-origin:left center}
.slide img{width:100%;height:100%;object-fit:cover;object-position:top center;pointer-events:none;
  -webkit-user-drag:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
/* -webkit-touch-callout is the one that matters on a phone: it removes the
   long-press "Save Image" sheet on iOS. Friction, not protection — every one
   of these pages is already stamped examaker.com with the school's own name,
   which is the only thing that actually survives being copied. */
.cnav{position:absolute;top:50%;transform:translateY(-50%);z-index:9;
  width:42px;height:42px;border-radius:50%;border:1px solid rgba(255,255,255,.18);
  background:rgba(13,18,28,.6);backdrop-filter:blur(8px);color:#fff;
  display:flex;align-items:center;justify-content:center;font-size:19px;
  box-shadow:inset 0 1px 0 0 rgba(255,255,255,.25),0 8px 20px -4px rgba(0,0,0,.45);
  transition:background .2s,opacity .2s,transform .08s}
.cnav:active{transform:translateY(-50%) scale(.94)}
.cnav[disabled]{opacity:0;pointer-events:none}
.cprev{left:max(6px,calc(50% - (var(--wa,280px) / 2) - 52px))}
.cnext{right:max(6px,calc(50% - (var(--wa,280px) / 2) - 52px))}
.slidemeta{text-align:center;margin-top:0;min-height:48px}
.slidemeta .t{font-size:15px;font-weight:600}
.slidemeta .s{font-size:12.5px;color:rgba(255,255,255,.62);margin-top:3px;max-width:34ch;
  margin-inline:auto;line-height:1.5}
.dots{display:flex;justify-content:center;gap:2px;margin-top:2px;flex-wrap:wrap}
.dots button{width:26px;height:38px;border:0;background:none;padding:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center}
.dots button::before{content:"";display:block;width:7px;height:7px;border-radius:999px;
  background:rgba(255,255,255,.42);transition:width .3s ease,background .3s ease}
.dots button:hover::before{background:rgba(255,255,255,.7)}
.dots button.on::before{width:22px;background:#fff}
.proof-foot{display:grid;gap:12px;justify-items:center;margin-top:28px}
/* The gradient ends on #1849a9 and the brand button is also blue, so the
   default primary read as a flat slab here. White inverts cleanly. */
.proof-foot .btn{background:#fff;background-image:none;color:var(--gm-900);
  border-color:#fff;box-shadow:0 10px 24px -8px rgba(0,0,0,.5)}
.proof-foot .btn:hover{filter:none;background:#f2f6ff}

/* ── Exam patterns ──────────────────────────────────────────────────────── */
/* The builder card: dashed so it reads as an empty slot to fill rather than a
   seventh pattern that already exists. */
/* Two classes: .patcard is defined BELOW this block and sets a solid border,
   so at equal specificity it would win on source order and the dashes would
   never render. */
.patcard.patnew{display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:8px;border:1.5px dashed var(--blue-300);background:var(--blue-25);
  min-height:100%;transition:border-color .2s,background .2s,transform .06s}
.patcard.patnew:hover{border-color:var(--blue-600);background:var(--blue-50)}
.patcard.patnew:active{transform:translateY(1px)}
.patcard.patnew .plus{width:34px;height:34px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:21px;font-weight:600;line-height:1;
  background:var(--blue-600);color:#fff;box-shadow:0 4px 10px -2px rgba(21,112,239,.45)}
.patcard.patnew .nt{font-size:14.5px;font-weight:700;color:var(--blue-800);letter-spacing:-.01em}
.patcard.patnew .ns{font-size:12.5px;color:var(--gm-600);line-height:1.45;max-width:24ch}
.patgrid{display:grid;gap:10px}
.patcard{border:1px solid var(--gm-200);border-radius:14px;padding:16px;background:#fff;
  box-shadow:var(--sh-xs)}
.patcard .pt{display:flex;align-items:center;gap:9px;font-size:15px;font-weight:700}
.patcard .pt .ic{width:30px;height:30px;border-radius:9px;background:var(--blue-50);
  color:var(--blue-700,#1849a9);display:flex;align-items:center;justify-content:center;font-size:14px;flex:none}
.patcard .pd{font-size:13px;color:var(--gm-500);margin-top:6px;line-height:1.5}
.patcard .pm{display:inline-flex;align-items:center;gap:6px;margin-top:10px;padding:4px 10px;
  border-radius:999px;background:var(--gm-50);border:1px solid var(--gm-200);
  font-size:11px;font-weight:700;color:var(--gm-600);font-family:Arial,sans-serif}

/* ── Steps: the exact cards from the live site ────────────────────────────
   Stacked on a phone, not a side-scroller: there are only three, each is a
   full step of the flow, and a reader who misses step 3 has missed the point.
   .rail is shared with the pricing cards, which DO want to scroll, so this
   overrides only the steps. Two classes, not one: these rules sit ABOVE
   .rail in the file, and at equal specificity .rail would win on source
   order and keep the side-scroll. */
.rail.steprail{display:grid;grid-template-columns:1fr;gap:16px;
  overflow:visible;padding:0;margin:0}
.rail.steprail > *{width:auto;max-width:420px;margin-inline:auto}
@media(min-width:900px){
  .rail.steprail{grid-template-columns:repeat(3,1fr);gap:20px}
  .rail.steprail > *{max-width:none;margin-inline:0}
}
.rail{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;
  padding:2px var(--gutter) 6px;margin:0 calc(var(--gutter) * -1)}
.rail::-webkit-scrollbar{display:none}
.rail > *{scroll-snap-align:start;flex:none;width:82vw;max-width:320px}
.step{
  --shot-h:280px;
  position:relative;border-radius:16px;overflow:hidden;
  padding-top:var(--shot-h);
  display:flex;flex-direction:column;justify-content:flex-end;
  background:linear-gradient(135deg,#EB6659 0%,#AC4CC0 50%,#4B65F0 100%);
  box-shadow:var(--sh-lg);border:1px solid rgba(255,255,255,.2);
}
.step .rays{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  mix-blend-mode:screen;pointer-events:none;z-index:0}
/* No drop shadow on the screenshot: the card already sits on a gradient and
   the shadow only muddied the bottom edge where it meets the caption.
   justify-content:flex-end is load-bearing, not tidiness: the image is
   240x440 inside a 280px window, so whichever end it is pinned to decides
   which half of the app screen you see. The live component pins it to the
   bottom (flex flex-col justify-end in howitworks.tsx); without this the
   image sits at the top and the card shows the wrong half, sliced mid-screen. */
.step .shot{position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:85%;max-width:240px;height:var(--shot-h);overflow:hidden;border-radius:0 0 28px 28px;z-index:1;
  display:flex;flex-direction:column;justify-content:flex-end}
/* Each SVG ends with a strip of flat app background below its last content
   row — 42px on card 1, 30px on cards 2 and 3, measured off the rendered
   assets. Pinned to the bottom of the window that strip IS the gap under
   the screenshot. Nudging the image down by its own tail drops the strip
   outside the window and shows that much more of the screen instead. */
.step .shot img{width:100%;height:auto;object-fit:cover;object-position:bottom;
  transform:translateY(var(--tail,30px))}
.step:nth-child(1){--tail:42px}
/* The screenshot ends right on this box's top edge, so this padding IS the
   gap between the two. 24 was the live component's value and read as a void;
   14 closed it too far. */
.step .cap{position:relative;z-index:3;padding:22px 24px 30px;display:flex;flex-direction:column;
  align-items:center;gap:7px;margin-top:auto;text-align:center;color:#fff}
.step .caphead{display:flex;align-items:center;gap:12px}
.step .caphead img{width:26px;height:26px;filter:drop-shadow(0 2px 3px rgba(0,0,0,.3))}
.step h3{color:#fff;font-size:18px;letter-spacing:-.02em}
/* Tighter than the live component's leading-relaxed (1.625). Two short
   centred lines read as one sentence when they sit close; spread apart they
   read as two separate statements. */
.step p{font-size:14px;font-weight:500;color:rgba(255,255,255,.8);line-height:1.42;max-width:260px}
.demo-cta{margin-top:22px;border:1px solid var(--gm-200);border-radius:16px;background:var(--gm-25);
  padding:20px;display:grid;gap:14px}
.demo-cta .t{font-size:17px;font-weight:700;letter-spacing:-.015em}
.demo-cta .s{font-size:13.5px;color:var(--gm-600);margin-top:4px;line-height:1.55}

/* ── Control: faithful mini-recreations of the real app sheets ──────────── */
.control{background:var(--gm-25);border-top:1px solid var(--gm-200);border-bottom:1px solid var(--gm-200)}
/* Four capabilities down the left, the matching screen on the right. One
   column on a phone (cards, then the screen), two from 900px. The old
   horizontal pill rail put four tabs in a side-scroller where the fourth was
   off-screen and unread. */
.ctrl2{display:grid;gap:18px}
/* Below 900px the four cards are a swipeable row, not a 4-deep stack that
   pushes the screen they describe off the bottom of the phone. Each card stays
   a full card — title, line and plan chip — so nothing is lost to the change. */
.ctrl2-menu{display:flex;gap:10px;overflow-x:auto;scrollbar-width:none;
  scroll-snap-type:x mandatory;
  margin-inline:calc(var(--gutter) * -1);padding:2px var(--gutter) 6px}
.ctrl2-menu::-webkit-scrollbar{display:none}
/* snap-align:center, not start — the first card then sits with space either
   side instead of jammed against the container edge, and the JS below can
   bring any card to the middle when it is chosen */
.ctrl2-menu > *{flex:none;width:78vw;max-width:300px;scroll-snap-align:center}
@media(min-width:900px){
  .ctrl2-menu{display:grid;gap:10px;align-content:start;overflow:visible;
    margin-inline:0;padding:0}
  .ctrl2-menu > *{width:auto;max-width:none}
}
.ctrlcard{display:flex;gap:12px;text-align:left;width:100%;padding:14px;border-radius:14px;
  border:1px solid var(--gm-200);background:#fff;cursor:pointer;
  transition:border-color .18s,box-shadow .18s,background .18s}
.ctrlcard:hover{border-color:var(--blue-300)}
.ctrlcard[aria-selected="true"]{border-color:var(--blue-600);background:var(--blue-25);
  box-shadow:0 1px 2px rgba(16,42,86,.05),0 8px 20px -10px rgba(24,73,169,.35)}
.ctrlcard .n{flex:none;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:12.5px;font-weight:700;
  background:var(--gm-100);color:var(--gm-600);transition:background .18s,color .18s}
.ctrlcard[aria-selected="true"] .n{background:var(--blue-600);color:#fff}
.ctrlcard .cc{display:flex;flex-direction:column;gap:3px;min-width:0}
.ctrlcard .ct{font-size:15px;font-weight:700;letter-spacing:-.015em;color:var(--gm-900)}
.ctrlcard .cd{font-size:13px;color:var(--gm-600);line-height:1.45}
/* Paid tiers wear the premium gradient as an OUTLINE, not a fill: four
   solid gradient pills down one column shouted louder than the card titles.
   Two backgrounds — white clipped to the padding box, the gradient to the
   border box — is how you get a gradient border with no extra element. */
.ctrlcard .cp{align-self:start;margin-top:5px;padding:4px 10px;border-radius:999px;
  border:1px solid transparent;font-size:11px;font-weight:700;letter-spacing:.01em;
  /* Three layers, painted first on top: a 12% wash of the gradient, then
     white, both clipped to the padding box — so the fill reads as a tint of
     the brand rather than a solid slab. The border box gets the gradient at
     full strength, which is what draws the outline. */
  background:
    linear-gradient(-90deg,rgba(75,101,240,.12) 0%,rgba(172,76,192,.12) 49.58%,rgba(235,102,89,.12) 100%) padding-box,
    linear-gradient(#fff,#fff) padding-box,
    var(--grad-premium) border-box;
  color:#9333a8}
/* the label itself carries the gradient, clipped to the glyphs */
.ctrlcard .cp .g{background:var(--grad-premium);-webkit-background-clip:text;
  background-clip:text;color:transparent}
/* free is a different KIND of statement, so it keeps its own colour */
.ctrlcard .cp.free{background:var(--su-50);border:1px solid #a6f4c5;color:var(--su-600)}

/* The stage. A full sheet shows everything and so points at nothing; one
   piece on a lit ground points at itself. The glow is a radial wash rather
   than a border so the element reads as lifted off the page, not framed. */
/* One height for all four on a phone: the tabs advance on their own, and a
   stage that resized on every switch made the whole section jump under the
   reader. 330px is the tallest piece (the builder) plus its padding. */
.spot{position:relative;display:flex;flex-direction:column;justify-content:flex-start;
  align-items:center;height:330px;
  padding:24px 18px;border-radius:18px;border:1px solid var(--gm-200);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(32,101,245,.10), transparent 62%),
    radial-gradient(90% 70% at 85% 100%, rgba(172,76,192,.07), transparent 70%),
    #fff;
  overflow:hidden}
.spot::before{content:"";position:absolute;inset:0;
  background-image:radial-gradient(#cbd5e1 1.25px,transparent 1.25px);
  background-size:16px 16px;opacity:.5;
  -webkit-mask-image:radial-gradient(70% 60% at 50% 50%,transparent 30%,#000 100%);
          mask-image:radial-gradient(70% 60% at 50% 50%,transparent 30%,#000 100%)}
/* the piece itself floats above the wash */
.spot > *{position:relative;z-index:1;margin-inline:auto;width:100%;
  background:#fff;border-radius:12px;
  box-shadow:0 1px 2px rgba(16,42,86,.06),0 18px 40px -14px rgba(16,42,86,.34)}
.spot-narrow > *,.spot-mid > *{max-width:420px}

.spot-tight > *{max-width:330px}
.spot .cand{display:block;padding:13px 15px;border:1px solid var(--gm-200)}
/* A stack that fades out downward, so it reads as "and more below" without
   drawing a scrollbar or a cut edge. --dim is set per row in the markup; the
   mask finishes the job so even the last row's box edge dissolves. */
.spot .stack{display:flex;flex-direction:column;gap:8px;background:none;box-shadow:none;
  -webkit-mask-image:linear-gradient(#000 38%,rgba(0,0,0,.35) 76%,transparent 100%);
          mask-image:linear-gradient(#000 38%,rgba(0,0,0,.35) 76%,transparent 100%)}
.spot .stack > *{opacity:var(--dim,1)}
.spot .stack .cand{background:#fff;border-radius:12px;
  box-shadow:0 1px 2px rgba(16,42,86,.06),0 10px 24px -14px rgba(16,42,86,.3)}
.spot .stack .optline2{display:flex;align-items:center;gap:8px}
.spot .stack .optline2 .gut{flex:none;font-size:12px;font-weight:700;color:var(--gm-500)}
.spot .stack .optline2 .fieldbox{flex:1;padding:9px 12px;border:1px solid var(--gm-200);
  box-shadow:none;font-size:13px}
/* the field that is actually being edited keeps the focus ring; the options
   below are context, not the subject */
.spot .fieldbox.focused{border-color:var(--blue-300);
  box-shadow:0 0 0 3px rgba(32,101,245,.12),0 18px 40px -14px rgba(16,42,86,.34)}

/* The app's Review step, add-question/page.tsx:1259 — same pills, same order,
   same 14/21 question type. */
.reviewcard{padding:16px;border:1px solid var(--gm-200);background:var(--gm-50);
  border-radius:12px;display:flex;flex-direction:column;gap:12px;text-align:left}
.reviewcard .rpills{display:flex;flex-wrap:wrap;gap:6px}
.reviewcard .rp{padding:2px 8px;border-radius:6px;border:1px solid;
  font-size:11px;font-weight:600;line-height:1.5}
.reviewcard .rp-type{border-color:var(--blue-200);background:var(--blue-50);color:var(--blue-600)}
.reviewcard .rp-yours{border-color:#a6f4c5;background:#ecfdf3;color:#087443}
.reviewcard .rq{margin:0;font-size:14px;line-height:21px;color:#202939}

/* one step darker than the default card edge, so the builder rows read as
   editable fields rather than printed text */
.spot .seccard,.spot .partrow .inp{border-color:var(--gm-300)}
.spot .partrow{background:none;box-shadow:none}
/* One even rhythm between the total banner, the part row and the section
   card. The gap goes on the STAGE, which is the flex parent of all three —
   putting it on the blocks themselves only laid out their own contents. */
.spot-tight{gap:10px}
.spot .totalbanner{margin-bottom:0}
.spot .fieldlbl{display:block;background:none;box-shadow:none;margin:0 0 6px;
  font-size:11px;text-align:left}
.spot .fieldbox{padding:12px 14px;border:1px solid var(--gm-200);box-shadow:none}
.spot .caret{display:inline-block;width:1.5px;height:15px;margin-left:2px;
  vertical-align:-3px;background:var(--blue-600)}
.spot .wizh1{margin:0 0 10px;padding:14px 16px 0;background:none;box-shadow:none;
  font-size:15px}
.spot .chipwrap{padding:0 16px 16px;background:none;box-shadow:none}
.spot-tight .totalbanner,.spot-tight .seccard{max-width:330px}
@media(prefers-reduced-motion:no-preference){
  .spot .caret{animation:caret 1.1s steps(1) infinite}
  @keyframes caret{0%,49%{opacity:1}50%,100%{opacity:0}}
}

.ctrl2-view{position:relative;min-width:0}
.ctrlview{display:none}
.ctrlview.on{display:block}
/* The pieces are static. Nothing in them is a control, so nothing in them
   takes a pointer or a tab stop. */
.ctrlview .spot,.ctrlview .spot *{pointer-events:none;user-select:none}
/* Caveat, the same hand the closing section uses. It names the screen without
   competing with it — a caption in the page's own UI type would read as more
   interface. */
/* Full width of the view, centred by text-align. An auto-margined max-width
   box centres against the view instead of the stage, which is why it sat
   off to the left. */
.handnote{margin:12px 0 0;width:100%;text-align:center;font-family:Caveat,cursive;
  font-size:19px;line-height:1.3;color:var(--gm-500)}
@media(min-width:900px){
  /* The stage is capped rather than given the whole column: a 420px piece
     floating in 1330px of dotted ground reads as lost, not spotlit. */
  .ctrl2{grid-template-columns:minmax(0,400px) minmax(0,560px);gap:28px;
    align-items:start;justify-content:center}
  /* Sticks while you read down the four cards, so the piece a card describes
     is always on screen next to it. Stretching the stage to the full height of
     the column instead left a 780px panel around a 420px element. */
  .ctrl2-view{position:sticky;top:86px}
  .spot{justify-content:center;min-height:360px;padding:34px 22px;height:auto}
  /* Swap and Edit start at the stage's midpoint and run off the bottom, so
     the stack reads as continuing rather than ending. A fixed height is what
     makes the midpoint knowable: with min-height the stage grows to fit the
     stack and there is no overflow left to fade. Desktop only — on a phone
     the stage is short and a midpoint start would push the stack off it. */
  .spot-narrow{height:380px;justify-content:flex-start;padding:104px 22px 0}
  .handnote{font-size:21px;margin-top:14px}
}
@keyframes qin{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.ctrl-copy{margin-bottom:16px}
.ctrl-copy .t{font-size:18px;font-weight:700;letter-spacing:-.02em}
.ctrl-copy .d{font-size:14px;color:var(--gm-600);margin-top:6px;line-height:1.6}
.freechip{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;
  background:var(--su-50);border:1px solid var(--su-100);color:var(--su-700);
  font-size:10.5px;font-weight:700;white-space:nowrap}

/* ══════════════════════════════════════════════════════════════════════════
   APP-SURFACE RECREATIONS
   Rebuilt from a read of the real components so a teacher who signs up
   recognises the screen. The one thing to get right: the real swap sheet uses
   a difficulty CIRCLE, plain coloured text for type and source, and pills only
   for "Your Question" and "Current". The in-app demo mocks these as three
   rounded pills, which is wrong, and copying it would be the most visible lie
   on this page.
   Sources: components/paper-preview/SwapBottomSheet.tsx,
   components/paper-preview/QuestionEditSheet.tsx,
   app/home/units/add-question/page.tsx,
   app/home/questions/create-template/page.tsx
   ══════════════════════════════════════════════════════════════════════════ */
.appframe{background:#fcfcfd;border:1px solid var(--gm-200);border-radius:16px;overflow:hidden;
  box-shadow:var(--sh-lg)}
.sheetgrab{width:36px;height:4px;border-radius:99px;background:var(--gm-300);margin:9px auto 4px}
.sheethead{padding:10px 16px 14px;border-bottom:1px solid var(--gm-300);
  box-shadow:0 8px 20px rgba(23,23,23,.06);background:#fcfcfd}
.sheethead .h3{font-size:16px;font-weight:700;color:#000}
.slotlabel{font-size:14px;font-weight:700;color:#000;line-height:1.35;margin-top:12px}

/* unit tabs are 93px CARDS, not pills */
.unittabs{display:flex;gap:12px;overflow-x:auto;scrollbar-width:none;margin-top:12px}
.unittabs::-webkit-scrollbar{display:none}
.unittab{flex:none;width:93px;padding:10px;border-radius:8px;text-align:left;
  background:#fff;border:1px solid var(--gm-300)}
.unittab.on{background:var(--blue-100);border:2px solid var(--blue-500);padding:9px}
.unittab .u1{font-size:14px;font-weight:700;line-height:1.35;color:var(--gm-800)}
.unittab .u2{font-size:11px;line-height:1.35;color:#4a5568;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* purple subtype / category chips */
.pchip{flex:none;padding:6px 12px;border-radius:999px;font-size:12px;font-weight:600;
  background:#fff;border:1px solid #e9d7fe;color:#7839ee}
.pchip.on{background:#7839ee;border-color:#7839ee;color:#fff}

/* ownership toggle + amber source select */
.filterrow{display:flex;gap:8px;align-items:center;overflow-x:auto;scrollbar-width:none;margin-top:12px}
.filterrow::-webkit-scrollbar{display:none}
.seg{display:inline-flex;flex:none;border-radius:999px;background:var(--gm-100);padding:4px;gap:2px}
.seg button{padding:6px 10px;border-radius:999px;font-size:12px;font-weight:700;border:0;
  background:transparent;color:#4a5568;display:inline-flex;align-items:center;gap:4px}
.seg button.on{background:var(--blue-600);color:#fff}
.seg .ct{font-size:11px;color:var(--gm-400)}
.seg button.on .ct{color:rgba(255,255,255,.8)}
.srcsel{flex:none;padding:6px 12px;border-radius:999px;font-size:12px;font-weight:700;
  background:#fff;border:1px solid #fedf89;color:#b54708;white-space:nowrap}

/* candidate card */
.candlist{padding:14px;display:flex;flex-direction:column;gap:8px;background:#fcfcfd}
.cand{width:100%;text-align:left;border-radius:12px;padding:12px;display:flex;flex-direction:column;
  gap:10px;background:#fff;border:1px solid var(--gm-200);box-shadow:0 2px 8px rgba(16,24,40,.06);
  transition:border-color .2s,box-shadow .2s,transform .06s;position:relative}
.cand:active{transform:scale(.99)}
.cand.on{background:var(--gm-50);border:2px solid #111827;padding:11px;
  box-shadow:0 4px 12px rgba(16,24,40,.08)}
.cand .tick2{position:absolute;top:10px;right:10px;width:20px;height:20px;border-radius:50%;
  background:var(--gm-950);color:#fff;display:none;align-items:center;justify-content:center;
  font-size:10px;font-weight:800}
.cand.on .tick2{display:flex}
.badgerow{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding-right:24px}
.dbadge{width:16px;height:16px;border-radius:50%;display:inline-flex;align-items:center;
  justify-content:center;font-size:10px;font-weight:600;color:#fff;flex:none}
.dbadge.e{background:#17b26a} .dbadge.m{background:#eab308} .dbadge.h{background:#f04438}
.tmtext{color:var(--blue-600);font-size:12px;font-weight:700}
.dotsep{color:var(--gm-300);font-size:12px}
.srctext{color:#b54708;font-size:12px;font-weight:700;display:inline-flex;align-items:center;gap:4px}
.yourpill{padding:2px 8px;border-radius:6px;border:1px solid #a6f4c5;background:#ecfdf3;color:#087443;
  font-size:11px;font-weight:600;display:inline-flex;align-items:center;gap:4px}
.curpill{padding:2px 8px;border-radius:6px;background:#111827;color:#fff;font-size:11px;
  font-weight:600;white-space:nowrap}
.candbody{font-size:13px;line-height:17px;color:var(--gm-800)}
.candbody .ord{color:var(--gm-400);font-weight:600;margin-right:5px}
.sheetfoot{display:flex;gap:12px;padding:12px 16px;border-top:1px solid var(--gm-300);background:#fff}
.sheetfoot .btn{flex:1;min-height:40px;font-size:14px}
.papernow{padding:11px 16px;border-top:1px solid var(--gm-100);background:var(--gm-25);
  font-size:11px;color:var(--gm-500);font-weight:600}
.paperline{font-family:Georgia,"Times New Roman",serif;color:#1e293b;padding:14px 16px;
  font-size:14px;line-height:1.55}
.paperline .idx{font-weight:700;margin-right:7px}

/* edit sheet */
.editeyebrow{font-size:10px;font-weight:700;color:var(--gm-400);text-transform:uppercase;
  letter-spacing:.08em;line-height:1}
.editq{font-size:15px;font-weight:900;color:#1b2a45;margin-top:4px;line-height:1}
.fieldlbl{display:block;font-size:11px;font-weight:700;color:var(--gm-800);
  text-transform:uppercase;letter-spacing:.04em}
.fieldbox{border:1px solid var(--gm-300);border-radius:9px;padding:10px 12px;font-size:13.5px;
  color:var(--gm-800);background:#fff;margin-top:7px;line-height:1.5;min-height:44px}
.fieldbox.focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(32,101,245,.14);outline:none}
.optline2{display:flex;gap:9px;align-items:flex-start;margin-top:10px}
.optline2 .gut{font-size:11px;color:var(--gm-500);font-weight:600;padding-top:11px;flex:none;width:14px}
.optline2 .fieldbox{margin-top:0;flex:1;min-height:0}

/* add-question wizard */
.wizhead{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;background:#fff}
.wizhead .lbl{font-size:14px;font-weight:600;color:#4a5568}
.wizhead .cancel{font-size:14px;font-weight:600;color:#d92d20}
.wiz{display:flex;gap:4px;padding:0 14px;background:var(--gm-100);height:8px;align-items:center}
.wiz i{flex:1;height:4px;border-radius:99px;background:var(--gm-200);display:block}
.wiz i.on{background:var(--blue-600)}
.wizh1{font-size:19px;font-weight:800;color:var(--gm-950);margin-bottom:14px;letter-spacing:-.02em}
.kchip{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:999px;
  font-size:13px;font-weight:600;white-space:nowrap;border:1px solid var(--gm-300);
  background:#fff;color:#4a5568}
.kchip.on{background:var(--gm-950);border-color:var(--gm-950);color:#fff}
.chipwrap{display:flex;flex-wrap:wrap;gap:8px}
.unitcard{width:100%;text-align:left;display:flex;align-items:center;justify-content:space-between;
  gap:12px;border-radius:12px;border:1px solid var(--gm-200);background:var(--gm-50);
  padding:13px 16px;margin-top:8px}
.unitcard.on{border-color:var(--blue-600);background:var(--blue-50)}
.unitcard .ue{font-size:11px;font-weight:700;color:var(--gm-400);text-transform:uppercase;letter-spacing:.04em}
.unitcard .un{font-size:14px;font-weight:600;color:var(--gm-950)}
.unitcard .uc{color:var(--blue-600);font-weight:800;flex:none}
.markscard{border-radius:12px;border:1px solid var(--gm-200);background:var(--gm-50);padding:12px 16px;
  display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:14px}
.markscard .l{font-size:13px;color:var(--gm-500)}
.markscard .r{font-size:14px;font-weight:700}
.capsmall{font-size:11px;font-weight:700;color:var(--gm-400);text-transform:uppercase;
  letter-spacing:.04em;margin:14px 0 8px}
.reviewcard{border-radius:12px;border:1px solid var(--gm-200);background:var(--gm-50);padding:16px;
  display:flex;flex-direction:column;gap:12px}
.bluepill{padding:2px 8px;border-radius:6px;border:1px solid #b2ddff;background:var(--blue-50);
  color:var(--blue-600);font-size:11px;font-weight:600}
.metarow{padding-top:9px;border-top:1px solid var(--gm-200);font-size:12px;color:var(--gm-500);
  display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.ddot{width:8px;height:8px;border-radius:50%;background:#eab308;flex:none}
.appfoot{display:flex;align-items:center;gap:12px;padding:12px 14px;border-top:1px solid var(--gm-200);background:#fff}
.appfoot .btn{flex:1;min-height:42px;font-size:14px}

/* template builder still frame */
.ctxchips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
.ctxchips span{padding:4px 10px;border-radius:999px;background:var(--gm-100);color:var(--gm-700);
  font-size:11px;font-weight:600}
.totalbanner{padding:12px 16px;border-radius:12px;display:flex;align-items:center;
  justify-content:space-between;gap:12px;background:var(--su-50);border:1px solid #abefc6;
  color:#087443;margin-bottom:14px}
.totalbanner .l{font-size:11px;font-weight:500}
.totalbanner .r{font-size:13px;font-weight:600;white-space:nowrap}
.rowstack{display:flex;flex-direction:column;gap:10px}
.partrow{display:flex;align-items:center;gap:8px}
.partrow .grip{color:var(--gm-400);font-size:12px;letter-spacing:-1px;flex:none;line-height:1}
.partrow .inp{flex:1;border:1px solid var(--gm-300);border-radius:9px;padding:9px 12px;
  font-size:13.5px;background:#fff;color:var(--gm-800);font-weight:500}
.partrow .del{width:34px;height:34px;border-radius:9px;color:#d92d20;flex:none;display:flex;
  align-items:center;justify-content:center;font-size:13px}
.seccard{border-radius:16px;padding:12px;display:flex;flex-direction:column;gap:8px;background:var(--gm-100)}
.seccard .top{display:flex;align-items:center;gap:8px}
.typetag{padding:2px 8px;border-radius:6px;background:var(--blue-50);color:#1d4ed8;font-size:10.5px;
  font-weight:700;text-transform:uppercase;letter-spacing:.04em;flex:none}
.seccard .rule{height:1px;flex:1;background:var(--gm-200)}
.seccard .del{width:26px;height:26px;border-radius:8px;color:#d92d20;flex:none;display:flex;
  align-items:center;justify-content:center;font-size:12px}
.seccard .inp{border:1px solid var(--gm-300);border-radius:9px;padding:9px 12px;font-size:13.5px;background:#fff}
.seccard .cnt{display:flex;align-items:center;gap:10px}
.seccard .cnt .inp{flex:1}
.seccard .math{font-size:13px;font-weight:700;color:var(--blue-600);white-space:nowrap}
.addrow{display:flex;gap:10px;margin-top:12px}
.addrow .b{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;min-height:44px;
  border-radius:9px;font-size:14px;font-weight:600}
.addrow .b.gray{border:1px solid var(--gm-300);color:var(--gm-700);background:#fff}
.addrow .b.brand{border:1px solid var(--blue-300);color:var(--blue-600);background:#fff}

/* ── Features ───────────────────────────────────────────────────────────── */
.fgroup{margin-top:28px}
.fgroup .gh{display:flex;align-items:center;gap:10px;margin-bottom:13px;
  font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--gm-500)}
.fgroup .gh::after{content:"";flex:1;height:1px;background:var(--gm-200)}
/* One column of compact ROWS on a phone, not two columns of tall cards.
   Two columns look tighter but are not: at ~160px wide each description
   wrapped to six lines, so three rows of those ran taller than six
   full-width rows where the same text fits in two. Measured both. */
.fgrid{display:grid;grid-template-columns:1fr;gap:7px}
.fgrid li{padding:11px 13px;gap:11px;align-items:flex-start}
.fgrid .t{font-size:13.5px}
.fgrid .d{font-size:12px;line-height:1.4;margin-top:2px}
.fgrid .ic{width:28px;height:28px;font-size:14px}
@media(min-width:600px){
  .fgrid li{padding:14px;gap:12px}
  .fgrid .d{font-size:12.5px}
}
.fcard{border:1px solid var(--blue-100);border-radius:13px;padding:14px;
  background:linear-gradient(309deg,#C6E1FF -92.25%,#FFFFFF 85.72%);
  display:flex;gap:12px;align-items:flex-start}
.fcard .ic{flex:none;width:34px;height:34px;border-radius:9px;background:#fff;border:1px solid var(--blue-100);
  display:flex;align-items:center;justify-content:center;font-size:15px}
.fcard .t{font-size:14px;font-weight:700;letter-spacing:-.01em}
.fcard .d{font-size:12.5px;color:var(--gm-600);margin-top:3px;line-height:1.5}

/* ── ROI ────────────────────────────────────────────────────────────────── */
.roi{background:var(--gm-950);color:#fff;overflow:hidden}
.roi h2{color:#fff} .roi .lead{color:rgba(255,255,255,.66)}
.roi .eyebrow{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.2);color:#fff}
.roi-card{border:1px solid rgba(255,255,255,.12);border-radius:18px;
  background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.025));padding:22px 18px}
.roi-row{display:grid;gap:20px}
.sliderbox label{display:flex;justify-content:space-between;gap:12px;align-items:baseline;
  font-size:12.5px;font-weight:600;color:rgba(255,255,255,.62)}
.sliderbox .val{font-size:16px;font-weight:700;color:#fff;font-variant-numeric:tabular-nums}
input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:999px;
  background:rgba(255,255,255,.16);outline:none;margin:16px 0 0}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:26px;height:26px;border-radius:50%;
  background:#fff;border:5px solid var(--brand);cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.45)}
input[type=range]::-moz-range-thumb{width:26px;height:26px;border-radius:50%;background:#fff;
  border:5px solid var(--brand);cursor:pointer}
.roi-out{display:grid;gap:2px;margin-top:24px;padding-top:20px;border-top:1px solid rgba(255,255,255,.1)}
.roi-out .o{display:flex;align-items:baseline;justify-content:space-between;gap:14px;padding:11px 0;
  border-bottom:1px solid rgba(255,255,255,.07)}
.roi-out .o:last-child{border-bottom:0}
.roi-out .o .n{font-size:28px;font-weight:700;letter-spacing:-.03em;font-variant-numeric:tabular-nums;order:2;
  background:var(--grad-premium);-webkit-background-clip:text;background-clip:text;color:transparent}
.roi-out .o .l{font-size:12.5px;font-weight:600;color:rgba(255,255,255,.6);order:1}
.roi-plan{margin-top:20px;padding-top:20px;border-top:1px solid rgba(255,255,255,.1);
  display:grid;gap:12px}
.roi-plan .pl{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.roi-plan .pl .l{font-size:12.5px;font-weight:600;color:rgba(255,255,255,.6)}
.roi-plan .pl .v{font-size:21px;font-weight:700;letter-spacing:-.02em;white-space:nowrap;
  background:var(--grad-premium);-webkit-background-clip:text;background-clip:text;color:transparent}
.roi-note{font-size:12px;color:rgba(255,255,255,.42);margin-top:16px;line-height:1.6}

/* ── Pricing ────────────────────────────────────────────────────────────── */
.prail > *{width:78vw;max-width:310px}
/* The rail scrolls sideways, so overflow-y clips too — and .rail's 2px of top
   padding is less than the "Most popular" badge's 11px overhang, which sheared
   the top off it on mobile. Desktop is a grid with overflow:visible, so it only
   ever needed fixing here. Doubled class: .rail alone would win on source order. */
.rail.prail{padding-top:16px}
/* Free trial leads at every width. It was already first on desktop; on mobile
   the rail fell back to DOM order and opened on Teacher Pro, so the one card
   that costs nothing to say yes to was two swipes away. */
.p-trial{order:1} .p-teacher{order:2} .p-pro{order:3}
.pcard{border:1px solid var(--gm-200);border-radius:16px;padding:20px;background:#fff;
  display:flex;flex-direction:column;box-shadow:var(--sh-xs);height:100%}
.pcard.hi{background:var(--blue-950);border-color:var(--blue-900);color:#fff;box-shadow:var(--sh-xl);position:relative}
.pcard .tag{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--gm-500)}
.pcard.hi .tag{color:var(--blue-300)}
.pcard .price{font-size:32px;font-weight:700;letter-spacing:-.03em;margin:9px 0 2px}
.pcard .price small{font-size:13px;font-weight:500;color:var(--gm-500)}
.pcard.hi .price small{color:#93c5fd}
.pcard .sub{font-size:12.5px;color:var(--gm-500)} .pcard.hi .sub{color:#93c5fd}
/* The two prices a teacher can say yes to without a decision go green — the
   same family as the ticks, so it reads as one language rather than a new
   accent. su-600 not su-500: at 32px/700 this is "large text", where 3:1 is
   the floor, and su-500 sits at 2.8:1 on white. The /month sub-label keeps
   its grey (.pcard .price small wins on specificity) so the hierarchy holds. */
.p-trial .price,.p-teacher .price{color:var(--su-600)}
.plist{list-style:none;margin:16px 0 18px;padding:0;display:grid;gap:8px;font-size:13.5px;
  color:var(--gm-600);flex:1}
.pcard.hi .plist{color:rgba(255,255,255,.84)}
.plist li{display:flex;gap:8px;align-items:flex-start}
.plist .tk{color:var(--su-500);font-weight:800;flex:none}
.popular{position:absolute;top:-11px;left:50%;transform:translateX(-50%);
  background:#fddede;color:#e9655c;font-size:9.5px;font-weight:800;letter-spacing:.09em;
  padding:5px 13px;border-radius:999px;text-transform:uppercase;white-space:nowrap}
.soonbadge{position:absolute;top:-11px;left:50%;transform:translateX(-50%);
  background:var(--gm-100);color:var(--gm-600);font-size:9.5px;font-weight:800;letter-spacing:.09em;
  padding:5px 13px;border-radius:999px;text-transform:uppercase;white-space:nowrap;
  border:1px dashed var(--gm-300)}
.pcard.dim{opacity:.72}
.riskrow{display:grid;gap:9px;margin-top:24px;font-size:13px;color:var(--gm-600);font-weight:500}
.riskrow span{display:flex;align-items:center;gap:8px}

/* ── Comparison ─────────────────────────────────────────────────────────── */
.cmp-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--gm-200);
  border-radius:14px;background:#fff}
.cmp-scroll::-webkit-scrollbar{height:6px}
.cmp-scroll::-webkit-scrollbar-thumb{background:var(--gm-300);border-radius:99px}
.cmp{width:100%;min-width:560px;border-collapse:separate;border-spacing:0;font-size:13px}
.cmp th,.cmp td{padding:12px 14px;text-align:left;border-bottom:1px solid var(--gm-100)}
.cmp thead th{background:var(--gm-50);font-size:10.5px;font-weight:700;letter-spacing:.055em;
  text-transform:uppercase;color:var(--gm-500);border-bottom:1px solid var(--gm-200);white-space:nowrap}
.cmp thead th.us{background:var(--blue-50);color:var(--blue-800)}
.cmp td.us{background:var(--blue-25);font-weight:600;color:var(--gm-900)}
.cmp tbody tr:last-child td{border-bottom:0}
.cmp td.feat{font-weight:600;color:var(--gm-800);position:sticky;left:0;background:#fff;
  box-shadow:1px 0 0 var(--gm-100);min-width:180px}
.yes{color:var(--su-600);font-weight:700} .no{color:var(--gm-400)} .part{color:var(--wa-700);font-weight:600}
.cmp-note{font-size:12.5px;color:var(--gm-500);margin-top:12px;line-height:1.6}

/* ── Testimonials ───────────────────────────────────────────────────────── */
.marquee-mask{position:relative;overflow:hidden}
.marquee{display:flex;gap:12px;width:max-content;animation:mq 52s linear infinite}
@keyframes mq{to{transform:translateX(calc(-50% - 6px))}}
.tcard{width:272px;flex:none;border:1px solid var(--gm-200);border-radius:14px;padding:16px;background:#fff;
  box-shadow:var(--sh-xs);display:flex;flex-direction:column}
.tcard .q{font-size:13.5px;color:var(--gm-700);line-height:1.6;flex:1}
.tcard .who{display:flex;gap:10px;align-items:center;margin-top:14px;padding-top:13px;
  border-top:1px solid var(--gm-100)}
.tcard .who img{width:36px;height:36px;border-radius:50%;flex:none}
.tcard .nm{font-size:13.5px;font-weight:700} .tcard .rl{font-size:12px;color:var(--gm-500)}
.stars{display:flex;gap:2px;color:#f59e0b;font-size:12px;margin-bottom:9px}

/* ── FAQ ────────────────────────────────────────────────────────────────── */
.faq{max-width:820px;margin:0 auto}
.fitem{border:1px solid var(--gm-200);border-radius:13px;margin-bottom:9px;overflow:hidden;background:#fff;
  transition:border-color .2s,box-shadow .2s}
.fitem.open{border-color:var(--blue-300);box-shadow:var(--sh-sm)}
.fq{width:100%;display:flex;align-items:center;justify-content:space-between;gap:14px;padding:16px;
  background:none;border:0;text-align:left;font-size:14.5px;font-weight:600;color:var(--gm-900);
  min-height:54px;line-height:1.4}
.fitem.open .fq{color:var(--blue-800)}
.fq .chev{transition:transform .25s var(--ease-ios);color:var(--gm-400);flex:none;font-size:11px}
.fitem.open .fq .chev{transform:rotate(180deg);color:var(--blue-600)}
.fa{max-height:0;overflow:hidden;transition:max-height .32s var(--ease-ios),opacity .25s;opacity:0}
.fitem.open .fa{max-height:460px;opacity:1}
.fa .inner{padding:0 16px 17px;font-size:14px;color:var(--gm-600);line-height:1.65}

/* ── Final CTA ──────────────────────────────────────────────────────────── */
.final{background:linear-gradient(180deg,#1570EF 0%,#2E90FA 44%,#EAF2FF 100%);
  padding:56px 0 64px;text-align:center;overflow:hidden;position:relative}
.final .wrap{position:relative;z-index:2}
.final h2{color:#fff;margin:14px auto 11px;max-width:15ch;font-size:30px}
.final .lead{color:rgba(255,255,255,.9);max-width:44ch;margin:0 auto 22px}
.final .eyebrow{background:rgba(255,255,255,.15);border-color:rgba(255,255,255,.3);color:#fff}
.final h2::after{border-top-color:rgba(255,255,255,.85);border-bottom-color:rgba(255,255,255,.3)}
/* the red-pen correction */
.struck{position:relative;display:inline-block;color:rgba(255,255,255,.66)}
.struck svg{position:absolute;left:-4%;top:52%;width:108%;height:14px;overflow:visible}
/* Centred on the word it corrects, not on the headline. As a block it was
   centred by the h2's text-align and drifted right of "typing". */
/* Clear of the word, with room to read as a separate correction. The badge
   above is pushed down to make that room rather than the word being crushed
   into the strike to find it. */
.penfix{position:absolute;left:50%;bottom:106%;
  transform:translateX(-50%) rotate(-2.2deg);
  font-family:"Caveat","Outfit",cursive;font-weight:700;color:#ffd8a8;
  font-size:.62em;line-height:1;white-space:nowrap;pointer-events:none;
}
/* room for .penfix, which hangs above the first line of the headline. In em
   so it tracks the headline: .penfix is .62em tall, so a fixed pixel gap
   cleared the badge on a phone and collided on a desktop. */
.final h2{margin-top:.8em}
.final .btnrow{display:grid;gap:10px;max-width:360px;margin:0 auto}
.final .fine{margin-top:16px;font-size:12.5px;color:rgba(255,255,255,.82);line-height:1.6}
/* paper edge peeking from the bottom, tying back to the hero */
.final .fan{position:absolute;left:50%;bottom:-58%;transform:translateX(-50%);
  width:min(620px,140%);opacity:.5;z-index:1;pointer-events:none}
.final .fan span{position:absolute;left:50%;bottom:0;width:150px;height:210px;background:#fff;
  border-radius:8px 8px 0 0;box-shadow:0 -8px 24px rgba(16,24,40,.12);transform-origin:50% 100%}

/* ── Footer ─────────────────────────────────────────────────────────────── */
footer{background:#0D1117;color:var(--gm-300);padding:40px 0 26px}
.fgrid2{display:grid;gap:28px}
footer h4{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--gm-500);margin-bottom:10px}
footer a{display:block;font-size:14px;color:var(--gm-300);padding:7px 0}
footer .blurb{font-size:13px;color:var(--gm-400);line-height:1.6;margin-top:11px;max-width:36ch}
.fbot{display:grid;gap:7px;margin-top:28px;padding-top:18px;border-top:1px solid #1f2937;
  font-size:12.5px;color:var(--gm-500)}

/* ── Sticky mobile action bar ───────────────────────────────────────────── */
.sticky{position:fixed;left:0;right:0;bottom:0;z-index:70;display:flex;gap:9px;
  padding:10px var(--gutter) calc(10px + env(safe-area-inset-bottom));
  background:rgba(255,255,255,.97);backdrop-filter:blur(10px);border-top:1px solid var(--gm-200);
  transform:translateY(110%);transition:transform .34s var(--ease-ios)}
.sticky.show{transform:none}
.sticky .btn{min-height:46px;font-size:15px}

/* ── Scroll reveal, gated on .js so a no-JS visitor sees a complete page ── */
.js .rv{opacity:0;transform:translateY(12px)}
.js .rv.in{opacity:1;transform:none;transition:opacity .55s ease,transform .55s var(--ease-ios)}




/* ══════════════════════════════════════════════════════════════════════════
   HERO ACCENTS
   A small, shared vocabulary: a ribbon swish behind the hero, a hand-drawn
   accent mark, the teacher's pen, and the green free-papers badge carried over
   from the live site. Used once or twice each. The moment any of these appears
   three times on one screen it stops reading as craft and starts reading as
   clutter, so resist adding more.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Hand-drawn strokes ───────────────────────────────────────────────────
   Four loose marker strokes, inlined once as a sprite and referenced with
   <use>. The paths carry no fill, so each instance takes its colour from CSS
   `color` and can be tinted per section: brand blue on light backgrounds,
   white on dark ones.

   The fade is a mask, not an opacity ramp baked into the artwork, so one file
   serves every placement. Each stroke therefore dissolves into the background
   instead of ending on a hard edge, which is what keeps them decorative rather
   than distracting.

   Rules of use: at most one per screenful, always behind content, never over
   body copy, and always aria-hidden. They are atmosphere, not information. */
.stroke-sprite{position:absolute;width:0;height:0;overflow:hidden}
.stroke{
  position:absolute;z-index:0;pointer-events:none;
  color:var(--brand);opacity:.15;
  -webkit-mask-image:linear-gradient(115deg,#000 6%,rgba(0,0,0,.45) 52%,transparent 86%);
          mask-image:linear-gradient(115deg,#000 6%,rgba(0,0,0,.45) 52%,transparent 86%);
}
/* Paint lives on the sprite paths as currentColor, because a descendant
   selector cannot cross into a <use> shadow tree. CSS drives it from here
   via `color`, which is inherited and does cross. */
.stroke svg{display:block;width:100%;height:auto}
/* Lives in .hero-bg at z-index 0, behind every piece of content, so it can
   carry some presence without competing with anything. Held to min(74%,1000px)
   and anchored right: at 148% and centred it spilled across the headline
   column, which is what made it read as unbalanced. */
.stroke.duo{opacity:.62}
/* fade from the other corner, for strokes anchored on the opposite side */
.stroke.rev{
  -webkit-mask-image:linear-gradient(295deg,#000 6%,rgba(0,0,0,.45) 52%,transparent 86%);
          mask-image:linear-gradient(295deg,#000 6%,rgba(0,0,0,.45) 52%,transparent 86%);
}
/* On dark sections the same stroke is painted white and pulled back further —
   light ink on a dark ground reads much stronger at the same opacity. */
.proof .stroke,.roi .stroke,.final .stroke,.on-dark .stroke{color:#fff;opacity:.10}
.final .stroke{opacity:.16}

/* The hand-drawn accent mark (assets/brand/highlight.png, #2065F5 on
   transparent). Decorative only — every use carries aria-hidden. */
/* The mark reads as pointing down-left, so it belongs on a top-RIGHT corner.
   Add .flip to mirror it when it has to sit on a left edge. */
.doodle{position:absolute;pointer-events:none;z-index:4;opacity:.9}
.doodle.sm{width:26px} .doodle.md{width:38px} .doodle.lg{width:52px}
.doodle.flip{transform:scaleX(-1)}

/* Green "free papers" badge, carried over from the live hero. */
.freebadge{
  position:absolute;z-index:20;top:-14px;left:-8px;
  background:#22c55e;color:#fff;border:2px solid #86efac;border-radius:999px;
  padding:6px 10px;font-size:11.5px;font-weight:800;line-height:1;text-align:center;
  box-shadow:var(--sh-md);transform:rotate(-15deg);white-space:nowrap;
}
@media(prefers-reduced-motion:no-preference){
  .freebadge{animation:pulse-border 1.6s ease-in-out infinite}
}
@keyframes pulse-border{
  0%,100%{border-color:#86efac;box-shadow:0 0 0 0 rgba(34,197,94,.4)}
  50%{border-color:#4ade80;box-shadow:0 0 8px 3px rgba(34,197,94,.3)}
}
/* Carries the whole lead->CTA gap: a margin on .cta-row would collapse
   into this one and be ignored. 44 not 34 because the badge is rotated
   -15deg, so its corner reaches ~14px above its own box and at 34 it sat
   6px off the paragraph. */
.cta-wrap{position:relative;margin-top:34px}

/* ── The audience split ───────────────────────────────────────────────────
   A text link was too quiet for a second buyer worth many times a single
   teacher. This is a real tappable panel with its own icon and arrow, still
   clearly secondary to the primary call to action above it. */
.schoolcard{
  position:relative;   /* anchors .doodle — without it the mark escapes to <section> */
  display:flex;align-items:center;gap:12px;margin-top:36px;padding:13px 14px;
  border:1px solid var(--blue-200);border-radius:14px;
  /* 260% wide so the drift below has somewhere to travel; the still frame
     (reduced motion, or no animation support) is the first third, which is
     already a readable blue wash rather than the near-white it had. */
  background:linear-gradient(105deg,var(--blue-50) 0%,#fff 26%,var(--blue-50) 52%,#e8f2ff 78%,var(--blue-50) 100%);
  background-size:260% 100%;
  box-shadow:0 1px 2px rgba(16,42,86,.05),0 6px 16px -8px rgba(24,73,169,.22);
  transition:border-color .2s,box-shadow .2s,transform .06s;
}
/* The sheen rides the BORDER, not the card. A sweep across the whole surface
   is what loading skeletons do, so over real text it reads as "still
   loading" — exactly the wrong signal on the one link to the school page.
   padding + mask-composite paints the 1px ring only. */
.schoolcard::before{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:linear-gradient(105deg,
    transparent 30%,rgba(255,255,255,.9) 42%,var(--blue-300) 50%,
    rgba(255,255,255,.9) 58%,transparent 70%);
  background-size:260% 100%;background-position:120% 0;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
  pointer-events:none;opacity:0;
}
/* Two solid bands, a wide one and a narrow one, leaning "/" and sweeping to
   the bottom-right. Double-position stops (`colour A B`) give hard edges:
   each stop ends where the next begins, so nothing interpolates between
   them. 235% on both axes gives the diagonal travel somewhere to go. */
.schoolcard::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(118deg,
    transparent 0 43.5%,
    rgba(255,255,255,.62) 43.5% 48%,      /* the wide band  */
    transparent 48% 49.4%,                /* the gap        */
    rgba(255,255,255,.62) 49.4% 51.6%,    /* the narrow one */
    transparent 51.6% 100%);
  background-size:235% 235%;background-position:100% 100%;
  opacity:0;
}

/* Must sit BELOW the two rules above: a media query carries no specificity, so
   when this block was upstream the `opacity:0` in those definitions won and
   neither effect ever painted. */
@media(prefers-reduced-motion:no-preference){
  /* 14s: slow enough to register as depth rather than as something demanding
     attention beside a primary CTA. */
  .schoolcard{animation:schoolwash 14s ease-in-out infinite}
  .schoolcard::before{opacity:1;animation:schoolsheen 3s ease-in-out infinite}
  .schoolcard::after{opacity:1;animation:schoolshine 3s ease-in-out infinite}
}
@keyframes schoolwash{0%,100%{background-position:0 0}50%{background-position:100% 0}}
/* Both passes share the 3s cycle and the same 40%-100% window, so the ring
   lights up as the bands cross it: one light source, not two animations.
   1200ms still, then an 1800ms sweep — the sweep is deliberately the slow
   part; shortening it made the bands read as a flicker rather than as light
   moving across a surface. The band is off-screen at 100%, so the loop back
   to the start frame is invisible. */
@keyframes schoolsheen{
  0%,40%{background-position:120% 0}
  100%{background-position:-40% 0}
}
/* background-position offset = (elementW - backgroundW) x pct. backgroundW is
   235% of the element, so the multiplier is NEGATIVE: a falling percentage is
   a rising pixel offset, which slides the background right and carries the
   bands from the top-left corner out through the bottom-right. Verified by
   reading the resolved offset across the pass, not by eye. */
@keyframes schoolshine{
  0%,40%{background-position:100% 100%}
  100%{background-position:0% 0%}
}
.schoolcard:hover{border-color:var(--blue-300);
  box-shadow:0 1px 2px rgba(16,42,86,.06),0 10px 22px -10px rgba(24,73,169,.34)}
.schoolcard:active{transform:translateY(1px)}
.schoolcard .ic{
  flex:none;width:38px;height:38px;border-radius:11px;background:#fff;
  border:1px solid var(--blue-100);display:flex;align-items:center;justify-content:center;font-size:18px;
}
.schoolcard .tx{flex:1;min-width:0}
/* both are <span>: without this the description runs on from the title */
.schoolcard .t1,.schoolcard .t2{display:block}
.schoolcard .t1{font-size:13.5px;font-weight:700;color:var(--gm-900);line-height:1.3}
/* caps need a little tracking or the letters crowd at this weight */
.schoolcard .t1 .caps{text-transform:uppercase;letter-spacing:.03em}
.schoolcard .t2{font-size:12px;color:var(--gm-500);margin-top:2px;line-height:1.3}
.schoolcard .go{
  flex:none;display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:700;
  color:var(--blue-800);white-space:nowrap;
}
/* phone: the words fight the heading for width, so show only the chevron */
.schoolcard .go .lbl{display:none}
@media(min-width:600px){ .schoolcard .go .lbl{display:inline} }

/* The AI sparkle from the marketing pack, used as-is. An illustration says
   "AI" faster than a pill with the word in it, and it is already the brand's
   own mark for this. Decorative, so it is aria-hidden. */
.aispark{position:absolute;z-index:8;top:-44px;left:-52px;width:112px;height:112px;
  filter:drop-shadow(0 8px 18px rgba(124,58,237,.32));pointer-events:none}
@media(prefers-reduced-motion:no-preference){
  .aispark{animation:sparkfloat 4.5s ease-in-out infinite}
  @keyframes sparkfloat{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-7px) rotate(-6deg)}}
}

/* ── Fact card ────────────────────────────────────────────────────────────
   The metrics and the subject rail were two stacked blocks doing one job.
   Merged into a single card: a header strip naming the board, three equal
   metrics, then the subjects scrolling underneath a hairline. The board is
   NAMED rather than counted — we cover one board, and "1 board" reads as a
   limitation where the board's name reads as focus. The subjects run as one
   plain line rather than fourteen bordered pills, which made a single fact
   look like fourteen objects and became the loudest thing on screen.      */
/* Square bottom corners and no bottom border, so the card reads as a layer
   tucked into the section beneath it rather than as a floating tile. The
   shadow is cast upward only, for the same reason — a shadow under it would
   lift it back off the page.
   No accent bar on the top edge: it was decoration that solved nothing, and on
   a card whose whole job is to be read quickly it just drew the eye away from
   the figures. */
.factcard{
  position:relative;z-index:2;margin-top:34px;
  border:1px solid var(--gm-200);border-bottom:0;
  border-radius:18px 18px 0 0;background:#fff;
  box-shadow:0 -14px 30px -18px rgba(16,24,40,.16);
  overflow:hidden;
}
/* The board reads as a metric like the rest, not as a header strip with two
   facts pushed to opposite corners. Its value is words rather than a number,
   so it takes a smaller size and a tinted ground to mark it as the anchor
   the other three hang off. Full width on a phone, first of four from 900px. */
.facts{display:grid;grid-template-columns:repeat(3,1fr)}
.facts .f.board{grid-column:1 / -1;border-bottom:1px solid var(--gm-200);
  background:linear-gradient(135deg,var(--blue-25),#fff)}
.facts .f.board .fv{font-size:19px;color:var(--blue-800)}
.facts .f.board .fk{color:var(--gm-600)}
/* the divider is drawn by .f + .f; the cell after a full-width board would get
   one against the card's own left edge */
.facts .f.board + .f::before{display:none}
@media(min-width:900px){
  .facts{grid-template-columns:1.45fr 1fr 1fr 1fr}
  .facts .f.board{grid-column:auto;border-bottom:0}
  .facts .f.board + .f::before{display:block}
}
.facts .f{position:relative;padding:27px 16px;text-align:center}
.facts .f + .f::before{content:"";position:absolute;left:0;top:50%;
  transform:translateY(-50%);width:1px;height:54%;background:var(--gm-200)}
.facts .fv{margin:0;font-size:26px;font-weight:700;letter-spacing:-.03em;line-height:1.1;
  font-variant-numeric:tabular-nums;color:var(--gm-900)}
.facts .fk{margin:5px 0 0;font-size:10.5px;font-weight:700;color:var(--gm-500);
  letter-spacing:.09em;text-transform:uppercase}

/* subject rail, inside the same card */
.subrail{position:relative;overflow:hidden;background:var(--gm-25);
  border-top:1px solid var(--gm-100);padding:18px 0}
.subrail::before,.subrail::after{content:"";position:absolute;top:0;bottom:0;width:78px;z-index:3;
  pointer-events:none}
.subrail::before{left:0;background:linear-gradient(90deg,var(--gm-25) 30%,rgba(252,252,253,0))}
.subrail::after{right:0;background:linear-gradient(-90deg,var(--gm-25) 30%,rgba(252,252,253,0))}
/* the leading pad keeps the first subject clear of the edge fade at rest */
.subrail .rowwrap{display:flex;width:max-content;gap:16px;padding-left:18px}
.subrail .run{display:flex;gap:9px;flex:none;padding-right:9px;list-style:none;margin:0;padding-left:0}
@media(prefers-reduced-motion:no-preference){
  .subrail .rowwrap{animation:subrail 44s linear infinite}
  .subrail:hover .rowwrap{animation-play-state:paused}
}
@keyframes subrail{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){
  .subrail{overflow-x:auto;scrollbar-width:none}
  .subrail::-webkit-scrollbar{display:none}
}
/* A running line, not fourteen bordered pills. Pills made one fact look like
   fourteen objects and turned a quiet strip into the loudest thing on screen. */
.subrail .run{gap:16px}
.subrail .run li{flex:none;white-space:nowrap;font-size:15px;font-weight:600;
  color:var(--gm-700);display:flex;align-items:center;gap:16px}
.subrail .run li::after{content:"";width:4px;height:4px;border-radius:50%;
  background:var(--gm-300);flex:none}

/* ══════════════════════════════════════════════════════════════════════════
   ACCESSIBILITY & OUTPUT
   ══════════════════════════════════════════════════════════════════════════ */

/* Keyboard users get a visible ring everywhere; pointer users never see it.
   The app's own focus treatment is a 2px brand ring, matched here. */
:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:6px}
:focus:not(:focus-visible){outline:none}
.on-dark :focus-visible,.proof :focus-visible,.roi :focus-visible,.final :focus-visible{
  outline-color:#fff}

/* Skip link — first tabbable element on the page. */
.skip{
  position:absolute;left:12px;top:-64px;z-index:200;
  display:inline-flex;align-items:center;min-height:44px;padding:0 18px;
  border-radius:0 0 10px 10px;background:var(--gm-950);color:#fff;
  font-size:14px;font-weight:600;transition:top .18s var(--ease-ios);
}
.skip:focus{top:0}

/* Visually hidden but read aloud. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* Tab semantics for the control section. */
[role="tabpanel"]:focus{outline:none}
[role="tabpanel"]:focus-visible{outline:2px solid var(--brand);outline-offset:4px}

/* FAQ is a button + region pair, so the chevron must not be announced. */
.fq .chev{pointer-events:none}

/* Anchored sections must not hide under the sticky header. */
[id]{scroll-margin-top:calc(var(--navh) + 16px)}

/* Print: the marketing page is occasionally printed by a head of school
   deciding on a purchase. Give them something readable. */
@media print{
  .topbar,.nav,.sticky,.cnav,.dots,.skip,.demo-cta,.hero-bg,.fan{display:none !important}
  body{padding-bottom:0;font-size:12pt;color:#000;background:#fff}
  .sec{padding:18pt 0;break-inside:avoid}
  .proof,.roi,.schools,.final{background:#fff !important;color:#000 !important}
  .proof h2,.roi h2,.final h2,.proof .lead,.roi .lead,.final .lead{color:#000 !important}
  .viewport{height:auto}
  .track{transform:none !important;flex-wrap:wrap;gap:12pt}
  .slide{opacity:1 !important;transform:none !important;width:46% !important;height:auto !important;
    box-shadow:none !important;border:1px solid #999}
  .rail{display:block}
  .rail > *{width:auto;max-width:none;margin-bottom:12pt}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:9pt;color:#555}
}

/* ══════════════════════════════════════════════════════════════════════════
   ≥600px
   ══════════════════════════════════════════════════════════════════════════ */
@media(min-width:600px){
  :root{--gutter:22px}
  h1{font-size:40px} h2{font-size:30px} .lead{font-size:16.5px}
  .sec{padding:64px 0}
  .cta-row{display:flex;flex-wrap:wrap;gap:12px}
  .cta-row .btn{flex:1;min-width:220px}
  .reassure{display:flex;flex-wrap:nowrap;gap:10px 16px;font-size:12.5px;white-space:nowrap;
    justify-content:flex-start}
  .statstrip{grid-template-columns:repeat(4,1fr)}
  .cta-wrap{margin-top:44px}
  .freebadge{top:-15px;left:-10px;font-size:12px;padding:7px 12px}
  .statstrip div{border-top:0;border-left:1px solid var(--gm-200)}
  .statstrip div:first-child{border-left:0}
  .deck{width:min(52vw,286px)}
  .chip-c{display:inline-flex;bottom:3%;left:-10%}
  .fgrid,.patgrid{grid-template-columns:1fr 1fr}
  .roi-row{grid-template-columns:1fr 1fr;gap:28px}
  .roi-out{grid-template-columns:repeat(3,1fr);gap:16px}
  .roi-out .o{flex-direction:column;align-items:center;text-align:center;border-bottom:0;gap:3px}
  .roi-out .o .n{order:1;font-size:32px} .roi-out .o .l{order:2;font-size:11.5px;
    text-transform:uppercase;letter-spacing:.06em}
  .roi-plan{grid-template-columns:1fr auto;align-items:center;gap:18px}
  .roi-note{text-align:center}
  .riskrow{display:flex;flex-wrap:wrap;justify-content:center;gap:10px 24px}
  .demo-cta{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:22px 24px}
  .final .btnrow{display:flex;justify-content:center;max-width:none}
  .final h2{font-size:38px}
  .fgrid2{grid-template-columns:1fr 1fr}
  .fbot{display:flex;justify-content:space-between}
  .viewport{height:500px}
  .tcard{width:300px}
}

/* ══════════════════════════════════════════════════════════════════════════
   ≥900px — the desktop nav appears here
   ══════════════════════════════════════════════════════════════════════════ */
@media(min-width:900px){
  :root{--gutter:24px;--navh:64px}
  body{padding-bottom:0}
  h1{font-size:50px} h2{font-size:34px}
  .sec{padding:76px 0}
  .topbar{font-size:12.5px;padding:8px 20px}
  .nav .logo{height:36px}
  .navlinks{display:flex;align-items:center;gap:3px}
  .navlinks a.nl{padding:9px 12px;border-radius:8px;font-size:14px;font-weight:500;color:var(--gm-600)}
  .navlinks a.nl:hover{color:var(--gm-900);background:var(--gm-50)}
  .navlinks a.nl.on{color:var(--gm-900);background:var(--gm-100)}
  .navsep{width:1px;height:20px;background:var(--gm-200);margin:0 7px}
  .login{display:inline-flex;align-items:center;min-height:40px;padding:0 16px;
    border:1px solid var(--gm-700);border-radius:9px;font-size:14px;font-weight:600;color:var(--gm-700)}
  .burger,.drawer,.navright{display:none !important}
  .sticky{display:none}

  .hero{padding:34px 0 0}
  .hero-inner{display:grid;grid-template-columns:1.04fr .96fr;gap:40px;align-items:center;
    padding-top:26px;padding-bottom:22px}
  .hero-inner>div:first-child{text-align:left}
  .hero .lead{margin-inline:0}
  .hero h1{margin:0 0 22px}
  .hero .lead{max-width:34rem}
  .deck{width:330px;margin:0 auto}
  .chip-a{top:-2%;left:-20%} .chip-b{bottom:24%;right:-19%} .chip-c{bottom:1%;left:-11%}

  .cov-card{padding:20px 24px}
  .cov-head{display:flex;flex-wrap:wrap;gap:9px 22px;align-items:baseline;padding-right:0}
  .pillrow{flex-wrap:wrap;overflow:visible;padding-right:0}
  .streamkey{padding-right:0}
  .swipehint{display:none}

  .rail{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;overflow:visible;padding:0;margin:0}
  .step h3{font-size:19px} .step p{font-size:15px}
  .rail > *{width:auto;max-width:none}
  .prail{grid-template-columns:repeat(3,1fr)}
  .step{--shot-h:290px}
  .step .shot{max-width:240px}

  .patgrid{grid-template-columns:repeat(3,1fr);gap:13px}
  .ctrl-grid{display:grid;grid-template-columns:.85fr 1.15fr;gap:40px;align-items:start}
  .ctrl-copy{position:sticky;top:calc(var(--navh) + 24px)}
  .ctrl-copy{margin-bottom:0}
  .fgrid{grid-template-columns:repeat(3,1fr);gap:13px}
  .fgrid2{grid-template-columns:1.5fr 1fr 1fr 1fr;gap:34px}
  .roi-card{max-width:940px;margin:0 auto;padding:32px 34px}
  .cmp{min-width:0;font-size:14px}
  .cmp td.feat{position:static;box-shadow:none}
  .cmp-scroll{overflow:visible}
  .viewport{height:560px}
  .track{gap:30px}
  .proof-foot{display:flex;justify-content:center;align-items:center;gap:20px;flex-wrap:wrap}
  .qopts{grid-template-columns:1fr 1fr;gap:5px 18px}
  .marquee-mask::before,.marquee-mask::after{content:"";position:absolute;top:0;bottom:0;width:90px;
    z-index:3;pointer-events:none}
  .marquee-mask::before{left:0;background:linear-gradient(90deg,#fff,transparent)}
  .marquee-mask::after{right:0;background:linear-gradient(-90deg,#fff,transparent)}
  .marquee:hover{animation-play-state:paused}
  .final{padding:86px 0 96px}
  .final h2{font-size:46px}
  footer{padding:56px 0 34px}
}

@media(min-width:1100px){
  .freebadge{left:-26px}
  h1{font-size:56px} h2{font-size:39px} .lead{font-size:18px}
  .sec-head{margin-bottom:42px}
  .fcard{transition:transform .2s var(--ease-ios),box-shadow .2s}
  .fcard:hover{transform:translateY(-2px);box-shadow:var(--sh-md)}
  .slide.idle{cursor:pointer} .slide.idle:hover{opacity:.5}
  .cnav:hover{background:rgba(13,18,28,.76)}
  .deck{width:356px}
}

@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  html{scroll-behavior:auto}
}

/* ── Before and after ─────────────────────────────────────────────────────
   Two FULL pages, each shown from the middle out. The inner page is laid out at
   200%% of its window and pinned to one edge, so what shows is half of a whole
   page — not a page scaled down to fit half the room. The rule over the seam
   overhangs both ends so it reads as laid ON the sheets. */
.split{display:grid;gap:18px;margin-top:6px}
.ba{position:relative;padding-top:30px}
.ba-tags{position:absolute;top:0;left:50%;transform:translateX(-50%);width:100%;
  max-width:660px;display:flex;justify-content:space-between;gap:10px;z-index:7}
.ba-tag{padding:5px 11px;border-radius:999px;font-size:11px;font-weight:700;border:1px solid;
  white-space:nowrap}
.ba-tag.bad{background:rgba(217,45,32,.16);border-color:rgba(253,162,155,.45);color:#fda29b}
.ba-tag.good{background:rgba(23,178,106,.18);border-color:rgba(117,224,167,.45);color:#75e0a7}
.ba-stage{--wipe:50%;position:relative;aspect-ratio:880/1247;max-width:620px;
  margin-inline:auto;user-select:none;
  filter:drop-shadow(0 26px 54px rgba(0,0,0,.6))}
/* Both pages sit at the FULL stage width and are revealed by clip-path, so
   dragging moves only the clip — nothing resizes or reflows mid-drag, and the
   typed page stays a complete page at every position. */
.ba-half{position:absolute;inset:0;background:#fff;border-radius:12px}
.ba-left{clip-path:inset(0 calc(100% - var(--wipe,50%)) 0 0)}
.ba-right{clip-path:inset(0 0 0 var(--wipe,50%))}
.ba-left .tpage{position:absolute;inset:0}
/* max-width:none is load-bearing: the global img rule caps every image at 100%
   of its box, which is not what "fill the stage" means here. */
.ba-right img{position:absolute;inset:0;width:100%;max-width:none;height:100%;
  object-fit:cover;object-position:top center;display:block}
/* The rule: one straight bar, not a drawn curve. It overhangs both ends so it
   reads as laid ON the sheets, and the bloom either side is what separates it
   from a plain border — a hard edge alone looks like a table cell divider. */
.ba-rule{position:absolute;left:var(--wipe,50%);top:-22px;height:calc(100% + 44px);
  width:11px;padding:0;border:0;
  transform:translateX(-50%);z-index:6;border-radius:999px;
  background:#2f3a4d;cursor:ew-resize;touch-action:none;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.1),0 18px 44px -16px rgba(0,0,0,.6)}
.ba-rule:focus-visible{outline:2px solid #fff;outline-offset:4px}
/* the grip: the only part that says "this moves" */
.ba-rule .grip{position:absolute;top:50%;left:50%;width:40px;height:40px;
  transform:translate(-50%,-50%);border-radius:50%;background:#fff;
  display:flex;align-items:center;justify-content:center;gap:4px;
  box-shadow:0 2px 6px rgba(16,42,86,.25),0 12px 30px -6px rgba(16,42,86,.55)}
.ba-rule .grip i{width:0;height:0;border:5px solid transparent}
.ba-rule .grip i:first-child{border-right-color:#41597d}
.ba-rule .grip i:last-child{border-left-color:#41597d}
.ba-rule:active .grip{transform:translate(-50%,-50%) scale(.94)}
/* The glow is the brand gradient itself, blurred — a box-shadow can only be
   one colour, so the gradient goes on a pseudo-element behind the bar and
   is blurred into a halo. Run vertically (180deg) rather than the token's
   -90deg: across an 11px bar a horizontal gradient shows one colour. */
.ba-rule::before{content:"";position:absolute;z-index:-1;
  /* offset down and behind, so it reads as a shadow the bar casts rather
     than a symmetric halo around it */
  inset:2px -20px -18px -20px;border-radius:999px;
  background:linear-gradient(180deg,#4B65F0 0%,#AC4CC0 50%,#EB6659 100%);
  filter:blur(24px);opacity:.28}

/* the typed page */
/* A wide, wasteful left margin — the single biggest reason a typed paper
   runs to more sheets than it needs to. It is the thing the green note
   opposite is contrasted against, so it has to be visibly generous. */
.tpage{padding:5% 5% 0 13%;font-size:6.2px;color:#1f2937;background:#fff;
  font-family:"Times New Roman",Times,serif;font-size:calc(0.30vw + 5px);line-height:1.5}
.tt{margin:0;text-align:center;font-weight:700;letter-spacing:.05em;font-size:1.2em}
.ts{margin:.2em 0 0;text-align:center;font-size:.95em}
.ts2{margin:.2em 0 1.1em;font-size:.88em;display:flex;justify-content:space-between}
.tsec{margin:.75em 0 .45em;font-weight:700;font-size:.95em}
.tsec-off{margin-left:7px}
.tq{margin:0 0 .45em;font-size:.88em;display:flex;gap:.45em;align-items:baseline}
.tq-in{padding-left:1em}
.tn{flex:none}
.tm{margin-left:auto;padding-left:.9em;flex:none}
.tq-in .tm{padding-right:.8em}
/* option rows: indented under their stem, and deliberately not on a shared
   grid — hand-typed options never line up between questions */
.tq-opt{padding-left:1.5em;font-size:.84em;margin-bottom:.5em}
.tq-opt2{padding-left:2.1em}

.notes{position:relative;display:flex;flex-direction:column;gap:10px;margin:0;padding:0;list-style:none}
.mnote{display:flex;align-items:center;gap:6px;font-family:Caveat,cursive;
  font-size:17px;line-height:1.15;font-weight:700}
.mnote .ar{width:34px;height:16px;flex:none}
.mnote .tk{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;
  margin-right:5px;border-radius:50%;background:#17b26a;color:#fff;
  font-family:Inter,system-ui,sans-serif;font-size:8px;font-weight:800;vertical-align:1px}
.mnote.bad{color:#fda29b}
.mnote.good{color:#75e0a7}
/* On a phone the red notes stack ABOVE the page and the green ones BELOW,
   so the arrows cannot point inward the way they do in the desktop margins.
   Red sits on the left of its line pointing down-left at the typed half;
   green sits on the right pointing up-right at ours. */
.notes-l .mnote{flex-direction:row;justify-content:flex-start}
.notes-l .ar{order:-1;transform:rotate(180deg)}
.notes-r .mnote{flex-direction:row;justify-content:flex-end}
.notes-r .ar{order:1;transform:none}

@media(min-width:900px){
  .split{grid-template-columns:minmax(0,1fr) minmax(0,2.2fr) minmax(0,1fr);gap:14px;align-items:stretch}
  .notes{display:block}
  .mnote{position:absolute;top:var(--top);width:100%;margin:0;font-size:19px}
  /* back to margin notes pointing inward at the page between them */
  .notes-l .mnote{flex-direction:row;justify-content:flex-end;text-align:right}
  .notes-l .ar{order:1;transform:rotate(-8deg)}
  .notes-r .mnote{flex-direction:row;justify-content:flex-start;text-align:left}
  .notes-r .ar{order:-1;transform:scaleX(-1) rotate(8deg)}
  .mnote .ar{width:44px;height:20px}
  .tpage{font-size:9px}
  .ba-tag{font-size:12px}
}

/* Gradient label on a ghost button. The gradient is clipped to the glyphs,
   so it needs its own span — one element cannot both clip a background to
   its text and carry the button's own background. */
.btn.gradtext .g{background:var(--grad-premium);-webkit-background-clip:text;
  background-clip:text;color:transparent}
.btn.gradtext .arrow{color:var(--blue-600)}


/* ── Boards ────────────────────────────────────────────────────────────────
   A status board, not a logo wall. The chip is the point: a teacher scanning
   for their own board needs to know in one glance whether it is there, and a
   page that honestly says "coming" for most of them is what keeps the two that
   say "live" believable. */
.boardgrid{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.bcard{border:1px solid var(--gm-200);border-radius:14px;padding:13px 15px;background:#fff;
  box-shadow:var(--sh-xs)}
.bcard b{display:block;font-size:14.5px;font-weight:700;color:var(--gm-900);margin-top:7px;
  line-height:1.3}
.bcard .bmeta{display:block;font-size:12px;color:var(--gm-500);margin-top:3px;line-height:1.4}
.bcard .bstat{display:inline-block;font-size:9.5px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;padding:3px 8px;border-radius:999px;
  background:var(--gm-100);color:var(--gm-500);border:1px solid var(--gm-200)}
.bcard.is-live{border-color:#abefc6;background:linear-gradient(180deg,var(--su-50),#fff 60%)}
.bcard.is-live .bstat{background:var(--su-50);color:var(--su-700);border-color:#abefc6}
.bcard.is-soon{border-color:var(--blue-200);background:linear-gradient(180deg,var(--blue-25),#fff 60%)}
.bcard.is-soon .bstat{background:var(--blue-50);color:var(--blue-800);border-color:var(--blue-100)}
.boardfoot{margin-top:18px;font-size:13.5px;line-height:1.65;color:var(--gm-600);
  max-width:72ch;margin-inline:auto;text-align:center}
.boardfoot b{color:var(--gm-900)}
.boardfoot a{color:var(--blue-800);font-weight:600;border-bottom:1.5px solid var(--blue-200);
  white-space:nowrap}

@media(min-width:600px){ .boardgrid{grid-template-columns:repeat(2,1fr);gap:12px} }
@media(min-width:900px){ .boardgrid{grid-template-columns:repeat(4,1fr)} }

/* ── Sub-pages ─────────────────────────────────────────────────────────────
   The landing page's hero is a stage: a rotating deck, a stroke sprite, four
   layered panels. A sub-page that borrowed it would take three seconds to say
   one sentence. These pages get a quiet band instead — eyebrow, headline,
   standfirst, two buttons — so the answer the visitor searched for is the
   first thing on screen rather than the second. */
.subhero{position:relative;overflow:hidden;padding:44px 0 40px;
  background:linear-gradient(180deg,var(--blue-25),#fff 78%);
  border-bottom:1px solid var(--gm-200)}
.subhero .wrap{max-width:860px;text-align:center}
.subhero h1{font-size:clamp(28px,5.2vw,44px);line-height:1.12;letter-spacing:-.02em;
  color:var(--gm-900);margin:12px 0 0;font-weight:700}
.subhero .lead{margin:14px auto 0;max-width:62ch}
.subhero .cta-row{justify-content:center;margin-top:22px}
/* Status line for a page about something not yet shipped. Dated on purpose:
   an undated "coming soon" is the sentence that quietly becomes a lie. */
.statusline{display:inline-flex;align-items:center;gap:8px;margin-top:16px;
  padding:7px 14px;border-radius:999px;font-size:12.5px;font-weight:600;
  background:var(--wa-50);color:var(--wa-700);border:1px solid var(--wa-100)}
.statusline.is-live{background:var(--su-50);color:var(--su-700);border-color:var(--su-100)}
.statusline .dot{width:7px;height:7px;border-radius:999px;background:currentColor;flex:none}
/* The one board signal above the fold on the landing page needs to say what is
   next, or it reads as the whole answer. */
.soonlink{color:var(--blue-800);font-weight:600;border-bottom:1px solid var(--blue-200);
  white-space:nowrap}

/* Long-form body copy — used by the sub-pages and by every blog post. Sized
   for reading, not for scanning: 68ch, 17px, 1.75. */
.prose{max-width:68ch;margin-inline:auto;font-size:17px;line-height:1.75;color:var(--gm-700)}
.prose > * + *{margin-top:18px}
.prose h2{font-size:clamp(21px,3.4vw,27px);line-height:1.25;color:var(--gm-900);
  font-weight:700;letter-spacing:-.015em;margin-top:40px;scroll-margin-top:calc(var(--navh) + 16px)}
.prose h3{font-size:18.5px;line-height:1.35;color:var(--gm-900);font-weight:700;margin-top:28px}
.prose strong{color:var(--gm-900);font-weight:600}
/* :not(.btn) is load-bearing. `.prose a` is (0,1,1) and `.btn` is (0,1,0),
   so without it every button inside a prose block loses its own colour and
   renders as blue underlined text on a blue fill. */
.prose a:not(.btn){color:var(--blue-800);font-weight:600;border-bottom:1.5px solid var(--blue-200)}
.prose a:not(.btn):hover{border-bottom-color:var(--blue-600)}
.prose ul,.prose ol{padding-left:22px}
.prose li + li{margin-top:9px}
.prose li::marker{color:var(--gm-400)}
.prose blockquote{margin-inline:0;padding:14px 18px;border-left:3px solid var(--blue-200);
  background:var(--blue-25);border-radius:0 12px 12px 0;color:var(--gm-800);font-size:16.5px}
.prose figure{margin-inline:0}
.prose figcaption{margin-top:8px;font-size:13px;color:var(--gm-500);text-align:center}
.prose table{width:100%;border-collapse:collapse;font-size:15px;display:block;overflow-x:auto}
.prose th,.prose td{padding:10px 12px;border-bottom:1px solid var(--gm-200);text-align:left;
  vertical-align:top}
.prose th{font-weight:700;color:var(--gm-900);background:var(--gm-50);white-space:nowrap}
/* A callout for the thing the reader must not miss. */
.prose .note{padding:16px 18px;border-radius:14px;background:var(--gm-50);
  border:1px solid var(--gm-200);font-size:16px}
.prose .note b{color:var(--gm-900)}

/* ── Blog ──────────────────────────────────────────────────────────────────
   Linked from the footer, not the nav. A blog in the primary navigation sends
   a buying visitor sideways; in the footer it is found by the people who came
   looking for it and by the crawlers that follow every link.
   Cover art is inline SVG, not photography — it scales, it weighs almost
   nothing, it needs no image pipeline, and it can be tinted from the same
   tokens as the rest of the site. */
.bloghead{padding:40px 0 8px;background:linear-gradient(180deg,var(--blue-25),#fff 80%)}
.bloghead .wrap{max-width:760px;text-align:center}
.postgrid{list-style:none;margin:28px 0 0;padding:0;display:grid;gap:18px}
@media(min-width:680px){ .postgrid{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1040px){ .postgrid{grid-template-columns:repeat(3,1fr)} }
.postcard{position:relative;display:flex;flex-direction:column;background:#fff;
  border:1px solid var(--gm-200);border-radius:18px;overflow:hidden;box-shadow:var(--sh-xs);
  transition:transform .22s var(--ease-ios),box-shadow .22s var(--ease-ios),border-color .22s}
.postcard:hover{transform:translateY(-3px);box-shadow:var(--sh-lg);border-color:var(--blue-200)}
.postcard .cover{display:block;width:100%;aspect-ratio:16/9;background:var(--gm-50);
  border-bottom:1px solid var(--gm-200)}
.postcard .cover svg{display:block;width:100%;height:100%}
.postcard .body{padding:16px 18px 18px;display:flex;flex-direction:column;flex:1}
.postcard h2,.postcard h3{font-size:17.5px;line-height:1.32;color:var(--gm-900);font-weight:700;
  letter-spacing:-.01em;margin:9px 0 0}
.postcard p{margin:8px 0 0;font-size:14px;line-height:1.6;color:var(--gm-600)}
.postcard .pmeta{margin-top:auto;padding-top:14px;display:flex;align-items:center;gap:8px;
  font-size:12.5px;color:var(--gm-500)}
/* The whole card is the link, but only the title is the accessible name — a
   stretched pseudo-element keeps one link per card instead of three. */
.postcard a.stretch::after{content:"";position:absolute;inset:0}
.postcard a.stretch{color:inherit}
.ptag{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.07em;
  text-transform:uppercase;padding:3px 9px;border-radius:999px;
  background:var(--blue-50);color:var(--blue-800);border:1px solid var(--blue-100)}
.ptag.is-classroom{background:var(--su-50);color:var(--su-700);border-color:var(--su-100)}
.ptag.is-product{background:var(--wa-50);color:var(--wa-700);border-color:var(--wa-100)}

/* A post. The cover sits full-bleed above the title, the way a real magazine
   piece does, then the column narrows for reading. */
.post{padding:0 0 8px}
.postcover{max-width:940px;margin:24px auto 0;border-radius:20px;overflow:hidden;
  border:1px solid var(--gm-200);box-shadow:var(--sh-md);background:#fff}
.postcover svg{display:block;width:100%;height:auto}
.posthead{max-width:760px;margin:26px auto 0;text-align:center}
.posthead h1{font-size:clamp(26px,4.6vw,40px);line-height:1.16;letter-spacing:-.02em;
  color:var(--gm-900);font-weight:700;margin:12px 0 0}
.posthead .pmeta{margin-top:14px;display:flex;justify-content:center;align-items:center;
  gap:8px;font-size:13px;color:var(--gm-500);flex-wrap:wrap}
.postbody{margin-top:34px}
.postfoot{max-width:68ch;margin:44px auto 0;padding-top:26px;border-top:1px solid var(--gm-200)}
.postfoot h2{font-size:15px;font-weight:700;color:var(--gm-900);margin:0 0 12px}
.morelist{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.morelist a{display:flex;justify-content:space-between;gap:14px;align-items:baseline;
  padding:12px 15px;border:1px solid var(--gm-200);border-radius:13px;background:#fff;
  font-size:15px;font-weight:600;color:var(--gm-800);transition:border-color .2s,background .2s}
.morelist a:hover{border-color:var(--blue-200);background:var(--blue-25)}
.morelist .mt{font-size:12px;font-weight:600;color:var(--gm-400);white-space:nowrap}

/* Cover-art primitives. Every cover is built from these so the posts read as
   one publication rather than as unrelated graphics: a tinted field,
   soft-shadowed paper, and a headline set in the site's own type. */
.cvr .field{fill:var(--blue-25)}
.cvr .ink{fill:var(--gm-900)}
.cvr .dim{fill:var(--gm-500)}
.cvr .rule{stroke:var(--gm-200);stroke-width:2;fill:none}
.cvr .paper{fill:#fff;stroke:var(--gm-200);stroke-width:1.5}
.cvr .accent{fill:var(--brand)}
.cvr .warm{fill:#EB6659}
.cvr .good{fill:var(--su-500)}
.cvr text{font-family:Outfit,system-ui,sans-serif;font-weight:700}

}
