/* ============================================================
   scenaristo — marketing site
   Warm-editorial system, extended from the product's own tokens.
   ============================================================ */

:root{
  /* paper / surfaces */
  --paper:#FBF6EE; --paper-2:#F4ECDC; --paper-3:#EFE6D4;
  --surface:#FFFDF8; --surface-2:#FAF4EA;
  /* ink */
  --ink:#221F18; --ink-soft:#2B271E; --ink-2:#6C6457; --ink-3:#A89E8C; --ink-4:#C6BCA8;
  /* lines */
  --line:#EBE2D1; --line-2:#DDD0BA;
  /* accent (tweakable) */
  --accent:#C2542E;
  --accent-soft:color-mix(in oklab, var(--accent) 13%, var(--paper));
  --accent-mid:color-mix(in oklab, var(--accent) 26%, var(--paper));
  --accent-ink:color-mix(in oklab, var(--accent) 70%, var(--ink));
  /* dark band */
  --night:#1C1913; --night-2:#262119;
  --night-ink:#F4ECDD; --night-ink-2:#B7AC97; --night-line:#3A332785;

  --sans:'Hanken Grotesk',system-ui,-apple-system,sans-serif;
  --serif:'Newsreader',Georgia,serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;

  --maxw:1180px;
  --gut:clamp(20px,5vw,64px);
  --sect-y:clamp(72px,9vw,132px);
  --radius:16px;
}
[data-density="compact"]{ --sect-y:clamp(52px,6vw,88px); }

*{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--sans); font-size:18px; line-height:1.6;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
::selection{ background:var(--accent-mid); }
a{ color:inherit; text-decoration:none; }
img{ max-width:100%; display:block; }
button{ font-family:inherit; cursor:pointer; border:none; background:none; color:inherit; }
h1,h2,h3,h4,p{ margin:0; }

.wrap{ max-width:var(--maxw); margin:0 auto; padding-inline:var(--gut); }
.serif{ font-family:var(--serif); font-weight:400; letter-spacing:-.012em; }
.it{ font-style:italic; }
.acc{ color:var(--accent-ink); }

/* ---------- eyebrow ---------- */
.eyebrow{
  display:inline-flex; align-items:center; gap:10px;
  font-family:var(--mono); font-size:12px; font-weight:500;
  letter-spacing:.18em; text-transform:uppercase; color:var(--ink-3);
}
.eyebrow::before{ content:""; width:22px; height:1px; background:var(--ink-4); }
.eyebrow.no-rule::before{ display:none; }

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; gap:9px; justify-content:center;
  font-size:15.5px; font-weight:600; line-height:1; padding:15px 22px;
  border-radius:12px; transition:transform .14s ease, filter .18s ease, background .18s, color .18s;
  white-space:nowrap;
}
.btn svg{ width:18px; height:18px; }
.btn-primary{ background:var(--accent); color:#fff; box-shadow:0 2px 10px color-mix(in oklab,var(--accent) 36%,transparent); }
.btn-primary:hover{ transform:translateY(-2px); filter:brightness(1.05); }
.btn-ghost{ background:var(--surface); color:var(--ink); box-shadow:inset 0 0 0 1px var(--line-2); }
.btn-ghost:hover{ transform:translateY(-2px); background:var(--surface-2); box-shadow:inset 0 0 0 1px var(--line-2),0 6px 18px rgba(40,28,16,.08); }
.btn-dark{ background:var(--ink); color:var(--paper); }
.btn-dark:hover{ transform:translateY(-2px); background:#000; }
.btn-link{ display:inline-flex; align-items:center; gap:7px; font-weight:600; color:var(--accent-ink); font-size:15px; }
.btn-link svg{ width:16px; height:16px; transition:transform .16s; }
.btn-link:hover svg{ transform:translateX(3px); }

/* ---------- top nav ---------- */
.nav{
  position:sticky; top:0; z-index:50;
  background:color-mix(in oklab,var(--paper) 82%,transparent);
  -webkit-backdrop-filter:blur(14px) saturate(150%); backdrop-filter:blur(14px) saturate(150%);
  border-bottom:1px solid var(--line);
}
.nav-in{ max-width:var(--maxw); margin:0 auto; padding:13px var(--gut);
  display:flex; align-items:center; justify-content:space-between; gap:24px; }
.brand{ display:flex; align-items:center; gap:11px; }
.brand-mark{
  width:32px; height:32px; display:block; flex:0 0 auto;
}
.brand-word{ font-family:var(--serif); font-style:italic; font-size:23px; letter-spacing:.2px; }
.nav-links{ display:flex; align-items:center; gap:30px; }
.nav-links a{ font-size:15px; font-weight:500; color:var(--ink-2); transition:color .15s; }
.nav-links a:hover,.nav-links a.on{ color:var(--ink); }
.nav-cta{ display:flex; align-items:center; gap:14px; }
.nav-cta .btn{ padding:11px 17px; font-size:14.5px; }

/* ---------- mobile nav toggle + panel ---------- */
.nav-menu-btn{
  display:none; flex:0 0 auto; align-items:center; justify-content:center;
  width:40px; height:40px; border-radius:10px; position:relative;
  background:var(--surface); box-shadow:inset 0 0 0 1px var(--line-2); color:var(--ink);
}
.nav-menu-btn svg{ width:19px; height:19px; position:absolute; transition:opacity .15s ease, transform .18s ease; }
.nav-menu-btn .ic-close{ opacity:0; transform:rotate(-45deg) scale(.7); }
.nav-menu-btn[aria-expanded="true"] .ic-open{ opacity:0; transform:rotate(45deg) scale(.7); }
.nav-menu-btn[aria-expanded="true"] .ic-close{ opacity:1; transform:none; }

.nav-mobile{
  display:none; max-height:0; overflow:hidden;
  background:var(--paper); border-top:0 solid var(--line);
  transition:max-height .3s cubic-bezier(.2,.7,.3,1);
}
.nav-mobile.open{ max-height:80vh; overflow-y:auto; border-top-width:1px; }
.nav-mobile-links{ display:flex; flex-direction:column; padding:6px var(--gut) 0; }
.nav-mobile-links a{ padding:15px 2px; font-size:16.5px; font-weight:500; color:var(--ink-2); border-bottom:1px solid var(--line); }
.nav-mobile-links a.on{ color:var(--ink); }
.nav-mobile-cta{ display:flex; flex-direction:column; gap:10px; padding:18px var(--gut) 24px; }
.nav-mobile-cta .btn{ width:100%; }
body.menu-open{ overflow:hidden; }

/* ---------- hero ---------- */
.hero{ padding-top:clamp(48px,7vw,92px); padding-bottom:var(--sect-y); position:relative; overflow:hidden; }
.hero-grid{ display:grid; grid-template-columns:1.02fr 1fr; gap:clamp(32px,5vw,72px); align-items:center; }
.hero-h1{ font-family:var(--serif); font-weight:400; letter-spacing:-.02em; line-height:1.02;
  font-size:clamp(40px,5.6vw,76px); margin:22px 0 0; text-wrap:balance; }
.hero-sub{ font-size:clamp(18px,1.5vw,21px); line-height:1.62; color:var(--ink-2); margin-top:24px; max-width:34ch; text-wrap:pretty; }
.hero-cta{ display:flex; flex-wrap:wrap; gap:13px; margin-top:32px; }
.hero-meta{ display:flex; align-items:center; gap:11px; margin-top:20px; font-family:var(--mono);
  font-size:12.5px; color:var(--ink-3); flex-wrap:wrap; }
.hero-meta .dot{ width:3px; height:3px; border-radius:50%; background:var(--ink-4); }

/* centered hero variant */
[data-hero="centered"] .hero-grid{ grid-template-columns:1fr; text-align:center; max-width:880px; margin-inline:auto; }
[data-hero="centered"] .hero-copy{ display:flex; flex-direction:column; align-items:center; }
[data-hero="centered"] .hero-sub{ max-width:54ch; }
[data-hero="centered"] .hero-cta{ justify-content:center; }
[data-hero="centered"] .hero-meta{ justify-content:center; }
[data-hero="centered"] .hero-shot{ margin-top:clamp(40px,5vw,64px); }
[data-hero="centered"] .hero-shot .frame{ transform:none; }

/* ---------- product frame ---------- */
.frame{
  position:relative; border-radius:14px; overflow:hidden; background:var(--ink);
  box-shadow:0 1px 0 rgba(255,255,255,.4) inset, 0 30px 70px -28px rgba(40,28,16,.5),
    0 8px 24px -12px rgba(40,28,16,.3), 0 0 0 1px var(--line-2);
}
.frame img{ display:block; width:100%; height:auto; }
.hero-shot .frame{ transform:perspective(1600px) rotateY(-3deg) rotateX(1.4deg); transition:transform .5s cubic-bezier(.2,.7,.3,1); }
.hero-shot .frame:hover{ transform:perspective(1600px) rotateY(0deg) rotateX(0deg); }
.frame img.zoomable{ cursor:zoom-in; }
.frame img.zoomable:focus-visible{ outline:2px solid var(--accent-ink); outline-offset:-2px; }

/* ---------- screenshot lightbox ---------- */
.lightbox{ border:0; padding:0; background:transparent; overflow:visible; }
.lightbox:focus{ outline:none; }
.lightbox::backdrop{ background:rgba(15,11,7,.85); -webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px); }
.lightbox figure{ margin:0; }
.lightbox img{
  display:block; width:auto; height:auto; max-width:min(1848px, 94vw); max-height:86vh;
  border-radius:12px; cursor:zoom-out;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.08);
}
.lightbox-cap{
  margin:14px auto 0; text-align:center;
  font-family:var(--mono); font-size:12px; letter-spacing:.04em; color:rgba(255,255,255,.75);
}
.lightbox-close{
  position:fixed; top:18px; right:22px; width:40px; height:40px; border:0; border-radius:50%;
  font-size:26px; line-height:1; color:#fff; background:rgba(255,255,255,.12); cursor:pointer;
}
.lightbox-close:hover{ background:rgba(255,255,255,.22); }
html.lightbox-open{ overflow:hidden; }
@media (prefers-reduced-motion:no-preference){
  .lightbox[open]{ animation:lb-in .18s ease; }
  @keyframes lb-in{ from{ opacity:0; transform:scale(.98); } }
}

.frame-tag{
  position:absolute; left:14px; bottom:14px; z-index:3;
  font-family:var(--mono); font-size:11px; letter-spacing:.04em; color:#fff;
  background:rgba(15,11,7,.5); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  padding:5px 10px; border-radius:7px;
}
.shot-float{ position:relative; }
.shot-float .pin{
  position:absolute; z-index:4; background:var(--surface); border:1px solid var(--line-2);
  border-radius:12px; padding:11px 14px; box-shadow:0 14px 36px -14px rgba(40,28,16,.4);
  font-size:13.5px; max-width:230px;
}
.shot-float .pin .pin-lbl{ font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--accent-ink); margin-bottom:4px; }
.shot-float .pin b{ font-weight:600; }

/* ---------- hero shot at product scale ----------

   The centered hero variant above puts the shot under the copy
   instead of beside it, which frees it from the 48% column it shares in the
   two-column hero and lets it run wider than the 1180px text measure.

   1240px is not an arbitrary breakout. The shots are 1848px assets declared
   at 924, so they carry exactly 2x for a 924px box. At 1240 they are down to
   1.49x, which is still past 1x and reads clean on a laptop, but a retina
   display is now interpolating. Going wider than this needs new captures
   before it is worth doing. */
.hero-shot-wide{ padding-inline:var(--gut); }
.hero-shot-wide .frame{ max-width:1240px; margin-inline:auto; }

/* Everything above the shot is on a budget, because the shot only makes this
   argument if some of it is in the fold. Stacking the copy over the shot
   instead of beside it costs a full column of height, and these numbers buy
   roughly 150px of it back: the frame lands about a third visible at 900px.

   The display size drops to 62px for a second reason. At 76px on this measure
   the headline balanced onto two lines that split "deleting words" across the
   break, which cuts the one phrase in the sentence that is set in terracotta
   and carries the whole idea. */
.hero[data-hero="centered"]{ padding-top:clamp(40px,4vw,52px); }
/* The display measure is capped independently of the copy block below it.
   Given the full 752px the headline balances onto two lines and breaks
   "deleting words" across them, which splits the one phrase set in terracotta.
   Under 660 it lands in three, whole.

   The cap is in em, so it is a measure in type rather than in pixels and it
   scales with every value the clamp can take. A fixed 540px was right at 62px
   and wrong the moment the short-viewport rule below dropped the display to
   52, where the same 540 fits more per line and the headline balanced back
   onto two, splitting the phrase again. 8.7em is that same 540 at 62px, and
   stays proportional all the way down.

   em rather than ch: ch is the width of Newsreader's zero, which means
   nothing to Japanese or Korean.

   It is also not a tightening. The two-column hero gives this headline a
   1.02fr share of 1052px less a 72px gap, which is 495px in every locale, so
   this hands all twelve more room than they have today, not less.

   8.7em rather than the 9em the break actually flips at, so that a fallback
   metric or a rounding difference cannot land the page on the wrong side. */
[data-hero="centered"] .hero-h1{ font-size:clamp(38px,4.6vw,62px); margin-top:16px; max-width:8.7em; }
[data-hero="centered"] .hero-sub{ max-width:62ch; margin-top:18px; }
[data-hero="centered"] .hero-cta{ margin-top:26px; }
[data-hero="centered"] .hero-shot{ margin-top:clamp(32px,3.4vw,44px); }

/* Short viewports get a second, harder pass at the same budget.

   Stacking the copy over the shot trades away the one thing the two-column
   hero was good at: it put the whole shot in the fold at any height, because
   the shot sat beside the copy rather than under it. At 1440x760, a 13"
   laptop, the untightened stack leaves a 141px strip of window chrome. This
   pulls the frame up by about 100px, which is a quarter of the shot rather
   than a sliver.

   Keyed on height alone, so a phone held in landscape gets it too. The lower
   bound of the display clamp is unchanged, so nothing here shrinks the
   headline on a narrow screen that is merely short. */
@media (max-height:820px){
  .hero[data-hero="centered"]{ padding-top:clamp(24px,3vw,30px); }
  [data-hero="centered"] .hero-h1{ font-size:clamp(38px,4.6vw,52px); }
  [data-hero="centered"] .hero-sub{ margin-top:14px; }
  [data-hero="centered"] .hero-cta{ margin-top:20px; }
  [data-hero="centered"] .hero-meta{ margin-top:14px; }
  [data-hero="centered"] .hero-shot{ margin-top:clamp(24px,2.6vw,30px); }
}

/* ---------- generic section ---------- */
.section{ padding-block:var(--sect-y); }
.section.line-top{ border-top:1px solid var(--line); }
.sect-head{ max-width:720px; }
.sect-head.center{ margin-inline:auto; text-align:center; }
.sect-title{ font-family:var(--serif); font-weight:400; letter-spacing:-.016em; line-height:1.06;
  font-size:clamp(30px,3.9vw,50px); margin-top:18px; text-wrap:balance; }
.sect-lede{ font-size:clamp(17px,1.4vw,20px); line-height:1.6; color:var(--ink-2); margin-top:18px; text-wrap:pretty; }
.sect-head.center .sect-lede{ margin-inline:auto; max-width:60ch; }

/* split feature row */
.split{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(36px,5vw,80px); align-items:center; }
.split.rev .split-media{ order:-1; }
.split-copy .eyebrow{ margin-bottom:18px; }
.split-copy .split-title{ font-family:var(--serif); font-weight:400; letter-spacing:-.015em; line-height:1.08;
  font-size:clamp(28px,3.4vw,44px); text-wrap:balance; }
.split-copy p{ font-size:18px; line-height:1.62; color:var(--ink-2); margin-top:18px; text-wrap:pretty; }
.split-copy .split-cta{ margin-top:26px; }
.mini-list{ list-style:none; padding:0; margin:24px 0 0; display:flex; flex-direction:column; gap:14px; }
.mini-list li{ display:flex; gap:13px; align-items:flex-start; font-size:16px; color:var(--ink-soft); }
.mini-list .ic{ flex:0 0 auto; width:26px; height:26px; border-radius:8px; display:grid; place-items:center;
  background:var(--accent-soft); color:var(--accent-ink); margin-top:1px; }
.mini-list .ic svg{ width:15px; height:15px; }
.mini-list b{ font-weight:600; color:var(--ink); }

/* ---------- dark band ---------- */
.band-dark{ background:var(--night); color:var(--night-ink); }
.band-dark .sect-title,.band-dark .split-title{ color:var(--night-ink); }
.band-dark .sect-lede,.band-dark .split-copy p{ color:var(--night-ink-2); }
.band-dark .eyebrow{ color:var(--night-ink-2); }
.band-dark .eyebrow::before{ background:var(--night-line); }
.band-dark .mini-list li{ color:var(--night-ink); }
.band-dark .mini-list .ic{ background:color-mix(in oklab,var(--accent) 26%,var(--night)); color:#fff; }
.privacy-cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; margin-top:clamp(40px,5vw,60px); }
.pcard{ background:var(--night-2); border:1px solid var(--night-line); border-radius:var(--radius); padding:26px 24px; }
.pcard .pic{ width:40px; height:40px; border-radius:11px; display:grid; place-items:center;
  background:color-mix(in oklab,var(--accent) 22%,var(--night)); color:#fff; margin-bottom:18px; }
.pcard .pic svg{ width:21px; height:21px; }
.pcard h3{ font-family:var(--serif); font-weight:500; font-size:21px; color:var(--night-ink); }
.pcard p{ font-size:15px; line-height:1.55; color:var(--night-ink-2); margin-top:9px; }

/* ---------- feature grid (cards) ---------- */
.fgrid{ display:grid; grid-template-columns:repeat(2,1fr); gap:18px; margin-top:clamp(40px,5vw,56px); }
.fcard{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:30px 28px; transition:transform .16s ease, box-shadow .2s ease, border-color .2s; }
.fcard:hover{ transform:translateY(-3px); border-color:var(--line-2); box-shadow:0 18px 40px -22px rgba(40,28,16,.32); }
.fcard .fic{ width:42px; height:42px; border-radius:11px; display:grid; place-items:center;
  background:var(--accent-soft); color:var(--accent-ink); margin-bottom:18px; }
.fcard .fic svg{ width:22px; height:22px; }
.fcard h3{ font-family:var(--serif); font-weight:500; font-size:22px; letter-spacing:-.01em; }
.fcard p{ font-size:15.5px; line-height:1.58; color:var(--ink-2); margin-top:9px; text-wrap:pretty; }
.fcard .tag{ display:inline-block; margin-top:14px; font-family:var(--mono); font-size:11px;
  letter-spacing:.04em; color:var(--ink-3); padding:4px 9px; border-radius:6px; background:var(--paper-2); }

/* ---------- how it works steps ---------- */
.steps{ display:grid; grid-template-columns:repeat(4,1fr); gap:24px; margin-top:clamp(44px,5vw,60px); counter-reset:step; }
.step{ position:relative; }
.step-n{ font-family:var(--mono); font-size:13px; color:var(--accent-ink); font-weight:600; letter-spacing:.05em; }
.step-rule{ height:1px; background:var(--line-2); margin:14px 0 16px; position:relative; }
.step-rule::before{ content:""; position:absolute; left:0; top:-2px; width:5px; height:5px; border-radius:50%; background:var(--accent); }
.step h3{ font-family:var(--serif); font-weight:500; font-size:20px; }
.step p{ font-size:15px; line-height:1.55; color:var(--ink-2); margin-top:8px; }

/* ---------- stage rail ----------

   The same four steps as .steps, but read as one continuous
   narrative instead of four parallel columns: the rail scrolls, the product
   pane stays pinned beside it, and the shot swaps as each step takes over.

   Kept as its own component rather than a modifier on .steps, because .steps
   is also on /podcast, /shorts and /download and none of them have a product
   shot per step to pin.

   The four-column grid it replaces was also the worst cell in the layout for
   long locales: every title had 25% of the measure. Here a title has a full
   column of its own, so French and Finnish stop being the constraint. */
.stage{
  display:grid; grid-template-columns:minmax(260px,.85fr) 1.15fr;
  gap:clamp(36px,5vw,72px); align-items:start;
  margin-top:clamp(44px,5vw,64px);
}

.stage-step{ position:relative; padding:clamp(20px,2.4vw,28px) 0 clamp(20px,2.4vw,28px) 24px; }
/* One continuous rule down the rail, with the active segment in terracotta.
   Drawn per step rather than as one element behind them so it needs no
   measurement and cannot drift out of sync with the active step. */
.stage-step::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:2px;
  background:var(--line-2); transition:background .3s ease;
}
.stage-step.on::before{ background:var(--accent); }
.stage-step .step-n{ font-family:var(--mono); font-size:13px; font-weight:600; letter-spacing:.05em; color:var(--ink-3); transition:color .3s ease; }
.stage-step.on .step-n{ color:var(--accent-ink); }
.stage-step h3{ font-family:var(--serif); font-weight:500; font-size:clamp(21px,2.3vw,27px); margin-top:10px; color:var(--ink-3); transition:color .3s ease; text-wrap:balance; }
.stage-step p{ font-size:15.5px; line-height:1.56; margin-top:9px; color:var(--ink-3); transition:color .3s ease; text-wrap:pretty; }
.stage-step.on h3{ color:var(--ink); }
.stage-step.on p{ color:var(--ink-2); }

/* The pane is a 924x520 shot in a column about 560px wide, so it is only some
   317px tall against a rail four steps long. Pinned at the nav it sits high
   with a screen of empty paper under it; 20vh drops it toward the optical
   centre of the rail instead. The 96px floor keeps it clear of the sticky nav
   on short viewports, where 20vh would tuck it underneath. */
.stage-media{ position:sticky; top:clamp(96px,20vh,200px); }
/* The frame holds four absolutely-stacked shots, so it needs its own height:
   with every child out of flow there is nothing left to give it one. The ratio
   is the assets' own 924x520. */
.stage-media .frame{ aspect-ratio:924/520; }
.stage-media .frame img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .4s ease;
}
/* The first shot and the first step ship with .on already in the markup, so
   the section is a working still frame rather than an empty box when the
   script never runs. */
.stage-media .frame img.on{ opacity:1; }

@media (prefers-reduced-motion:reduce){
  .stage-media .frame img{ transition:none; }
  .stage-step,.stage-step::before,.stage-step h3,.stage-step p,.stage-step .step-n{ transition:none; }
}

/* ---------- big CTA band ---------- */
.cta-band{ padding-block:var(--sect-y); border-top:1px solid var(--line); }
.cta-inner{ text-align:center; max-width:760px; margin-inline:auto; }
.cta-inner .sect-title{ font-size:clamp(32px,4.4vw,58px); }
.cta-actions{ display:flex; flex-wrap:wrap; gap:14px; justify-content:center; margin-top:30px; }
.cta-fine{ margin-top:18px; font-family:var(--mono); font-size:12.5px; color:var(--ink-3); }

/* ---------- pricing ---------- */
.price-grid{ display:grid; grid-template-columns:1.1fr 1fr; gap:22px; margin-top:clamp(40px,5vw,56px); align-items:stretch; }
.plan{ background:var(--surface); border:1px solid var(--line-2); border-radius:20px; padding:34px 32px; display:flex; flex-direction:column; }
.plan.feature{ background:var(--ink); color:var(--paper); border-color:var(--ink); position:relative; }
.plan-badge{ position:absolute; top:24px; right:28px; font-family:var(--mono); font-size:11px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--accent); background:color-mix(in oklab,var(--accent) 18%,var(--ink)); padding:5px 11px; border-radius:7px; }
.plan h3{ font-family:var(--serif); font-weight:500; font-size:26px; }
.plan .plan-price{ display:flex; align-items:baseline; gap:8px; margin-top:16px; }
.plan .plan-price b{ font-family:var(--serif); font-weight:500; font-size:clamp(44px,6vw,64px); line-height:1; letter-spacing:-.02em; }
.plan .plan-price span{ font-size:15px; color:var(--ink-3); }
.plan.feature .plan-price span{ color:var(--night-ink-2); }
.plan .plan-desc{ font-size:16px; line-height:1.55; margin-top:14px; color:var(--ink-2); }
.plan.feature .plan-desc{ color:var(--night-ink-2); }
.plan-feats{ list-style:none; padding:0; margin:24px 0 0; display:flex; flex-direction:column; gap:13px; flex:1; }
.plan-feats li{ display:flex; gap:11px; align-items:flex-start; font-size:15.5px; }
.plan-feats .ck{ flex:0 0 auto; width:20px; height:20px; border-radius:6px; display:grid; place-items:center;
  background:var(--accent-soft); color:var(--accent-ink); margin-top:1px; }
.plan.feature .plan-feats .ck{ background:color-mix(in oklab,var(--accent) 30%,var(--ink)); color:#fff; }
.plan-feats .ck svg{ width:12px; height:12px; }
.plan-feats .muted{ color:var(--ink-3); }
.plan.feature .plan-feats .muted{ color:var(--night-ink-2); opacity:.7; }
.plan .btn{ margin-top:28px; width:100%; }

/* ---------- faq ---------- */
.faq{ max-width:820px; margin:clamp(40px,5vw,56px) auto 0; }
.faq details{ border-top:1px solid var(--line); padding:4px 0; }
.faq details:last-child{ border-bottom:1px solid var(--line); }
.faq summary{ list-style:none; cursor:pointer; display:flex; align-items:center; justify-content:space-between; gap:20px;
  padding:22px 4px; font-family:var(--serif); font-weight:500; font-size:clamp(19px,1.7vw,23px); color:var(--ink); }
.faq summary::-webkit-details-marker{ display:none; }
.faq .q-ic{ flex:0 0 auto; width:26px; height:26px; border-radius:50%; display:grid; place-items:center;
  border:1px solid var(--line-2); color:var(--ink-2); transition:transform .2s, background .2s, color .2s; }
.faq .q-ic svg{ width:14px; height:14px; }
.faq details[open] .q-ic{ transform:rotate(45deg); background:var(--accent); color:#fff; border-color:transparent; }
.faq .a{ padding:0 4px 24px; font-size:16.5px; line-height:1.62; color:var(--ink-2); max-width:64ch; }

/* ---------- stat row ---------- */
.stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:24px; margin-top:clamp(36px,4vw,52px); }
.stat-c{ border-left:2px solid var(--accent); padding-left:20px; }
.stat-c b{ display:block; font-family:var(--serif); font-weight:500; font-size:clamp(34px,4.4vw,52px); line-height:1; letter-spacing:-.02em; }
.stat-c span{ display:block; margin-top:10px; font-size:15px; color:var(--ink-2); line-height:1.45; }

/* ---------- page hero (subpages) ---------- */
.page-hero{ padding-top:clamp(48px,6vw,84px); padding-bottom:clamp(20px,3vw,40px); }
.page-hero .eyebrow{ margin-bottom:18px; }
.page-hero h1{ font-family:var(--serif); font-weight:400; letter-spacing:-.018em; line-height:1.04;
  font-size:clamp(38px,5vw,68px); text-wrap:balance; max-width:16ch; }
.page-hero p{ font-size:clamp(18px,1.5vw,21px); line-height:1.6; color:var(--ink-2); margin-top:22px; max-width:56ch; text-wrap:pretty; }

/* ---------- footer ---------- */
.footer{ border-top:1px solid var(--line); background:var(--surface-2); padding-block:clamp(48px,6vw,72px) 36px; }
.footer-top{ display:grid; grid-template-columns:1.2fr 1fr 1fr 1fr 1fr; gap:28px; }
.footer-brand .brand{ margin-bottom:16px; }
.footer-brand p{ font-size:15px; line-height:1.55; color:var(--ink-2); max-width:34ch; }
.fcol h4{ font-family:var(--mono); font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-3); margin-bottom:16px; }
.fcol a{ display:block; font-size:15px; color:var(--ink-2); margin-bottom:11px; transition:color .15s; }
.fcol a:hover{ color:var(--ink); }
.footer-bot{ display:flex; align-items:center; justify-content:space-between; gap:20px;
  margin-top:clamp(40px,5vw,60px); padding-top:26px; border-top:1px solid var(--line); flex-wrap:wrap; }
.footer-bot small{ font-size:13px; color:var(--ink-3); }
.footer-bot .made{ font-family:var(--mono); font-size:12px; color:var(--ink-3); }

/* ---------- reveal ---------- */
.reveal{ opacity:0; transform:translateY(18px); transition:opacity .7s cubic-bezier(.2,.7,.3,1), transform .7s cubic-bezier(.2,.7,.3,1); }
.reveal.in{ opacity:1; transform:none; }
@media (prefers-reduced-motion: reduce){ .reveal{ opacity:1; transform:none; transition:none; } html{ scroll-behavior:auto; } }

/* ---------- responsive ---------- */
/* The desktop nav collapses above the 900px content breakpoint.

   .nav-in is capped at 1180px with gutters of clamp(20px,5vw,64px), so the
   bar's content box is 0.9 of the viewport until the cap bites. The widest
   locale, French, needs 891px of it, which wants a viewport of 990px.

   The test that matters is gutter alignment, not horizontal overflow. Content
   can spill out of the box into the gutter without ever producing a
   scrollbar: at 940px French clears the viewport by 2px while sitting 45px
   into a 47px gutter, so the CTA stops lining up with everything below it.
   Checking only for overflow reports that as fine. It is not.

   1024 is the threshold because it is a real device width with 31px to spare
   for French, rather than the 9px that picking the 990px minimum would leave.

   Only the collapse lives here. The tightening below is for phones and would
   look wrong on a tablet showing brand, menu button and one CTA. */
@media (max-width:1023px){
  .nav-links{ display:none; }
  .nav-menu-btn{ display:inline-flex; }
  .nav-mobile{ display:block; }
  .nav-mobile[hidden]{ display:none; }

  /* The stage collapses with the nav rather than at the 900px content
     breakpoint, because its premise is a pane pinned beside a scrolling rail
     and the pane stops earning its column well before the layout stops
     fitting. The column is 1.15 of 2.15 after a 5vw gutter and a 5vw gap, so
     at 901px the shot is 440x248: a thumbnail of an interface, too small to
     read the transcript that is the entire point of showing it. At 1024 it is
     500x282, which is small but legible.

     Below this the shots come out entirely. Pinning one above the rail
     instead would cost more than half the viewport for the length of the
     section, and the rail already reads as what it is without them: a
     numbered list. The dimming goes with them, since nothing is being
     tracked any more.

     Reusing 1023 rather than picking a number: it is already the one
     documented breakpoint in this file between phone and desktop, and a
     second threshold 100px away would be two answers to one question. */
  .stage{ grid-template-columns:1fr; gap:0; }
  .stage-media{ display:none; }
  .stage-step h3{ color:var(--ink); }
  .stage-step p{ color:var(--ink-2); }
  .stage-step .step-n{ color:var(--accent-ink); }
}
@media (max-width:900px){
  .hero-grid{ grid-template-columns:1fr; gap:44px; }
  .hero-sub{ max-width:54ch; }
  .hero-shot .frame{ transform:none; }
  .split{ grid-template-columns:1fr; gap:36px; }
  .split.rev .split-media{ order:0; }
  .privacy-cards{ grid-template-columns:1fr; }
  .fgrid{ grid-template-columns:1fr; }
  .steps{ grid-template-columns:1fr 1fr; gap:30px 24px; }
  .price-grid{ grid-template-columns:1fr; }
  .stats{ grid-template-columns:1fr; gap:20px; }
  .footer-top{ grid-template-columns:1fr 1fr 1fr; gap:30px; }
  .nav-in{ gap:12px; padding-inline:16px; }
  .nav-cta{ gap:8px; }
  .nav-cta .btn-primary{ padding:9px 13px; font-size:13.5px; }
  .nav-menu-btn{ width:38px; height:38px; }
}
@media (max-width:560px){
  body{ font-size:17px; }
  .steps{ grid-template-columns:1fr; }
  .footer-top{ grid-template-columns:1fr; }
}

/* ---------- localization ---------- */

/* Marks a nav link that crosses into English, on the two pages that are not
   localized. The anchor also carries hreflang and lang for crawlers; this is
   the visible half, for readers. */
.nav-en{
  font-family:var(--mono); font-size:9px; letter-spacing:.08em;
  vertical-align:.35em; margin-left:4px; color:var(--ink-3);
}

/* Language picker, in .footer-bot under the copyright. */
.lang-switch{
  display:flex; flex-wrap:wrap; gap:6px 14px;
  margin-top:18px; padding-top:16px; border-top:1px solid var(--line-2);
  width:100%;
}
.lang-switch a{ font-size:13px; color:var(--ink-3); text-decoration:none; }
.lang-switch a:hover{ color:var(--ink); }
.lang-switch a[aria-current]{ color:var(--ink); font-weight:600; }

/* Suggestion banner. Fixed rather than in flow so revealing it causes no
   layout shift: it is unhidden after the page has already painted. */
.lang-banner{
  position:fixed; inset-inline:0; bottom:0; z-index:40;
  display:flex; align-items:center; justify-content:center; gap:14px;
  padding:12px 16px; background:var(--ink); color:var(--paper);
  font-size:14px;
}
/* `display:flex` above is an author rule, so it beats the browser's own
   `[hidden]{display:none}` and the hidden attribute stops meaning anything.
   The banner ships hidden and empty and is only filled when site.js has a
   language to suggest, so without this every other reader, including everyone
   who has dismissed it once, gets an empty dark bar pinned to the bottom of
   every page. */
.lang-banner[hidden]{ display:none; }
.lang-banner a{ color:var(--paper); text-underline-offset:3px; }
.lang-banner button{
  background:none; border:1px solid color-mix(in oklab,var(--paper) 40%,transparent);
  color:var(--paper); border-radius:7px; padding:4px 10px; font-size:13px; cursor:pointer;
}

/* ---------- CJK typefaces ----------

   None of the three brand fonts carry a single CJK glyph, so ja and ko fell
   through to the generic `serif` / `sans-serif` / `monospace` keywords and
   rendered in whatever face the operating system happened to pick. The brand
   serif is the site's whole identity, and the headlines were losing it.

   The Latin family stays first in every stack on purpose. Browsers fall back
   per glyph, not per element, so a Japanese sentence containing MP4, 9:16 or
   −14 LUFS keeps the brand face on the Latin runs and uses the CJK face only
   where it must. Reversing the order would render the numbers in the CJK font.

   Noto Serif JP and Noto Serif KR are requested by Layout.astro, subsetted to
   exactly the characters these dictionaries contain (137 KB and 93 KB). The
   named system faces behind them are not decoration: readers who block Google
   Fonts get Hiragino Mincho or Yu Mincho rather than a lottery.

   Korean is the one place the fallback changes voice. System myungjo is
   Batang, which is dated and poorly hinted at display sizes, so if the webfont
   does not arrive Korean lands on the system gothic instead. A well-set gothic
   is what Korean editorial design uses anyway; a bad myungjo is not.

   Only weight 400 of the CJK serif is loaded. Adding 500 roughly quadruples
   the download, so the seven places that set the serif to 500 drop to 400 here
   instead. On a mincho or myungjo face at heading sizes that is a far smaller
   difference than it is on Newsreader. */

:root:lang(ja){
  --serif:'Newsreader','Noto Serif JP','Hiragino Mincho ProN','Yu Mincho',YuMincho,'Source Han Serif JP',serif;
  --sans:'Hanken Grotesk','Hiragino Sans','Yu Gothic',YuGothic,Meiryo,'Noto Sans JP',system-ui,sans-serif;
  --mono:'IBM Plex Mono','Hiragino Sans','Yu Gothic',Meiryo,ui-monospace,monospace;
}
:root:lang(ko){
  --serif:'Newsreader','Noto Serif KR','Apple SD Gothic Neo','Malgun Gothic',serif;
  --sans:'Hanken Grotesk','Apple SD Gothic Neo','Malgun Gothic','Noto Sans KR',system-ui,sans-serif;
  --mono:'IBM Plex Mono','Apple SD Gothic Neo','Malgun Gothic',ui-monospace,monospace;
}

/* Weight 500 of the CJK serif is not loaded; see above. Without this the
   browser synthesises it, which on CJK means smeared strokes. */
:lang(ja) .pcard h3, :lang(ko) .pcard h3,
:lang(ja) .fcard h3, :lang(ko) .fcard h3,
:lang(ja) .step h3, :lang(ko) .step h3,
:lang(ja) .plan h3, :lang(ko) .plan h3,
:lang(ja) .plan .plan-price b, :lang(ko) .plan .plan-price b,
:lang(ja) .faq summary, :lang(ko) .faq summary,
:lang(ja) .stat-c b, :lang(ko) .stat-c b{
  font-weight:400;
}

/* ---------- CJK line-breaking and tracking ----------

   Latin defaults are wrong for Japanese and Korean in two specific ways, both
   visible in the rendered page rather than theoretical.

   Korean writes spaces between eojeol, not between every word, so the default
   `word-break: normal` is free to break inside one. A real headline came out
   as "자르고, 다듬 / 고, 공개하세요." with 다듬고 split across the line. `keep-all`
   is the fix; `overflow-wrap: anywhere` keeps a single unbreakable run from
   overflowing instead. Japanese does not want keep-all, which would forbid the
   mid-phrase breaks Japanese relies on; it wants strict kinsoku instead, so
   that 、 。 ) ー never begin a line.

   The eyebrow tracks at .18em because it is uppercase Latin. Uppercase is a
   no-op on hangul and kana, so all that survives is the tracking, which pulls
   the characters apart into something that reads as spaced-out text. */

:lang(ko) .hero-h1,
:lang(ko) .sect-title,
:lang(ko) .split-title,
:lang(ko) .page-hero h1,
:lang(ko) .fcard h3,
:lang(ko) p,
:lang(ko) li,
:lang(ko) .tag{
  word-break:keep-all;
  overflow-wrap:anywhere;
}

:lang(ja) .hero-h1,
:lang(ja) .sect-title,
:lang(ja) .split-title,
:lang(ja) .page-hero h1,
:lang(ja) p,
:lang(ja) li{
  line-break:strict;
}

/* The eyebrow tracks at .18em and uppercases because it is a Latin small-label
   convention. Neither survives contact with CJK: uppercase does nothing to
   kana or hangul, so the only thing it transforms is an embedded product name,
   turning "Shorts" into "SHORTS" one line above a nav that says Shorts. The
   tracking, with nothing to letter-space but CJK, just pulls the characters
   apart into something that reads as emphasis. */
:lang(ja) .eyebrow,
:lang(ko) .eyebrow{ letter-spacing:.02em; text-transform:none; }
