/* ==========================================================================
   EITRI — Design System  ·  "Reel House"
   Premium human video editing. Mobile-first / iOS-first.

   AESTHETIC: film-magazine editorial. Warm carbon base with a brown
   undertone (not blue-black), cream paper as the highest-contrast surface,
   vermillion as the single production accent. Display is a high-contrast
   serif set at poster scale; everything technical is monospaced small caps.
   Corners are near-square, fills are rare, hairline rules do the work.
   Depth comes from grain and halation, never from blurred gradient orbs.
   ========================================================================== */

/* --------------------------------------------------------- 1. Tokens ---- */
:root {
  /* Surfaces — warm carbon. Every one carries a red/yellow bias so the
     page never reads as the default blue-black SaaS dark theme. */
  --ink:        #0C0A09;
  --ink-2:      #12100D;
  --surface:    #191512;
  --surface-2:  #201B16;
  --surface-3:  #29231C;

  /* Paper — the cream the whole system is printed with. */
  --paper:      #F4EEE3;
  --paper-2:    #E5D9C6;

  /* Lines. --line/-2/-3 are DECORATIVE hairlines.
     --line-ui carries the boundary of an actual control and must hold 3:1. */
  --line:       rgba(244,238,227,.09);
  --line-2:     rgba(244,238,227,.16);
  --line-3:     rgba(244,238,227,.26);
  --line-ui:    rgba(244,238,227,.38);   /* 3.2:1 on --ink */

  /* Brand — vermillion. Film-poster orange, deeper and less neon than the
     old #FF6B2B, which glowed against a warm base instead of sitting on it. */
  --brand:      #E4562A;
  --brand-lift: #F4744A;
  --brand-dim:  rgba(228,86,42,.14);
  --brand-line: rgba(228,86,42,.36);

  /* Conversion — paper on carbon is the highest contrast pairing available,
     so the primary action needs no colour of its own. Lime is gone: an
     acid green had nothing to do with the rest of the system. */
  --cta:        #F4EEE3;
  --cta-lift:   #FFFFFF;
  --cta-dim:    rgba(244,238,227,.10);
  --cta-line:   rgba(244,238,227,.40);
  --cta-ink:    #100D0B;

  /* Editing levels — a film-stock ramp, cool grade to warm gold.
     Deliberately not green/amber/red (reads as severity) and deliberately
     not --brand, so vermillion keeps meaning EITRI rather than "Pro Max". */
  --lvl-1: #6E8B84;   /* Cut & Clean · slate teal */
  --lvl-2: #B9A16B;   /* Pro         · brass      */
  --lvl-3: #C4695A;   /* Pro Max     · clay       */
  --lvl-4: #E9C46A;   /* Cinematic   · gold       */

  /* Atmosphere — warm halation only. */
  --halo:       #B4441F;
  --halo-2:     #7A5A2E;

  /* Text. Every one of these carries real text somewhere, so every one
     must clear 4.5:1 on --ink. Warm white, never #FFF — pure white on a
     warm base is the one thing that makes the whole page look cold. */
  --t-1: #F7F2E9;
  --t-2: rgba(247,242,233,.76);   /* 10.6:1 */
  --t-3: rgba(247,242,233,.56);   /*  5.9:1 */
  /* Read that again: --t-4 is BRIGHTER than --t-3. This is not a typo and
     not a ramp. --t-3 carries secondary paragraphs at 16–17px; --t-4 carries
     10–11px uppercase mono at .14em+ tracking, and small letterforms with
     that much air between them need more luminance to hold the same
     perceived weight. Measured contrast goes up, apparent emphasis stays
     down. The names are positional, so pick by ROLE — body-secondary vs
     micro-label — not by number. */
  --t-4: rgba(247,242,233,.62);   /*  7.1:1 */

  /* Type — a cinematic display serif over a grotesque with real width,
     with mono carrying every technical label. No Inter anywhere. */
  --display: "Instrument Serif", "Display Fallback", Georgia, "Times New Roman", serif;
  --sans:    "Instrument Sans", "Sans Fallback", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Fluid scale — display runs bigger and tighter than before because a
     serif at poster scale is the whole point of the layout. */
  --fs-display: clamp(3.1rem, 1.4rem + 7.6vw, 7.5rem);
  --fs-h1:      clamp(2.6rem, 1.5rem + 5vw, 5rem);
  --fs-h2:      clamp(2.1rem, 1.4rem + 3.2vw, 3.9rem);
  --fs-h3:      clamp(1.3rem, 1.08rem + 1vw, 1.75rem);
  --fs-h4:      clamp(1.2rem, 1.08rem + 0.6vw, 1.45rem);
  --fs-body-lg: clamp(1.0625rem, 1rem + 0.5vw, 1.25rem);
  --fs-body:    clamp(1rem, .96rem + .2vw, 1.0625rem);
  --fs-sm:      clamp(.875rem, .85rem + .15vw, .9375rem);
  --fs-xs:      .75rem;
  --fs-mono:    .6875rem;
  --fs-micro:   .625rem;

  /* Spacing steps */
  --sp-1: .5rem;
  --sp-2: clamp(.75rem, .7rem + .25vw, 1rem);
  --sp-3: clamp(1.1rem, .9rem + .8vw, 1.75rem);
  --sp-4: clamp(1.75rem, 1.4rem + 1.6vw, 2.75rem);

  /* Rhythm */
  --gut:   clamp(1.25rem, .85rem + 1.9vw, 2.5rem);
  --sect:  clamp(4.5rem, 3rem + 7vw, 9.5rem);
  --maxw:  1280px;
  --slug:  clamp(120px, 13vw, 178px);   /* the editorial margin column */
  --stick: 92px;                        /* clearance under the fixed header */

  /* Radii — near-square. Print doesn't have a 24px corner radius. */
  --r-sm: 2px;
  --r:    3px;
  --r-lg: 3px;
  --r-xl: 4px;

  /* Motion */
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
}

/* ------------------------------------------- 1b. Metric-matched fallback -
   Sized so the pre-swap render occupies the same space as the webfont.
   Without these the font swap re-wrapped every headline and shifted layout,
   and a display serif swapping in at 7rem shifts a LOT. */
@font-face {
  font-family: "Sans Fallback";
  src: local("Segoe UI"), local("Roboto"), local("Helvetica Neue"), local("Arial");
  size-adjust: 101%;
  ascent-override: 92%;
  descent-override: 23%;
  line-gap-override: 0%;
  font-display: swap;
}
@font-face {
  font-family: "Display Fallback";
  src: local("Georgia"), local("Times New Roman"), local("Times");
  size-adjust: 94%;
  ascent-override: 88%;
  descent-override: 21%;
  line-gap-override: 0%;
  font-display: swap;
}

/* ----------------------------------------------------- 2. Reset/base ---- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--t-1);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100%;
}

/* H1 and H2 are the display voice: serif, near-solid leading, optically
   tightened. H3/H4 stay in the grotesque — a serif at 1.3rem in a card
   would read as a typo, not a decision. */
h1, h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  text-wrap: balance;
  color: var(--t-1);
}
h3, h4 {
  margin: 0;
  font-family: var(--sans);
  font-weight: 600;
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); line-height: .96; letter-spacing: -.024em; }
h2 { font-size: var(--fs-h2); line-height: 1.0;  letter-spacing: -.02em; }
h3 { font-size: var(--fs-h3); line-height: 1.24; letter-spacing: -.014em; }
h4 { font-size: var(--fs-h4); line-height: 1.32; letter-spacing: -.008em; }
@media (max-width: 600px) { h1, h2 { line-height: 1.03; } }

/* Serif italic is the accent voice — used for the pull-out phrase in a
   headline instead of reaching for another colour. */
h1 em, h2 em, .em { font-style: italic; color: var(--brand); }

p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
table { border-collapse: collapse; width: 100%; }

::selection { background: var(--brand); color: var(--paper); }

/* Focus — always visible, never removed. Vermillion reads on both the
   carbon page and the cream buttons; cream-on-cream did not. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 1px;
}

:target, [id] { scroll-margin-top: var(--stick); }

.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;
}

.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 200;
  transform: translateY(-160%);
  background: var(--cta); color: var(--cta-ink);
  padding: 12px 18px; border-radius: var(--r-sm);
  font-weight: 640; font-size: var(--fs-sm);
  transition: transform .2s var(--ease);
}
.skip-link:focus { transform: translateY(0); }

/* ------------------------------------------------------- 3. Layout ------ */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
  /* Every page sets `viewport-fit=cover`, which is what lets the carbon base
     run under the status bar and the home indicator instead of stopping at a
     white band. The cost is that in LANDSCAPE on a notched iPhone the layout
     viewport also extends under the sensor housing — about 59px of it — while
     this gutter only reaches ~30px at that width. The first characters of
     every line were sitting behind the notch. Taking whichever is larger
     fixes landscape without moving portrait, where both insets are 0.
     Declared second so a browser without env() simply keeps the line above. */
  padding-inline:
    max(var(--gut), env(safe-area-inset-left))
    max(var(--gut), env(safe-area-inset-right));
}
.wrap-narrow { max-width: 880px; }

.section { padding-block: var(--sect); position: relative; }
.section + .section { border-top: 1px solid var(--line); }

/* ---- The editorial masthead ----------------------------------------------
   A magazine doesn't stack a label, a headline and a paragraph down the
   centre of the page five times in a row. It runs the section slug in the
   margin and lets the body hold the measure. Above 1000px every
   `.section > .wrap` becomes that two-column spread, and the slug pins
   itself while its section scrolls past — so the reader always knows which
   chapter they're in. Everything else falls into the content column
   untouched, which is why the other six pages inherit this for free.

   The `:has()` gate matters: a section only becomes a spread if it actually
   owns a slug. Sections whose eyebrow is nested deeper (the journey block)
   or that have none at all (the closing plate) would otherwise be indented
   past an empty column and read as a layout bug. Where `:has()` is
   unsupported the grid simply never applies and the page falls back to the
   plain stack — no broken state. */
@media (min-width: 1000px) {
  .section > .wrap:has(> .eyebrow) {
    display: grid;
    grid-template-columns: var(--slug) minmax(0, 1fr);
    column-gap: clamp(2rem, 4.4vw, 5rem);
    align-items: start;
  }
  .section > .wrap:has(> .eyebrow) > * { grid-column: 2; min-width: 0; }
  .section > .wrap:has(> .eyebrow) > .eyebrow {
    grid-column: 1;
    grid-row: 1 / 200;
    position: sticky;
    top: calc(var(--stick) + 16px);
    margin: 0;
    align-self: start;
  }
  /* Narrow sections keep the slug but pull the measure in. */
  .wrap-narrow.wrap:has(> .eyebrow) { grid-template-columns: var(--slug) minmax(0, 640px); }
}

/* ---- Section slug --------------------------------------------------------
   Was a dot plus a caption. Now it's a printed marginal note: a rule that
   runs down the left edge, the label stacked beneath it in mono small caps,
   set vertically on desktop where it has a whole column to live in. */
.eyebrow {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  font-weight: 500;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--t-4);
  margin: 0 0 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.eyebrow .dot {
  display: block;
  width: 26px; height: 1px;
  border-radius: 0;
  background: var(--brand);
  flex-shrink: 0;
}
/* Only the eyebrow that actually lives in the margin column turns vertical.
   Eyebrows used as inline card labels (pricing steps, the sample how-to
   cards, the 404) must stay on one line or they wreck those cards. */
@media (min-width: 1000px) {
  .section > .wrap:has(> .eyebrow) > .eyebrow {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding-top: .55em;
    line-height: 1.5;
  }
  .section > .wrap:has(> .eyebrow) > .eyebrow .dot { width: 42px; }
}

.lede {
  font-size: var(--fs-body-lg);
  line-height: 1.6;
  color: var(--t-3);
  max-width: 54ch;
}

.grid { display: grid; gap: clamp(1rem, .6rem + 1.6vw, 1.75rem); }
@media (min-width: 720px) {
  .g-2 { grid-template-columns: repeat(2, 1fr); }
  .g-3 { grid-template-columns: repeat(3, 1fr); }
  .g-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) {
  .g-4 { grid-template-columns: repeat(4, 1fr); }
}

/* ------------------------------------------------- 4. Atmosphere --------
   The three drifting blurred circles are gone. They were the single most
   generic thing on the page and they cost three animated 72px-blur layers
   to produce. What replaces them is film: a static grain plate over the
   whole document, a vignette that closes the corners, and one warm
   halation bloom behind the hero. Cheaper and specific to the product. */

/* Grain — feTurbulence baked to a data URI so it costs one paint, never a
   filter. 180px tile, so the repeat is invisible at any viewport. */
body::before {
  content: "";
  /* inset: 0, not -50%. This plate is fixed and carries no transform, so it
     never needs to reach past the viewport — at -50% it was four times the
     screen area, and every one of those pixels was re-blended through
     `mix-blend-mode: overlay` on each scroll frame. On a phone that made it
     the most expensive declaration in the file. Identical look, a quarter of
     the compositing work. */
  position: fixed; inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: .30;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}
/* Vignette — the corners of a projected frame fall off. */
body::after {
  content: "";
  position: fixed; inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(130% 100% at 50% 42%, transparent 46%, rgba(0,0,0,.42) 100%);
}
/* Everything real sits above both plates. */
header, main, footer, .dock, .skip-link { position: relative; z-index: 2; }

.atmos {
  position: absolute; inset: 0;
  overflow: hidden; pointer-events: none; z-index: 0;
}
.atmos i {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(90px);
  will-change: transform;
}
/* One warm bloom top-left, one dim brass counterweight low-right. Both sit
   under 12% so they read as light leak on stock, not as a "hero gradient". */
.atmos .a {
  width: 58vw; height: 42vw; max-width: 760px; max-height: 520px;
  background: var(--halo); left: -14vw; top: -12vw; opacity: .11;
  animation: drift-a 34s var(--ease) infinite;
}
.atmos .b {
  width: 44vw; height: 34vw; max-width: 560px; max-height: 420px;
  background: var(--halo-2); right: -12vw; bottom: -14vw; opacity: .09;
  animation: drift-b 44s var(--ease) infinite;
}
.atmos .c { display: none; }   /* the third orb had no job */

@keyframes drift-a { 0%,100% { transform: translate3d(0,0,0) scale(1); } 50% { transform: translate3d(5vw,3vh,0) scale(1.1); } }
@keyframes drift-b { 0%,100% { transform: translate3d(0,0,0) scale(1); } 50% { transform: translate3d(-5vw,-4vh,0) scale(1.07); } }

/* The printed column grid. Fewer, firmer lines than the old 8-up wash —
   a visible 4-column measure with a vermillion rule marking the gutter the
   headline hangs off, so the page announces it was set, not centred. */
.ruled {
  /* Inset to the same measure as .wrap rather than to the viewport, so the
     vermillion rule lands on the actual slug gutter the headline hangs off.
     Pinned to the viewport it drifted into empty margin above ~1600px. */
  position: absolute; top: 0; bottom: 0; z-index: 0; pointer-events: none;
  left:  max(var(--gut), calc((100% - var(--maxw)) / 2 + var(--gut)));
  right: max(var(--gut), calc((100% - var(--maxw)) / 2 + var(--gut)));
  background-image:
    linear-gradient(90deg, var(--brand-line), var(--brand-line)),
    linear-gradient(90deg, rgba(244,238,227,.05) 1px, transparent 1px);
  /* The accent layer is a literal 1px-wide image, NOT a 100%-wide gradient
     with a 1px stop. A percentage background-position resolves against
     (area width − image width), so at 100% width that difference is zero and
     any percentage collapses to 0. Sized to 1px, 58% means 58%. */
  background-size: 1px 100%, 25% 100%;
  background-repeat: no-repeat, repeat;
  /* 58% is the .hero-grid column split (1.16fr / .84fr), so the rule lands in
     the gutter between the copy and the timeline rather than running through
     the headline, which is where --slug was putting it. */
  background-position: 58% 0, 0 0;
  mask-image: linear-gradient(180deg, transparent, #000 14%, #000 82%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 14%, #000 82%, transparent);
  opacity: .8;
}
/* Below the spread breakpoint there is no two-column split to mark, so the
   accent rule is dropped and only the measure rules remain. */
@media (max-width: 999px) {
  .ruled {
    background-image: linear-gradient(90deg, rgba(244,238,227,.05) 1px, transparent 1px);
    background-size: 33.333% 100%;
    background-repeat: repeat;
  }
}

/* --------------------------------------------------- 5. Buttons ---------
   Square, mono, letterspaced small caps. A pill button in a system built
   on hairline rules and a display serif was borrowed from a different
   website. This one reads as a stamp on a call sheet. */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 10px;
  min-height: 54px;
  padding: 0 28px;
  border-radius: var(--r-sm);
  font-family: var(--mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: center;
  overflow: hidden;
  transition: background .25s var(--ease), border-color .25s var(--ease),
              transform .18s var(--ease), color .25s var(--ease);
}
.btn:active { transform: translateY(1px); }

/* PAPER = conversion. The brightest surface on the page is reserved for
   the one action we want, so it needs no colour to out-rank everything. */
.btn-cta {
  background: var(--cta);
  color: var(--cta-ink);
  border: 1px solid var(--cta);
  box-shadow: 0 1px 0 rgba(0,0,0,.4), 0 14px 40px rgba(0,0,0,.45);
}
.btn-cta:hover { background: var(--cta-lift); border-color: var(--cta-lift); }

/* Vermillion wipes up from the baseline on hover — the accent arrives as
   a colour grade being applied, which is the thing we actually sell. */
.btn-cta::before {
  content: ""; position: absolute; inset: auto 0 0 0; height: 0;
  background: var(--brand);
  transition: height .32s var(--ease-out);
  /* Negative, not 0. A z-index:0 positioned pseudo paints ABOVE the parent's
     own inline text, so the wipe was erasing every label that wasn't wrapped
     in a span. At -1 it paints after the button's background but before its
     text, which is exactly the layer a colour grade belongs on. `isolation`
     keeps it from escaping behind the page. */
  z-index: -1;
}
.btn-cta:hover::before { height: 100%; }
/* The label deliberately stays near-black through the wipe. Cream on
   vermillion is only 3.2:1 and this is 12px mono, so it would fail; carbon
   on vermillion is 5.2:1 and passes. The grade still reads. */
.btn-cta:hover { color: var(--cta-ink); }
.btn-cta { position: relative; isolation: isolate; }
.btn-cta > * { position: relative; }

.btn-ghost {
  border: 1px solid var(--line-ui);
  color: var(--t-2);
  background: transparent;
}
.btn-ghost:hover { border-color: var(--brand); color: var(--t-1); background: var(--brand-dim); }

.btn-sm { min-height: 46px; padding: 0 18px; font-size: var(--fs-micro); letter-spacing: .14em; }
.btn-block { width: 100%; }

.btn .arw { transition: transform .25s var(--ease); position: relative; z-index: 1; }
.btn:hover .arw { transform: translateX(4px); }

/* --------------------------------------------------- 6. Surfaces --------
   A card is a plate in a magazine: hairline frame, near-square corner, and
   a rule that inks in along the top edge when you reach for it. The fill
   barely lifts off the page, so the border does the describing. */
.card {
  background: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.35rem, 1rem + 1.3vw, 2.1rem);
  position: relative;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.card::before {
  content: ""; position: absolute; top: -1px; left: -1px; height: 2px; width: 0;
  background: var(--brand);
  transition: width .45s var(--ease-out);
}
.card:hover { border-color: var(--line-2); background: var(--surface); }
.card:hover::before { width: calc(100% + 2px); }

.card-quiet { background: rgba(244,238,227,.022); }

.chip {
  display: inline-flex; align-items: center; gap: 9px;
  min-height: 30px; padding: 0 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--brand-line);
  background: var(--brand-dim);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--t-2);
}
.chip .pip {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--brand);
  animation: pip 2s var(--ease) infinite;
}
@keyframes pip { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.7); } }

/* --------------------------------------------------- 7. Header ---------- */
.hdr {
  position: sticky; top: 0; z-index: 100;
  background: rgba(12,10,9,.82);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
  border-bottom: 1px solid var(--line-2);
}
.hdr-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  min-height: 64px;
}
.lockup { display: inline-flex; align-items: center; gap: 11px; min-height: 44px; }
/* The wordmark is the display serif, wide-tracked — a masthead, not a logo
   in the body font like every other site's header. */
.lockup .wordmark {
  font-family: var(--display);
  font-size: 1.5rem; font-weight: 400;
  letter-spacing: .26em;
  padding-left: .1em;
  line-height: 1;
}
.hdr nav { display: none; }
@media (min-width: 900px) {
  .hdr-in { min-height: 76px; }
  .hdr nav { display: flex; align-items: center; gap: 34px; }
  .hdr nav a {
    position: relative;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: .18em; text-transform: uppercase;
    color: var(--t-4);
    min-height: 44px; display: inline-flex; align-items: center;
    transition: color .2s var(--ease);
  }
  /* Underline draws from the left, like a rule being ruled. */
  .hdr nav a::after {
    content: ""; position: absolute; left: 0; bottom: 22px;
    height: 1px; width: 0; background: var(--brand);
    transition: width .3s var(--ease-out);
  }
  .hdr nav a:hover, .hdr nav a[aria-current="page"] { color: var(--t-1); }
  .hdr nav a:hover::after, .hdr nav a[aria-current="page"]::after { width: 100%; }
}
.hdr .btn { flex-shrink: 0; white-space: nowrap; }

/* Header CTA label shortens instead of pushing the bar past the viewport */
.cta-long { display: inline; }
.cta-short { display: none; }
@media (max-width: 560px) {
  .cta-long { display: none; }
  .cta-short { display: inline; }
  .hdr .btn { padding: 0 14px; font-size: var(--fs-micro); }
  .lockup .wordmark { font-size: 1.2rem; letter-spacing: .18em; }
  .lockup { gap: 8px; }
  .mark { width: 28px; height: 28px; }
}
@media (max-width: 360px) {
  .lockup .wordmark { display: none; }
}

/* Grid/flex children must be allowed to shrink below their content width,
   otherwise long unbroken strings blow the layout out horizontally. */
.wrap, .grid > *, .levels > *, .steps > *, .trust > *,
.opts > *, .calc-grid > *, .hero-grid > *, .jrn > *,
.ftr-grid > *, .stage-meta > *, .rawex-out > * { min-width: 0; }

/* Long pasted URLs in inputs and copy must never widen the page */
.field input, .field textarea { overflow-wrap: break-word; }
.legal a, .form-note a { overflow-wrap: anywhere; }

/* ------------------------------------------------- 8. Logo mark --------- */
.mark { width: 32px; height: 32px; flex-shrink: 0; }
.mark .spine { fill: var(--paper); }
.mark .clip  { fill: rgba(244,238,227,.82); }
.mark .clip-sel { fill: var(--brand); }
.mark .tick  { fill: rgba(244,238,227,.30); }

/* ------------------------------------------------- 9. Reveal ------------ */
.rv {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
  will-change: opacity, transform;
}
.rv.in { opacity: 1; transform: none; will-change: auto; }
.rv-1 { transition-delay: .06s; }
.rv-2 { transition-delay: .12s; }
.rv-3 { transition-delay: .18s; }
.rv-4 { transition-delay: .24s; }

/* --------------------------------------------- 10. Timeline visual ------ */
.stage {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background:
    radial-gradient(120% 100% at 20% 0%, rgba(185,161,107,.13), transparent 60%),
    radial-gradient(90% 90% at 92% 100%, rgba(228,86,42,.11), transparent 62%),
    var(--ink-2);
  overflow: hidden;
}
.stage-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--t-4);
}
.stage-body { padding: clamp(1rem, .8rem + 1vw, 1.5rem); }

.track { display: grid; gap: 9px; }
.track-row {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: 10px;
  align-items: center;
}
.track-lbl {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  color: var(--t-4);
  text-transform: uppercase;
}
.track-lane {
  position: relative;
  height: 28px;
  border-radius: 8px;
  background: rgba(244,238,227,.035);
  overflow: hidden;
}
.clip-block {
  position: absolute; top: 0; bottom: 0;
  border-radius: 7px;
  background: rgba(244,238,227,.16);
  box-shadow: inset 0 1px 0 rgba(244,238,227,.18);
  transition: left .8s var(--ease-out), width .8s var(--ease-out),
              background .5s var(--ease), opacity .5s var(--ease);
}
.clip-block.sel { background: var(--brand); }
.clip-block.v   { background: rgba(185,161,107,.72); }
.clip-block.c   { background: rgba(110,139,132,.55); }

.playhead {
  position: absolute; top: 0; bottom: 0; width: 2px;
  background: var(--paper);
  box-shadow: 0 0 14px rgba(244,238,227,.6);
  z-index: 3;
  pointer-events: none;
}
.playhead::before {
  content: ""; position: absolute; top: -5px; left: 50%;
  transform: translateX(-50%);
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 7px solid var(--paper);
}

/* Waveform */
.wave { display: flex; align-items: flex-end; gap: 3px; height: 34px; }
.wave i {
  flex: 1; display: block;
  border-radius: 2px;
  height: 100%;
  transform-origin: bottom;
  background: linear-gradient(to top, rgba(244,238,227,.12), rgba(244,238,227,.5));
  animation: wv 1.6s var(--ease) infinite;
}
/* scaleY is composited; animating height relayouts 20 nodes every frame */
@keyframes wv { 0%,100% { transform: scaleY(.22); } 50% { transform: scaleY(1); } }

/* Caption block */
.capline {
  display: inline-block;
  padding: 5px 11px;
  border-radius: 7px;
  background: rgba(0,0,0,.62);
  border: 1px solid var(--line-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: -.01em;
}

/* Grade bars */
.grade { display: grid; gap: 7px; }
.grade-row { display: grid; grid-template-columns: 62px 1fr 34px; gap: 9px; align-items: center; }
.grade-row span { font-family: var(--mono); font-size: var(--fs-micro); letter-spacing: .1em; color: var(--t-4); text-transform: uppercase; }
.grade-track { height: 4px; border-radius: 3px; background: rgba(244,238,227,.09); position: relative; }
.grade-fill {
  position: absolute; inset: 0 auto 0 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--lvl-2), var(--brand));
  transition: width .9s var(--ease-out);
}
.grade-val { font-family: var(--mono); font-size: var(--fs-micro); color: var(--t-3); text-align: right; }

/* ---------------------------------------------- 12. Forms --------------- */
.field { display: grid; gap: 8px; margin-bottom: 20px; }
.field > label {
  font-size: var(--fs-sm);
  font-weight: 560;
  color: var(--t-2);
}
.field .hint { font-size: var(--fs-xs); color: var(--t-4); line-height: 1.5; }

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 52px;
  padding: 14px 16px;
  font-family: inherit;
  font-size: 16px;              /* 16px prevents iOS zoom-on-focus */
  color: var(--t-1);
  background: rgba(244,238,227,.035);
  border: 1px solid var(--line-ui);
  border-radius: var(--r-sm);
  transition: border-color .2s var(--ease), background .2s var(--ease);
  -webkit-appearance: none;
  appearance: none;
}
.field textarea { min-height: 112px; resize: vertical; line-height: 1.55; }
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='rgba(244,238,227,.5)' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 42px;
}
.field input::placeholder, .field textarea::placeholder { color: var(--t-4); }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--brand);
  background: rgba(244,238,227,.055);
  outline: none;
}
/* One focus colour site-wide. This used to be --cta, which is now cream and
   would be near-invisible sitting next to the cream buttons. */
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px;
}

.field .err {
  display: flex;
  align-items: center; gap: 6px;
  font-size: var(--fs-xs);
  color: #FF9C8A;
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .2s var(--ease), opacity .18s var(--ease);
}
.field.invalid .err { max-height: 4em; opacity: 1; }
.field.invalid input, .field.invalid select, .field.invalid textarea {
  /* Opaque, not .55 alpha — a control boundary has to clear 3:1 and the
     translucent version sat at 2.9:1 against the field surface. */
  border-color: #FF9C8A;
}
/* Error state is never colour-only — the ⚠ glyph and text carry it */
.field .err::before { content: "\26A0"; font-size: .9em; }

.form-note {
  font-size: var(--fs-xs);
  color: var(--t-4);
  line-height: 1.6;
  margin-top: 14px;
}

.form-ok {
  display: none;
  text-align: center;
  padding: clamp(1.5rem, 1rem + 3vw, 3rem) 1rem;
}
.form-ok.show { display: block; }
.form-ok .tick {
  width: 62px; height: 62px; margin: 0 auto 20px;
  border-radius: 50%;
  background: var(--brand-dim);
  border: 1px solid var(--brand-line);
  display: grid; place-items: center;
}

/* ---------------------------------------------- 13. Tables -------------- */
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--r); }
.tbl-scroll:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.tbl {
  min-width: 660px;
  font-size: var(--fs-sm);
}
.tbl th, .tbl td {
  padding: 14px 16px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.tbl thead th {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--t-4);
  font-weight: 400;
  position: sticky; top: 0;
  background: var(--ink-2);
}
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tbody tr:hover { background: rgba(244,238,227,.022); }
.tbl .dur { color: var(--t-2); font-weight: 560; }
.tbl .inc { font-family: var(--mono); color: var(--t-3); font-size: var(--fs-xs); }
.tbl .price { font-weight: 620; color: var(--t-1); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------- 14. Footer -------------- */
.ftr {
  border-top: 1px solid var(--line-2);
  padding-block: clamp(3rem, 2rem + 4vw, 5rem);
  position: relative;
}
.ftr-rail {
  position: absolute; top: -1px; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--brand) 18%, var(--brand) 82%, transparent);
  opacity: .5;
}
.ftr-grid { display: grid; gap: 34px; }
@media (min-width: 780px) { .ftr-grid { grid-template-columns: 1.5fr 1fr 1fr; gap: 56px; } }
.ftr h3, .ftr h4 {
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--t-4); font-weight: 500; margin-bottom: 10px;
}
.ftr li a {
  display: inline-flex; align-items: center;
  /* 44, not 42. Apple's minimum is 44pt and this was the only control on the
     site under it — in the one place it matters most, a stacked column of
     links where the next target is directly under your thumb. */
  min-height: 44px;
  font-size: var(--fs-sm); color: var(--t-3);
  transition: color .2s var(--ease), padding-left .25s var(--ease);
}
.ftr li a:hover { color: var(--t-1); padding-left: 6px; }
.ftr-base {
  margin-top: 42px; padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 12px;
  justify-content: space-between; align-items: center;
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .2em; text-transform: uppercase; color: var(--t-4);
}

/* ---------------------------------------------- 15. Utilities ----------- */
.mono { font-family: var(--mono); }
.tnum { font-variant-numeric: tabular-nums; }
.t2 { color: var(--t-2); } .t3 { color: var(--t-3); } .t4 { color: var(--t-4); }
.brand { color: var(--brand); }
.mt-s { margin-top: var(--sp-2); }  .mt-m { margin-top: var(--sp-3); }
.mt-l { margin-top: var(--sp-4); }  .mt-xl { margin-top: clamp(2.5rem,2rem+3vw,4rem); }
.center { text-align: center; }
.row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---------------------------------------------- 16. Mobile menu --------- */
.menu-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-right: -6px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-ui);
  color: var(--t-2);
}
@media (min-width: 900px) { .menu-btn { display: none; } }
.menu-btn span {
  position: relative; display: block; width: 17px; height: 1.5px;
  background: currentColor; border-radius: 2px;
  transition: transform .25s var(--ease), opacity .2s var(--ease);
}
.menu-btn span::before, .menu-btn span::after {
  content: ""; position: absolute; left: 0; width: 17px; height: 1.5px;
  background: currentColor; border-radius: 2px;
  transition: transform .25s var(--ease);
}
.menu-btn span::before { top: -6px; }
.menu-btn span::after  { top: 6px; }
.menu-btn[aria-expanded="true"] span { background: transparent; }
.menu-btn[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span::after  { transform: translateY(-6px) rotate(-45deg); }

.menu-panel {
  display: none;
  border-top: 1px solid var(--line);
  background: var(--ink-2);
  padding: 10px var(--gut) 22px;
}
.menu-panel.open { display: block; }
@media (min-width: 900px) { .menu-panel { display: none !important; } }
.menu-panel a {
  display: flex; align-items: center;
  min-height: 52px;
  font-size: 1.0625rem; font-weight: 560;
  color: var(--t-2);
  border-bottom: 1px solid var(--line);
}
.menu-panel a:last-of-type { border-bottom: 0; }
.menu-panel a[aria-current="page"] { color: var(--brand); }

/* ---------------------------------------------- 17. Hero ----------------
   Asymmetric on purpose. The headline column is wider than the stage and
   the stage is pushed down and allowed to run past the right edge of the
   measure, so the spread has a diagonal instead of two balanced halves. */
.hero {
  padding-block: clamp(3.5rem, 2rem + 7vw, 8rem) clamp(4rem, 2.5rem + 7vw, 8rem);
  position: relative;
  overflow: hidden;
}
.hero-grid { display: grid; gap: clamp(2.5rem, 1.5rem + 4vw, 4rem); align-items: center; }
@media (min-width: 1000px) {
  .hero-grid { grid-template-columns: 1.16fr .84fr; align-items: start; }
  /* The stage sits a beat below the headline's baseline and breaks the
     right margin — the single grid-breaking move on the page. */
  .hero-grid > *:last-child { margin-top: 5.5rem; margin-right: calc(var(--gut) * -1.6); }
}
@media (min-width: 1400px) {
  .hero-grid > *:last-child { margin-right: -7vw; }
}

.hero h1 {
  font-size: var(--fs-display);
  margin-top: 26px;
  line-height: .92;
  letter-spacing: -.028em;
}
/* Italic serif carries the emphasis. Colour is the reinforcement, not the
   mechanism, so the phrase still reads as emphasised in greyscale. */
.hero h1 .swap {
  font-style: italic;
  color: var(--brand);
  letter-spacing: -.012em;
}
.hero .lede { margin-top: 26px; max-width: 44ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }
@media (max-width: 420px) { .hero-actions .btn { width: 100%; } }

/* Trust marks run as a printed credit strip with rules between, not dots. */
.trustline {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px;
  margin-top: 34px; padding-top: 20px;
  border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .2em; text-transform: uppercase; color: var(--t-4);
}
.trustline i { width: 12px; height: 1px; border-radius: 0; background: var(--line-3); }

/* Hero stage phase pills */
.phases { display: flex; gap: 6px; }
.phases button {
  flex: 1; min-height: 44px; padding: 0 6px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: rgba(244,238,227,.03);
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--t-4);
  transition: color .25s var(--ease), border-color .25s var(--ease), background .25s var(--ease);
}
.phases button[aria-selected="true"] {
  color: var(--t-1);
  border-color: var(--brand-line);
  background: var(--brand-dim);
}

.stage-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 8px;
  margin-top: 14px;
}
.stage-meta div {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 11px; background: rgba(244,238,227,.022);
}
.stage-meta dt { font-family: var(--mono); font-size: var(--fs-micro); letter-spacing: .12em; text-transform: uppercase; color: var(--t-4); }
.stage-meta dd { margin: 4px 0 0; font-size: var(--fs-sm); font-weight: 620; }

/* ---------------------------------------------- 18. Steps ---------------
   Four boxes in a row is the layout every service page uses. This is a
   contents list instead: rules between entries, an oversized serif numeral
   hanging in the margin, and no card chrome at all. */
.steps { display: grid; gap: 0; position: relative; border-top: 1px solid var(--line-2); }

/* Undo the .card treatment these <li>s inherit from the markup. */
.steps .card.step {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: clamp(1.5rem, 1rem + 2vw, 2.4rem) 0;
}
.steps .card.step::before { display: none; }

.step {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "num  head"
    "num  body";
  column-gap: clamp(1.1rem, 3vw, 2.4rem);
  align-items: start;
  transition: background .3s var(--ease);
}
.step:hover { background: rgba(244,238,227,.022); }

/* The numeral is the display serif at heading scale — the thing your eye
   lands on first, and the reason the row needs no border or fill. */
.step .num {
  grid-area: num;
  font-family: var(--display);
  font-size: clamp(2.6rem, 1.6rem + 3.4vw, 4.6rem);
  font-weight: 400;
  line-height: .82;
  letter-spacing: -.03em;
  /* These numerals are real text, not decoration, so they clear the 3:1
     large-text floor (this is ~3.6:1) rather than sitting at hairline
     opacity like the rules around them. */
  color: rgba(247,242,233,.40);
  transition: color .35s var(--ease);
  min-width: 1.6em;
}
.step:hover .num { color: var(--brand); }

.step h3 { grid-area: head; font-size: var(--fs-h3); align-self: center; }
.step p {
  grid-area: body;
  margin-top: 10px;
  font-size: var(--fs-body);
  color: var(--t-3);
  line-height: 1.65;
  max-width: 62ch;
}
/* The icon moves to the far right as a quiet marginal glyph. */
.step .icon {
  /* Offset by the row's own top padding so the glyph sits on the heading's
     optical line rather than floating up against the hairline above it. */
  position: absolute; top: clamp(1.5rem, 1rem + 2vw, 2.4rem); right: 0;
  width: 40px; height: 40px; border-radius: 0;
  border: 0;
  background: none;
  display: none;
  place-items: center;
  opacity: .5;
  margin-bottom: 0;
}
@media (min-width: 780px) { .step .icon { display: grid; } }

/* Film leader above the list — a perforated strip with a light pass
   travelling it, marking the four stations the footage moves through. */
.rail { position: relative; height: 30px; margin: 4px 0 10px; }
.rail-track {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--line-2); overflow: hidden;
}
.rail-track::after {
  content: ""; position: absolute; top: -1px; left: -22%;
  width: 22%; height: 3px;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
  animation: rail 4.2s linear infinite;
}
@keyframes rail { to { left: 100%; } }
.rail-node {
  position: absolute; top: 50%; transform: translate(-50%,-50%);
  width: 7px; height: 7px; border-radius: 0;
  background: var(--ink); border: 1px solid var(--line-3);
  transition: background .4s var(--ease), border-color .4s var(--ease);
}
.rail-node.on { border-color: var(--brand); background: var(--brand); }

/* ---------------------------------------------- 19. Level cards ---------
   Four columns of a spec sheet, divided by shared hairlines instead of
   four floating boxes with gaps. Each column carries its own accent via
   --lc, so the level colour propagates to the rule, the key and the meter
   without four sets of duplicated rules. */
.levels {
  display: grid; gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line-2);
}
/* The 4-up breakpoint is pushed well past 1080px because the slug column
   now eats ~174px of the wrap: at 1080 each level would only get ~206px,
   which the serif headings and tracked-out mono buttons cannot hold. */
@media (min-width: 700px)  { .levels { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1280px) { .levels { grid-template-columns: repeat(4, 1fr); } }

.lvl:nth-child(1) { --lc: var(--lvl-1); }
.lvl:nth-child(2) { --lc: var(--lvl-2); }
.lvl:nth-child(3) { --lc: var(--lvl-3); }
.lvl:nth-child(4) { --lc: var(--lvl-4); }

.card.lvl {
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--ink);
  border: 0;
  border-radius: 0;
  padding: clamp(1.5rem, 1rem + 1.6vw, 2.1rem) clamp(1.2rem, .8rem + 1.4vw, 1.7rem);
  transition: background .3s var(--ease);
}
.card.lvl::before {
  display: block;
  background: var(--lc);
  height: 3px; top: 0; left: 0;
}
.card.lvl:hover { background: var(--ink-2); }
.card.lvl:hover::before { width: 100%; }

.lvl .key {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: var(--fs-mono); font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase; color: var(--t-2);
}
.lvl .key .sq { width: 8px; height: 8px; border-radius: 0; background: var(--lc) !important; }
/* The promise is the display serif — it's the sentence the level is sold on. */
.lvl h3 {
  margin-top: 20px;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.5rem, 1.2rem + 1.1vw, 1.95rem);
  line-height: 1.08;
  letter-spacing: -.018em;
}
.lvl .say { margin-top: 14px; font-size: var(--fs-sm); color: var(--t-2); font-weight: 500; line-height: 1.55; }
.lvl p.desc { margin-top: 12px; font-size: var(--fs-sm); color: var(--t-3); line-height: 1.65; flex: 1; }
.lvl .btn { margin-top: 24px; }

/* Polish meter — the "increasing craft" visual, no numbers */
.polish { display: flex; gap: 4px; margin-top: 20px; }
.polish i {
  height: 3px; flex: 1; border-radius: 0;
  background: rgba(244,238,227,.1);
  transition: background .5s var(--ease), transform .5s var(--ease);
}
.polish i.on { background: var(--lc, var(--brand)); }
.lvl:hover .polish i.on { transform: scaleY(2); }

/* Mini clip strip that gains layers per level */
.mini { display: grid; gap: 3px; margin-top: 20px; }
.mini .lane { height: 8px; border-radius: 0; background: rgba(244,238,227,.055); position: relative; overflow: hidden; }
.mini .lane b {
  position: absolute; top: 0; bottom: 0; border-radius: 0; display: block;
  background: rgba(244,238,227,.24);
}
.mini .lane b.o { background: var(--lc, var(--brand)); }
.mini .lane b.v { background: rgba(244,238,227,.42); }
.mini .lane b.c { background: rgba(244,238,227,.6); }
.mini .lane.off { opacity: .3; }

/* ---------------------------------------------- 20. Teaser -------------- */
/* Dim-until-hover is only safe where hover exists; on touch it stranded
   this card at 60% permanently, dropping its labels to ~1.8:1. */
.teaser { transition: opacity .4s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  /* .82, not .72 — at .72 the --t-4 caption inside fell to ~4.4:1. */
  .teaser { opacity: .82; }
  .teaser:hover, .teaser:focus-within { opacity: 1; }
}

.ladder { display: grid; gap: 10px; }
.ladder-row {
  display: grid; grid-template-columns: 96px 1fr;
  gap: 12px; align-items: center;
}
.ladder-row .nm {
  font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--t-4);
}
.ladder-bar { height: 34px; border-radius: 9px; position: relative; overflow: hidden; background: rgba(244,238,227,.04); }
.ladder-fill {
  position: absolute; inset: 0 auto 0 0; border-radius: 9px;
  background: linear-gradient(90deg, rgba(244,238,227,.13), rgba(185,161,107,.5) 55%, var(--brand));
  transition: width 1.1s var(--ease-out);
}
.ladder-tag {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--paper);
  background: rgba(0,0,0,.62); padding: 3px 7px; border-radius: var(--r-sm);
}

/* ---------------------------------------------- 21. Trust grid ----------
   A ledger. Hairline cells, no radius, the icon demoted to a small mark
   beside the heading rather than a 46px rounded tile above it. */
.trust {
  display: grid; gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line-2);
  border-radius: 0; overflow: hidden;
}
@media (min-width: 640px)  { .trust { grid-template-columns: repeat(2, 1fr); } }
/* Same reason as .levels — 1000px is exactly where the slug column appears,
   so going 3-up there would shrink each cell at the moment it loses width. */
@media (min-width: 1200px) { .trust { grid-template-columns: repeat(3, 1fr); } }
.trust > div {
  background: var(--ink);
  padding: clamp(1.5rem, 1.1rem + 1.3vw, 2.1rem);
  transition: background .25s var(--ease);
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 14px;
  align-content: start;
}
.trust > div:hover { background: var(--ink-2); }
.trust h3 { font-size: var(--fs-h4); margin-top: 0; align-self: center; }
.trust p { grid-column: 2; margin-top: 12px; font-size: var(--fs-sm); color: var(--t-3); line-height: 1.7; }
.trust .ico { width: 22px; height: 22px; color: var(--brand); align-self: center; }

/* ---------------------------------------------- 22. Calculator ---------- */
.calc-grid { display: grid; gap: 20px; }
@media (min-width: 1000px) {
  .calc-grid { grid-template-columns: 1.25fr .85fr; gap: 28px; align-items: start; }
  .calc-side { position: sticky; top: var(--stick); }
}

.cstep {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  padding: clamp(1.1rem, .9rem + 1vw, 1.6rem);
  transition: opacity .3s var(--ease);
}
.cstep + .cstep { margin-top: 14px; }
/* Dimming the whole locked step multiplied down its own explanatory label to
   ~3.5:1 — the one line the user most needs to read. The panel is dimmed,
   the instruction is not. */
.cstep.locked { opacity: .8; pointer-events: none; }
.cstep.locked .cstep-hd::after {
  content: "Choose above first";
  font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--t-2); margin-left: auto;
}
.cstep-hd { display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px; }
.cstep-hd .n {
  font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .2em; color: var(--brand);
}
.cstep-hd h3 { font-size: var(--fs-h4); }

.opts { display: grid; gap: 9px; }
@media (min-width: 560px) { .opts-3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 460px) { .opts-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 760px) { .opts-4 { grid-template-columns: repeat(2, 1fr); } }

.opt {
  position: relative;
  display: flex; flex-direction: column; gap: 5px;
  min-height: 62px;
  padding: 13px 16px;
  text-align: left;
  border: 1px solid var(--line-ui);
  border-radius: var(--r);
  background: rgba(244,238,227,.028);
  transition: border-color .2s var(--ease), background .2s var(--ease), transform .15s var(--ease);
}
.opt:hover { border-color: var(--line-3); background: rgba(244,238,227,.05); }
.opt:active { transform: scale(.99); }
.opt[aria-pressed="true"] {
  border-color: var(--brand);
  background: var(--brand-dim);
}
/* Selection is never colour-only — a check glyph is added too */
.opt[aria-pressed="true"]::after {
  content: "\2713";
  position: absolute; top: 12px; right: 14px;
  font-size: 13px; color: var(--brand); font-weight: 700;
}
.opt-lbl { font-size: var(--fs-body); font-weight: 620; letter-spacing: -.015em; }
.opt-sub { font-family: var(--mono); font-size: var(--fs-mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--t-4); }
.opt-key { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-body); font-weight: 620; }
.opt-key i { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }
.opt-say { font-size: var(--fs-sm); color: var(--t-3); }
.opt-price { font-family: var(--mono); font-size: var(--fs-xs); color: var(--t-2); margin-top: 2px; }
.opt-lvl { min-height: 92px; padding-right: 40px; }

/* raw footage input pair */
.raw-pair { display: grid; grid-template-columns: 120px 1fr; gap: 14px; align-items: center; }
@media (max-width: 420px) { .raw-pair { grid-template-columns: 1fr; } }

input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 44px; background: transparent; cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 3px; background: var(--line-ui);
}
input[type="range"]::-moz-range-track {
  height: 4px; border-radius: 3px; background: var(--line-ui);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 28px; height: 28px; margin-top: -12px;
  border-radius: 50%; background: var(--paper);
  border: 3px solid var(--brand);
  box-shadow: 0 6px 18px rgba(0,0,0,.45);
}
input[type="range"]::-moz-range-thumb {
  width: 22px; height: 22px;
  border-radius: 50%; background: var(--paper);
  border: 3px solid var(--brand);
  box-shadow: 0 6px 18px rgba(0,0,0,.45);
}

/* Live estimate panel */
.est {
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 90% at 15% 0%, rgba(185,161,107,.14), transparent 62%),
    var(--surface-2);
  padding: clamp(1.1rem, .9rem + 1vw, 1.6rem);
}
.est h3 { font-size: var(--fs-h4); }
.est-line {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm);
}
.est-line span:first-child { color: var(--t-3); }
.est-line span:last-child { font-weight: 600; font-variant-numeric: tabular-nums; }
.est-line.is-zero span:last-child { color: var(--t-4); font-weight: 500; }
.est-total {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding-top: 18px; margin-top: 6px;
}
.est-total span { font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .18em; text-transform: uppercase; color: var(--t-4); }
/* Money is set in the display serif — the biggest number on the page
   should look printed, not computed. */
.est-total strong {
  font-family: var(--display);
  font-size: clamp(2.4rem, 1.6rem + 3vw, 3.6rem);
  font-weight: 400; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.est-note { font-size: var(--fs-xs); color: var(--t-4); line-height: 1.6; margin-top: 14px; }

.est-hint {
  border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  padding: 28px 20px; text-align: center;
  color: var(--t-4); font-size: var(--fs-sm);
}

/* Above-the-fold price teaser. Reads as a spec strip, not a card grid. */
.teaser-price {
  border-top: 1px solid var(--line-2);
  border-bottom: 1px solid var(--line-2);
  padding-block: clamp(1.1rem, .9rem + 1vw, 1.6rem);
}
.teaser-price ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 1px;
  background: var(--line);
}
.teaser-price li {
  background: var(--ink);
  padding: 4px 0 4px 0;
  display: flex; flex-direction: column; gap: 4px;
}
@media (min-width: 560px) { .teaser-price li { padding-inline: 18px; } }
@media (min-width: 560px) { .teaser-price li:first-child { padding-left: 0; } }
.teaser-price li span {
  font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--t-4);
}
.teaser-price li strong {
  font-family: var(--display);
  font-size: clamp(2rem, 1.5rem + 2vw, 3rem);
  font-weight: 400; letter-spacing: -.025em; line-height: 1.05;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------- 23. Journey scroll ------ */
.jrn { display: grid; gap: 22px; }
@media (min-width: 1000px) { .jrn { grid-template-columns: .82fr 1.18fr; gap: 40px; align-items: start; } }

.jrn-visual { position: sticky; top: var(--stick); }
@media (max-width: 999px) { .jrn-visual { position: sticky; top: 76px; z-index: 20; } }

.jrn-frame {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-lg);
  border: 1px solid var(--line-2);
  overflow: hidden;
  background: linear-gradient(160deg, #302620, #141010);
}
.jrn-frame > * { position: absolute; inset: 0; }

.jl { opacity: 0; transition: opacity .55s var(--ease); }
.jl.on { opacity: 1; }

.jl-raw   { background: linear-gradient(160deg, #362A22, #171211); }
.jl-select{ background: repeating-linear-gradient(90deg, rgba(244,238,227,.05) 0 3px, transparent 3px 26px); }
.jl-cut   { background: radial-gradient(70% 70% at 50% 45%, rgba(244,238,227,.10), transparent 70%); }
.jl-enhance { background: radial-gradient(60% 60% at 30% 70%, rgba(110,139,132,.18), transparent 65%); }
.jl-design  { background: radial-gradient(60% 60% at 72% 28%, rgba(185,161,107,.32), transparent 62%); }
.jl-polish  { background:
  radial-gradient(70% 70% at 35% 30%, rgba(228,86,42,.30), transparent 64%),
  radial-gradient(60% 60% at 80% 78%, rgba(185,161,107,.28), transparent 62%); }
.jl-final   { background: linear-gradient(180deg, rgba(244,238,227,.06), transparent 40%);
  box-shadow: inset 0 0 90px rgba(228,86,42,.16); }

.jl-cap {
  inset: auto 0 14% 0; display: grid; place-items: center;
}
.jl-gfx {
  inset: 12% 8% auto auto; width: 74px; height: 46px;
  border: 1px solid rgba(244,238,227,.4); border-radius: 8px;
  background: rgba(185,161,107,.22);
}
.jl-3d {
  inset: auto auto 16% 10%; width: 60px; height: 60px;
  border: 1px solid rgba(244,238,227,.42); border-radius: 10px;
  background: linear-gradient(150deg, rgba(228,86,42,.5), rgba(185,161,107,.5));
  transform: rotate(-12deg);
  box-shadow: 12px 12px 0 rgba(244,238,227,.07);
}

.jrn-rail { display: flex; gap: 6px; margin-top: 12px; flex-wrap: wrap; }
.jrn-rail button {
  min-height: 44px; padding: 0 11px;
  border-radius: 999px; border: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--t-4);
  transition: all .2s var(--ease);
}
.jrn-rail button[aria-current="true"] {
  color: var(--t-1); border-color: var(--brand-line); background: var(--brand-dim);
}

.jrn-steps { display: grid; gap: 10px; }
.jrn-step {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); padding: clamp(1rem, .85rem + .8vw, 1.5rem);
  min-height: 30svh; display: flex; flex-direction: column; justify-content: center;
}
.jrn-step .idx { font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .2em; color: var(--brand); }
.jrn-step h3 { margin-top: 10px; font-size: var(--fs-h3); }
.jrn-step p { margin-top: 10px; color: var(--t-3); font-size: var(--fs-body); line-height: 1.65; }

/* ---------------------------------------------- 24. Matrix -------------- */
.mtx th:first-child, .mtx td:first-child {
  position: sticky; left: 0; background: var(--ink-2); z-index: 1;
  border-right: 1px solid var(--line);
  white-space: normal; min-width: 190px;
}
.mtx thead th:first-child { z-index: 2; }
.mtx td { text-align: center; }
.mtx td:first-child { text-align: left; color: var(--t-2); }
.mtx .yes { color: var(--t-1); font-weight: 700; }
.mtx .no  { color: var(--t-4); }
.mtx .val { font-size: var(--fs-xs); color: var(--t-2); }

/* Mobile: matrix becomes per-level accordions */
.acc { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.acc + .acc { margin-top: 10px; }
.acc > button {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: 60px; padding: 14px 18px;
  background: var(--surface); text-align: left;
}
.acc > button .k { display: inline-flex; align-items: center; gap: 10px; font-weight: 620; }
.acc > button .k i { width: 9px; height: 9px; border-radius: 3px; }
.acc > button .cx { color: var(--t-4); transition: transform .25s var(--ease); }
.acc > button[aria-expanded="true"] .cx { transform: rotate(45deg); }
.acc-body { padding: 4px 18px 18px; background: var(--ink-2); }
.acc-body li {
  display: flex; justify-content: space-between; gap: 14px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm);
}
.acc-body li:last-child { border-bottom: 0; }
.acc-body li span:first-child { color: var(--t-3); }
.acc-body li span:last-child { color: var(--t-1); font-weight: 560; text-align: right; }
.acc-body li .no { color: var(--t-4); font-weight: 400; }

@media (min-width: 900px) { .only-mob { display: none; } }
@media (max-width: 899px) { .only-desk { display: none; } }

/* Mobile price cards — replaces the sideways-scrolling table below 900px */
.pcard {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}
.pcard + .pcard { margin-top: 10px; }
.pcard-hd {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: rgba(244,238,227,.03);
  border-bottom: 1px solid var(--line);
}
.pcard-hd strong { font-size: var(--fs-body); font-weight: 620; letter-spacing: -.015em; }
.pcard-hd span {
  font-size: var(--fs-mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--t-4); white-space: nowrap;
}
.pcard ul { padding: 4px 16px 10px; }
.pcard li {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--t-3);
}
.pcard li:last-child { border-bottom: 0; }
.pcard li .price {
  color: var(--t-1); font-weight: 640;
  font-variant-numeric: tabular-nums; font-size: var(--fs-body);
}

/* ---------------------------------------------- 25. Raw example --------- */
.rawex-bar {
  display: flex; height: 46px; border-radius: 12px; overflow: hidden;
  border: 1px solid var(--line-2); background: rgba(244,238,227,.03);
}
.rawex-bar i {
  display: block; height: 100%;
  transition: width .35s var(--ease);
}
.rawex-bar .incl { background: linear-gradient(90deg, rgba(185,161,107,.55), rgba(185,161,107,.35)); }
.rawex-bar .xtra { background: linear-gradient(90deg, var(--brand), var(--brand-lift)); }
.rawex-legend {
  display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 14px;
  font-size: var(--fs-xs); color: var(--t-3);
}
.rawex-legend span { display: inline-flex; align-items: center; gap: 7px; }
.rawex-legend i { width: 10px; height: 10px; border-radius: 3px; }
.rawex-out {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
  gap: 10px; margin-top: 18px;
}
.rawex-out div {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 12px 14px; background: rgba(244,238,227,.022);
}
.rawex-out dt { font-family: var(--mono); font-size: var(--fs-micro); letter-spacing: .14em;
  text-transform: uppercase; color: var(--t-4); }
.rawex-out dd {
  margin: 6px 0 0;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.4rem, 1.2rem + .8vw, 1.8rem); line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------- 26. Policies + FAQ ------ */
.pol { display: grid; gap: 14px; }
@media (min-width: 860px) { .pol { grid-template-columns: repeat(2, 1fr); } }
.pol article { display: flex; flex-direction: column; gap: 14px; }
.pol .ico {
  width: 42px; height: 42px; border-radius: 12px;
  border: 1px solid var(--brand-line); background: var(--brand-dim);
  display: grid; place-items: center; color: var(--brand); flex-shrink: 0;
}
.pol h3 { font-size: var(--fs-h4); }
.pol p { max-width: 62ch; }
.pol p { font-size: var(--fs-body); color: var(--t-3); line-height: 1.7; }

.faq details {
  border-bottom: 1px solid var(--line);
}
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 64px; padding: 16px 2px;
  font-size: var(--fs-body); font-weight: 580;
  cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; font-size: 20px; color: var(--t-4); flex-shrink: 0;
  transition: transform .25s var(--ease);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p { padding: 0 2px 20px; font-size: var(--fs-body); color: var(--t-3); line-height: 1.7; max-width: 68ch; }

/* ---------------------------------------------- 27. Final CTA ----------- */
/* The closing plate reads as the back cover: heavy rules top and bottom,
   no fill, no glow. The type does the work. */
.cta-band {
  border: 0;
  border-block: 2px solid var(--brand);
  border-radius: 0;
  padding: clamp(2.4rem, 1.4rem + 5vw, 4.5rem) clamp(1.2rem, 1rem + 2vw, 2.5rem);
  text-align: center;
  position: relative; overflow: hidden;
  background: var(--ink-2);
}
/* Faint perforation strip down both edges — a frame on a strip of film. */
.cta-band::before, .cta-band::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 14px;
  background-image: linear-gradient(180deg, var(--line-2) 6px, transparent 6px);
  background-size: 100% 20px;
  opacity: .8;
}
.cta-band::before { left: 10px; }
.cta-band::after  { right: 10px; }
.cta-band > * { position: relative; z-index: 1; }
.cta-band h2 { max-width: 20ch; margin-inline: auto; }
.cta-band .lede { margin-inline: auto; }
.cta-band .row { justify-content: center; margin-top: 30px; }
@media (max-width: 460px) { .cta-band .btn { width: 100%; } }

/* ---------------------------------------------- 28. Legal pages --------- */
.legal { max-width: 68ch; }
.legal h2 { font-size: var(--fs-h3); margin-top: 44px; line-height: 1.25; letter-spacing: -.02em; }
.legal h2:first-of-type { margin-top: 0; }
.legal p, .legal li { color: var(--t-3); font-size: var(--fs-body); line-height: 1.65; }
.legal p + p { margin-top: 14px; }
.legal ul { margin-top: 14px; display: grid; gap: 10px; }
.legal ul li { padding-left: 22px; position: relative; }
.legal ul li::before {
  content: ""; position: absolute; left: 0; top: 11px;
  width: 7px; height: 7px; border-radius: 2px; background: var(--brand);
}
.legal strong { color: var(--t-1); font-weight: 600; }

/* ================================================ 29. Following docks ====
   A persistent action that travels with the reader. Two variants:
   · landing  → free sample
   · pricing  → live estimate + start project
   Both sit above the safe area, both are dismissible, both get out of the
   way when the thing they point at is already on screen.
   ======================================================================== */
.dock {
  position: fixed;
  left: 50%;
  bottom: max(14px, env(safe-area-inset-bottom));
  z-index: 90;
  width: min(680px, calc(100vw - 24px));
  transform: translate(-50%, 150%);
  opacity: 0;
  visibility: hidden;            /* keeps it out of the tab order when hidden */
  pointer-events: none;
  transition: transform .5s var(--ease-out), opacity .35s var(--ease),
              visibility 0s linear .5s;
}
.dock.show {
  transform: translate(-50%, 0);
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: transform .5s var(--ease-out), opacity .35s var(--ease),
              visibility 0s;
}

.dock-in {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 12px 10px 18px;
  border-radius: var(--r);
  border: 1px solid var(--line-2);
  border-top: 2px solid var(--brand);
  background: rgba(18,16,13,.9);
  backdrop-filter: blur(22px) saturate(1.2);
  -webkit-backdrop-filter: blur(22px) saturate(1.2);
  box-shadow: 0 18px 50px rgba(0,0,0,.6), inset 0 1px 0 rgba(244,238,227,.05);
}
.dock-txt { flex: 1; min-width: 0; }
.dock-txt strong {
  display: block;
  font-size: var(--fs-sm); font-weight: 620; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dock-txt span {
  display: block;
  font-family: var(--mono); font-size: var(--fs-mono);
  letter-spacing: .13em; text-transform: uppercase; color: var(--t-4);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dock .btn { flex-shrink: 0; min-height: 44px; padding: 0 20px; font-size: var(--fs-sm); }

.dock-close {
  flex-shrink: 0;
  width: 44px; height: 44px; margin-right: -2px;
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--t-4);
  transition: color .2s var(--ease), background .2s var(--ease);
}
.dock-close:hover { color: var(--t-1); background: rgba(244,238,227,.07); }

/* Running total reads as a number, not a label */
.dock-total {
  font-family: var(--display);
  font-size: 1.7rem; font-weight: 400; letter-spacing: -.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
  display: block;
}
.dock-total.bump { animation: bump .42s var(--ease); }
@keyframes bump {
  0% { transform: scale(1); }
  38% { transform: scale(1.13); color: var(--brand); }
  100% { transform: scale(1); }
}

@media (max-width: 520px) {
  .dock-in { gap: 8px; padding-left: 14px; }
  .dock .btn { padding: 0 14px; }
  .dock-close { width: 40px; height: 40px; }
}

/* ============================================ 30. "What you get" panel ===
   The payoff for choosing a level: the deliverables appear, and the ones
   that are NEW at this level are called out against the inherited ones.
   ======================================================================== */
.gets { margin-top: 16px; }
.gets-hd {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.gets-hd h4 { font-size: var(--fs-h4); }
.gets-hd em {
  font-family: var(--mono); font-size: var(--fs-mono); font-style: normal;
  letter-spacing: .14em; text-transform: uppercase; color: var(--t-4);
}

.gets ul { display: grid; gap: 0; }
.gets li {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm);
  color: var(--t-3);
  opacity: 0;
  transform: translate3d(0, 6px, 0);
  animation: getin .42s var(--ease-out) forwards;
}
.gets li:last-child { border-bottom: 0; }
@keyframes getin { to { opacity: 1; transform: none; } }

.gets li .mk {
  flex-shrink: 0; width: 16px; height: 16px; margin-top: 3px;
  border-radius: 5px;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 700;
  background: rgba(244,238,227,.07);
  color: var(--t-4);
}
/* New at this level — carries a word, not just a colour */
.gets li.fresh { color: var(--t-1); }
.gets li.fresh .mk { background: var(--brand-dim); color: var(--brand); }
.gets li.fresh .tag {
  margin-left: auto; flex-shrink: 0;
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--brand);
  align-self: center;
}

/* Level preview — abstract, gains a layer per level */
.pv {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--r);
  border: 1px solid var(--line-2);
  overflow: hidden;
  background: linear-gradient(160deg, #332822, #141010);
  margin-bottom: 16px;
}
.pv > i {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity .6s var(--ease);
}
.pv > i.on { opacity: 1; }
.pv .p-cut  { background: radial-gradient(70% 70% at 50% 45%, rgba(244,238,227,.10), transparent 70%); }
.pv .p-pro  { background: radial-gradient(60% 60% at 28% 72%, rgba(110,139,132,.20), transparent 66%); }
.pv .p-max  { background: radial-gradient(62% 62% at 74% 26%, rgba(185,161,107,.34), transparent 62%); }
.pv .p-cin  { background:
  radial-gradient(70% 70% at 34% 30%, rgba(228,86,42,.32), transparent 64%),
  linear-gradient(180deg, rgba(244,238,227,.07), transparent 42%);
  box-shadow: inset 0 0 80px rgba(228,86,42,.18); }

.pv .p-cap {
  position: absolute; inset: auto 0 13% 0;
  display: grid; place-items: center;
  opacity: 0; visibility: hidden;
  transition: opacity .6s var(--ease), visibility 0s linear .6s;
}
.pv .p-cap.on { opacity: 1; visibility: visible; transition: opacity .6s var(--ease), visibility 0s; }
.pv .p-gfx {
  position: absolute; top: 12%; right: 9%;
  width: 64px; height: 38px;
  border: 1px solid rgba(244,238,227,.42); border-radius: 7px;
  background: rgba(185,161,107,.24);
  opacity: 0; transform: translate3d(10px,0,0);
  transition: opacity .6s var(--ease), transform .6s var(--ease-out);
}
.pv .p-gfx.on { opacity: 1; transform: none; }
.pv .p-3d {
  position: absolute; bottom: 15%; left: 9%;
  width: 52px; height: 52px;
  border: 1px solid rgba(244,238,227,.44); border-radius: 9px;
  background: linear-gradient(150deg, rgba(228,86,42,.52), rgba(185,161,107,.52));
  box-shadow: 10px 10px 0 rgba(244,238,227,.07);
  opacity: 0; transform: rotate(-12deg) scale(.7);
  transition: opacity .6s var(--ease), transform .6s var(--ease-out);
}
.pv .p-3d.on { opacity: 1; transform: rotate(-12deg) scale(1); }

.pv-badge {
  position: absolute; top: 10px; left: 12px;
  font-family: var(--mono); font-size: var(--fs-micro);
  letter-spacing: .14em; text-transform: uppercase;
  padding: 5px 9px; border-radius: 999px;
  background: rgba(0,0,0,.55); border: 1px solid var(--line-2);
  color: var(--t-2);
}

/* The old mobile sticky panel is replaced by the dock */
.calc-side.stuck-mobile { position: static; margin-inline: 0; padding-inline: 0; background: none; }
@media (max-width: 999px) { .calc-side.stuck-mobile { padding-bottom: 0; } }
/* Reserved at every width — on desktop the dock would otherwise cover a
   focused link, failing WCAG 2.4.11 Focus Not Obscured. */
body.has-dock { padding-bottom: calc(82px + env(safe-area-inset-bottom)); }

/* ============================================ 31. Editorial furniture ====
   The pieces that make the page read as a printed spread rather than a
   stack of sections: marginal notes, a pull-quote, a drop cap, and a
   headline that arrives a line at a time from behind a mask.
   ======================================================================== */

/* Marginal note — a set-aside annotation, the way a caption sits beside a
   plate. It cannot go in the slug column (the sticky eyebrow spans the whole
   section there) and it cannot float, because as a direct child of the wrap
   it is a grid item and `float` computes to none on those. So it is pushed
   to the outer edge of the measure with an auto inline-start margin, which
   reads the same and is immune to both problems. */
.marginalia {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  line-height: 1.75;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--t-4);
  border-left: 1px solid var(--brand-line);
  padding-left: 14px;
  max-width: 30ch;
  margin-top: var(--sp-3);
}
@media (min-width: 1100px) {
  .marginalia {
    width: 30ch;
    margin-inline-start: auto;
    text-align: left;
  }
}

/* Pull-quote — the one place the display serif runs at headline scale
   inside body copy. Hangs off the left margin so it breaks the measure. */
.pull {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.7rem, 1.2rem + 2.4vw, 3rem);
  line-height: 1.12;
  letter-spacing: -.02em;
  color: var(--t-1);
  border-left: 2px solid var(--brand);
  padding-left: clamp(1rem, 2.5vw, 2rem);
  /* The UA gives <blockquote> a 40px inline margin. Left unreset it indents
     the quote on both sides, which is the opposite of hanging off the rule. */
  margin-inline: 0;
  margin-block: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  max-width: 22ch;
}
.pull cite {
  display: block;
  margin-top: 18px;
  font-family: var(--mono); font-style: normal;
  font-size: var(--fs-micro); letter-spacing: .22em;
  text-transform: uppercase; color: var(--t-4);
}

/* Drop cap — one per page, on the opening paragraph of the about block. */
.dropcap::first-letter {
  float: left;
  font-family: var(--display);
  font-size: 3.6em;
  line-height: .78;
  padding: .06em .12em 0 0;
  color: var(--brand);
}

/* Numbered chapter marker for the slug column. */
.eyebrow .no {
  font-size: var(--fs-micro);
  letter-spacing: .18em;
  color: var(--brand);
}

/* Statement figures — the standalone numbers in the trust/spec strips. */
.figure {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.6rem, 1.8rem + 3.4vw, 4.4rem);
  line-height: .95; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}

/* Headline mask reveal — each line rides up from behind its own overflow
   box, so the words appear to be printed onto the page rather than faded
   in. Applied only to the hero, where one orchestrated moment lands. */
.reveal-mask {
  display: block;
  overflow: hidden;
  /* Instrument Serif italic hangs well below the baseline. A flush overflow
     box would guillotine the descenders on "your footage," so the box grows
     downward and is pulled back up by the same amount. */
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
.reveal-mask > span {
  display: block;
  transform: translate3d(0, 115%, 0);
  transition: transform 1s var(--ease-out);
}
.rv.in .reveal-mask > span,
.reveal-mask.in > span { transform: none; }
.reveal-mask:nth-of-type(2) > span { transition-delay: .09s; }
.reveal-mask:nth-of-type(3) > span { transition-delay: .18s; }

/* Hairline divider with a vermillion tick, for breaking long text runs. */
.rule-tick {
  position: relative; height: 1px; border: 0; background: var(--line-2);
  margin-block: clamp(2rem, 1.5rem + 2vw, 3.5rem);
}
.rule-tick::before {
  content: ""; position: absolute; left: 0; top: 0; width: 46px; height: 1px;
  background: var(--brand);
}

/* ---------------------------------------------- 32. Legal + FAQ tune ---- */
.legal h2 { font-family: var(--display); font-weight: 400; letter-spacing: -.015em; }
.legal ul li::before { border-radius: 0; width: 8px; height: 1px; top: 14px; }
.faq summary { font-family: var(--sans); font-weight: 600; }

/* ------------------------------------------------ 32b. Touch & iOS ------
   Everything above this line was written hover-first. A phone has no hover.
   Safari synthesises one on tap and then LEAVES IT APPLIED until you touch
   something else, so all eighteen `:hover` rules in this file were states
   that stuck to whatever the reader last pressed. Two were real bugs rather
   than cosmetic ones:

   · `.ftr li a:hover` adds 6px of left padding. Tapping a footer link shunted
     the label sideways and left it there — a permanent layout shift caused
     by reading the page.
   · `.opt:hover` lifts the border and fill of a pricing option, which is very
     close to how `[aria-pressed="true"]` renders. After tapping through a few
     options, the previous ones all looked half-selected.

   The fix states the base value back on `:hover` wherever a fine pointer is
   absent, rather than gating eighteen scattered rules at their definition
   sites — one block to audit instead of eighteen to keep in sync. */
@media (hover: none) {
  .btn-cta:hover          { background: var(--cta); border-color: var(--cta); }
  .btn-cta:hover::before  { height: 0; }
  .btn-ghost:hover        { border-color: var(--line-ui); color: var(--t-2); background: transparent; }
  .btn:hover .arw         { transform: none; }

  .card:hover             { border-color: var(--line); background: var(--ink-2); }
  .card:hover::before     { width: 0; }
  .card.lvl:hover         { background: var(--ink); }
  .card.lvl:hover::before { width: 0; }
  .lvl:hover .polish i.on { transform: none; }

  .step:hover             { background: transparent; }
  .step:hover .num        { color: rgba(247,242,233,.40); }
  .trust > div:hover      { background: var(--ink); }
  .tbl tbody tr:hover     { background: transparent; }
  .opt:hover              { border-color: var(--line-ui); background: rgba(244,238,227,.028); }
  .dock-close:hover       { color: var(--t-4); background: transparent; }
  .ftr li a:hover         { color: var(--t-3); padding-left: 0; }

  /* The `:not()` is load-bearing. That nav rule is shared with
     `[aria-current="page"]`, so neutralising it flat would have erased the
     you-are-here underline on every iPad. */
  .hdr nav a:hover:not([aria-current="page"])        { color: var(--t-4); }
  .hdr nav a:hover:not([aria-current="page"])::after { width: 0; }
}

/* iOS paints a translucent grey rectangle over any tapped link or control.
   It flashes cold against a warm carbon page and it is the wrong shape for
   near-square editorial plates, so it goes, and is replaced properly below. */
a, button, summary, label,
[role="button"], .opt, .card { -webkit-tap-highlight-color: transparent; }

/* The replacement. Hover is a hint that something is reachable; `:active` is
   a confirmation that it was hit. A phone only ever needed the second one,
   and until now it had almost none.

   Scope is deliberate, and it is narrower than the list above. `.card`,
   `.card.lvl`, `.step` and `.trust > div` are div/article/li with no href,
   no role and no tabindex — nothing about them is pressable. Their hover
   states were desktop reach-for affordances, which is why they are cancelled
   above but NOT given a press state here. Two reasons: iOS Safari does not
   fire `:active` on a non-interactive element unless a touch handler is
   bound to it, so the rule would be inert; and if it did fire it would be a
   lie, promising a tap target that does not exist. Only things you can
   actually press get pressed feedback.

   Durations are roughly a third of the desktop hover equivalents, so the
   response lands inside the touch instead of trailing it. */
@media (hover: none) {
  .btn-cta:active::before { height: 100%; transition-duration: .12s; }
  .btn-ghost:active       { border-color: var(--brand); background: var(--brand-dim); color: var(--t-1); }
  .opt:active             { border-color: var(--line-3); background: rgba(244,238,227,.05); }
  .ftr li a:active        { color: var(--t-1); }
  .hdr nav a:active       { color: var(--t-1); }
  .dock-close:active      { color: var(--t-1); background: rgba(244,238,227,.07); }
  .faq summary:active     { color: var(--t-1); }
}

/* Coarse-pointer cost. `.atmos i` is two elements carrying a 90px Gaussian
   blur on 34- and 44-second infinite loops. A blur that wide is among the
   most expensive things a phone GPU can be handed, and it was being
   recomputed forever to move an 11%-opacity bloom a few percent sideways.
   The bloom earns its place; the drift does not. Holding it still also stops
   the animation keeping the compositor awake on a tab left open in a
   pocket. */
@media (pointer: coarse) {
  .atmos i { animation: none; filter: blur(58px); will-change: auto; }
}

/* `font-synthesis: none` — the display face is Instrument Serif, which ships
   400 and a true italic and nothing else. Every rule here sets 400 on
   purpose, but one stray `font-weight: 600` downstream and Safari would
   smear a synthetic bold across a 52px headline. This makes that failure
   impossible rather than merely currently-avoided. Both other families ship
   real weights, so nothing legitimate is lost.
   (No `accent-color` rule: the only native controls on the site are two
   range inputs, and both are already fully custom-painted via
   ::-webkit-slider-thumb and ::-moz-range-thumb, so it would be dead CSS.) */
html { font-synthesis: none; text-size-adjust: 100%; }
/* Vermillion selection, carbon text: 5.2:1. Cream on vermillion is 3.2:1. */
::selection { background: var(--brand); color: var(--cta-ink); }

/* ---------------------------------- 33. Reduced motion (hard stop) ------ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .rv { opacity: 1 !important; transform: none !important; }
  .reveal-mask > span { transform: none !important; }
  .atmos i { animation: none !important; }
  .wave i { transform: scaleY(.55) !important; }
}

/* Grain is a still plate, but it still costs a full-viewport composite on
   very small devices with no benefit. Ease it off rather than drop it. */
@media (max-width: 480px) {
  body::before { opacity: .2; }
}

/* --------------------------------------------------- 30. Form plumbing --- */
/* Honeypot. Must be reachable by a naive bot but never by a person or a
   screen reader — display:none is skipped by some bots, so move it instead. */
.hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Network/server failure on submit. Distinct from field validation: the
   details were NOT saved, and the message has to say so. */
.send-error {
  margin-top: var(--sp-3);
  padding: 14px 16px;
  border: 1px solid rgba(228,112,90,.5);
  border-left-width: 2px;
  background: rgba(228,112,90,.10);
  color: #F0B4A6;
  font-size: var(--fs-sm);
  line-height: 1.6;
}

/* Submit button while the request is in flight. */
.btn[disabled] { opacity: .6; cursor: progress; }
