/* ============================================================
   chriscip.com
   Palette sampled from his own kitchen footage. Every ratio computed.
   ============================================================ */

:root{
  --canvas:#F4F0E9;
  --panel:#EAE4D9;
  --ink:#1D2126;          /* 14.25:1 on canvas */
  --ink-soft:#565C64;     /* 5.94:1 */
  --rule:#8B7B60;         /* interactive borders, 3.63:1 */
  --hairline:#DCD3C4;     /* decorative only */

  --accent:#F7B03A;       /* FILL AND GRAPHIC ONLY. 1.65:1 as text. */
  --accent-hover:#FFC154;
  --accent-muted:rgba(247,176,58,.18);
  --accent-text:#8A5A08;  /* 5.21:1 */
  --on-accent:#191A1E;    /* on the amber button, 9.29:1 */
  --focus:#B57E12;        /* 3.10:1 */

  --data:#2F5F7D;         /* 6.05:1 */
  --data-line:#3D6B8A;    /* 5.04:1 */
  --line-dead:#8C8578;    /* 3.22:1 */

  --deep:#191A1E;
  --on-deep:#F4F0E9;

  --display:'Anton',Impact,'Haettenschweiler','Arial Narrow Bold',sans-serif;
  --body:'Instrument Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Helvetica,Arial,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  --tshadow:0 1px 2px rgba(8,10,14,.95),0 3px 12px rgba(8,10,14,.78),0 10px 44px rgba(8,10,14,.8);

  /* The logo's on-dark pair is #669BBC and #FFBE0B. Measured over this footage
     they read at 2.30 and 2.98, under the 3.5 floor, because the kitchen is
     bright and blue carries only 7% of perceived brightness. These are the same
     two hues lifted to the lightest-faithful tints that clear the floor. */
  --hero-blue:#9FC6DE;
  --hero-gold:#FFD87A;
  --plate-veg:#8FC9A8;   /* 9.18:1 on --deep */

  /* 300 gave 200vh of scroll through the hero, about 6 seconds at a normal
     flicking pace. 370 gave 270vh, roughly 8, so the journey lasts about two
     seconds longer. Every band range is in progress units, so they all stretch
     with it and nothing needs re-timing.
     470 = that same 370 of scrubbing plus one screen of hold at the end, where
     the video sits on its final frame while the page climbs over it. hero.js
     subtracts the hold from its range, so the film still finishes at 370. */
  --hero-vh:470;
  --hero-hold-vh:100;
  --gut:clamp(20px,5vw,80px);
}

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

/* visually hidden, still read aloud */
.vh{
  position:absolute;width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;
}

html,body{
  overflow-x:hidden;      /* fallback first */
  overflow-x:clip;
}
html{scroll-behavior:smooth}

body{
  margin:0;
  background:var(--canvas);
  color:var(--ink);
  font-family:var(--body);
  font-size:clamp(16px,1.05vw + 12px,19px);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

img,svg,video{display:block;max-width:100%}

::selection{background:var(--accent-muted);color:var(--ink)}

:focus-visible{
  outline:3px solid var(--focus);
  outline-offset:3px;
  border-radius:3px;
}

.skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--ink);color:var(--canvas);
  padding:.7rem 1.1rem;font-family:var(--mono);font-size:.8rem;
  text-decoration:none;border-radius:0 0 6px 0;
}
.skip:focus{left:0}

/* ---------- the fixed environment layer ---------- */

.env{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.env-glow{
  position:absolute;inset:-20%;
  background:
    radial-gradient(ellipse 60% 50% at 22% 18%,rgba(247,176,58,.10),transparent 62%),
    radial-gradient(ellipse 55% 55% at 82% 74%,rgba(47,95,125,.09),transparent 64%);
  animation:drift 96s var(--ease) -22s infinite alternate;
}
@keyframes drift{
  from{transform:translate3d(-2.5%,-1.5%,0) scale(1.02)}
  to{transform:translate3d(2.5%,2%,0) scale(1.08)}
}
.motes{position:absolute;inset:0}
.motes i{
  position:absolute;width:3px;height:3px;border-radius:50%;
  background:var(--accent);opacity:.09;
  animation:mote 74s linear infinite;
}
@keyframes mote{
  from{transform:translate3d(0,8vh,0)}
  to{transform:translate3d(3vw,-104vh,0)}
}

/* ---------- nav ---------- */

.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.85rem var(--gut);
  background:rgba(244,240,233,0);
  border-bottom:1px solid transparent;
  transition:background .5s var(--ease),border-color .5s var(--ease),backdrop-filter .5s var(--ease),padding .5s var(--ease);
}
.nav.stuck{
  background:rgba(244,240,233,.9);
  backdrop-filter:blur(14px) saturate(1.1);
  border-bottom-color:var(--hairline);
  padding-top:.6rem;padding-bottom:.6rem;
}
.nav-logo{display:block;line-height:0;flex:0 0 auto}
.nav-logo img{
  width:clamp(120px,13vw,178px);height:auto;
  filter:drop-shadow(0 1px 5px rgba(8,10,14,.42));
  transition:filter .5s var(--ease);
}
.nav.stuck .nav-logo img{filter:none}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  font-family:var(--mono);font-weight:700;font-size:.74rem;
  letter-spacing:.1em;text-transform:uppercase;text-decoration:none;
  padding:.72rem 1.15rem;border-radius:2px;border:1px solid transparent;
  transition:transform .35s var(--ease-out),background-color .35s var(--ease),box-shadow .35s var(--ease),color .35s var(--ease);
  will-change:transform;
}
.btn-accent{
  background:var(--accent);color:var(--on-accent);
  box-shadow:0 2px 0 rgba(138,90,8,.5), 0 8px 26px -12px rgba(138,90,8,.9);
  text-shadow:none;
}
.btn-accent:hover{background:var(--accent-hover);transform:translateY(-2px);box-shadow:0 4px 0 rgba(138,90,8,.5),0 16px 34px -14px rgba(138,90,8,.9)}
.btn-accent:active{transform:translateY(0)}

@media (pointer:coarse){
  .btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
}

/* ---------- hero ---------- */

.hero{
  position:relative;z-index:1;
  height:calc(var(--hero-vh) * 1vh);
}
.stage{
  position:sticky;top:0;
  height:100vh;height:100svh;
  overflow:hidden;
  background:var(--deep);
  isolation:isolate;
}

.poster,#hero{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;
  /* The clip is 16:9 and almost no window is, so cover is already trimming the
     sides. Biasing that trim to the right slides him off centre toward the right
     and opens the left for the captions. Costs nothing: no crop, no re-encode,
     no zoom. On a true 16:9 window there is no overflow to spend and this is
     simply inert, which is why the captions still clear him unaided. */
  object-position:22% 50%;
}
.poster{background-size:cover;background-position:22% 42%;background-repeat:no-repeat}
#hero{
  opacity:0;
  transition:opacity .8s var(--ease);
  transform:translateZ(0);
  will-change:transform;
}
.stage.video-ready #hero{opacity:1}
.stage.video-failed #hero{display:none}

/* global base scrim, always on, so no frame is ever raw behind the page */
.scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(8,10,14,.40) 0%,rgba(8,10,14,.10) 22%,rgba(8,10,14,0) 42%),
    radial-gradient(ellipse 120% 90% at 50% 45%,rgba(8,10,14,0) 36%,rgba(8,10,14,.44) 100%);
}

/* The static left wash: the whole legibility system for the hero captions, and
   completely still. It dies out before it reaches him, so he stays fully lit and
   the shade reads as the room falling off toward the corner rather than a panel
   laid over the picture. Percentages are of the stage, so it holds its shape at
   every window size. */
.wash{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,
    rgba(6,8,12,.60) 0%,
    rgba(6,8,12,.56) 20%,
    rgba(6,8,12,.40) 36%,
    rgba(6,8,12,.16) 50%,
    rgba(6,8,12,.035) 60%,
    rgba(6,8,12,0)   68%);
}

/* loading ring */
.ring{
  position:absolute;left:50%;bottom:3.2rem;transform:translateX(-50%);
  width:34px;height:34px;color:var(--canvas);opacity:.85;
  transform-origin:50% 50%;
  transition:opacity .5s var(--ease);
}
.ring circle{transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .18s linear}
.stage.video-ready .ring{opacity:0}

/* scroll cue, replaces the ring if the video never lands */
.cue{position:absolute;left:50%;bottom:3rem;transform:translateX(-50%);width:20px;height:32px;opacity:0}
.cue span{
  display:block;width:2px;height:16px;margin:0 auto;background:var(--canvas);opacity:.8;
  animation:cue 2.6s var(--ease) infinite;
}
@keyframes cue{0%,100%{transform:translateY(0);opacity:.25}50%{transform:translateY(9px);opacity:.85}}
.stage.video-failed .cue{opacity:1}

/* ---------- caption bands ---------- */

.bands{position:absolute;inset:0;pointer-events:none}

.band{
  position:absolute;
  opacity:0;
  /* Gutter as margin, not padding, so the cap below measures the TEXT and not
     text-plus-gutter. As padding it squeezed the content box to 320px while the
     longest word needed 340px, and an unbreakable inline-block overflows its
     line to the right, which is exactly the drifting right edge. */
  margin-left:var(--gut);
  padding:0;
  /* Hug the longest line: with right-aligned text the box edge IS the text edge,
     so max-content makes the right edge exact rather than leaving slack that
     moves as the box resizes.
     px/vw, never ch: a ch on a container resolves against the inherited body
     font, not the display face inside it, and caps the wrong measure. */
  width:max-content;
  max-width:min(30rem,40vw);
}
/* No per-band scrim. A scrim tied to a band's opacity has to appear and disappear
   with it, and that switching is visible however it is eased. The legibility now
   comes from .wash, one static left-hand fall of shade that never changes, so
   there is nothing to notice and the words are readable at every scroll position
   rather than only while their own band happens to be lit. */

.band-1{left:0;top:20vh}
.band-2{left:0;bottom:22vh}

.band-line{
  margin:0;
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(2.1rem,4.9vw,4.1rem);
  /* caps have no descenders, so the line box can open up without looking gappy */
  text-transform:uppercase;
  line-height:1.04;
  letter-spacing:.035em;
  color:var(--canvas);
  text-shadow:var(--tshadow);
}
/* band 1 sets ragged left against band 2's ragged right, so the two beats
   read as one composition instead of two stacked left-aligned blocks */
.band-1 .band-line{text-align:right}
.band-2 .band-line{text-align:left}
/* one real line per designed break, so the shape never depends on the box width */
.band-line .ln{display:block}

/* Brand colour on the hook: the logo's own blue on "outsmart", its gold on
   "metabolism", with "your" left in the canvas tone between them. */
.band-1 .ln:nth-child(1){color:var(--hero-blue)}
.band-1 .ln:nth-child(3){color:var(--hero-gold)}
/* band 2 answers it with the same pair, in the same order */
.band-2 .ln:nth-child(2){color:var(--hero-blue)}
.band-2 .ln:nth-child(3){color:var(--hero-gold)}

/* split spans */
.band-line .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.band-line .vis{display:block}
.band-line .w{display:inline-block;white-space:nowrap;padding:.06em 0;margin:-.06em 0}
.band-line .c{display:inline-block;will-change:transform,opacity}

/* (a) approach from depth, band 1: grows into place as the camera pushes in */
.band[data-split="depth"] .vis,
.band-1 .vis{
  transform:scale(calc(.84 + .16 * var(--k,1)));
  /* grows from its right edge, the edge the right-aligned text is anchored to */
  transform-origin:100% 50%;
  opacity:var(--k,1);
}
.band-1 .soft{
  position:absolute;inset:0;
  filter:blur(9px);
  opacity:calc(1 - var(--k,1));
  pointer-events:none;
}

/* (e) word by word rise, band 2 */
.band-2 .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.8,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * 26px));
}

/* the fixed identifier, never animates */
.ident{
  position:absolute;right:var(--gut);bottom:2.6rem;margin:0;
  font-family:var(--mono);font-size:.62rem;font-weight:400;
  letter-spacing:.13em;text-transform:uppercase;line-height:1.7;
  color:var(--canvas);
  padding:.55rem .8rem;
  text-align:right;
  max-width:min(34ch,72vw);
}
.ident b{
  display:block;font-weight:700;color:var(--accent);
  letter-spacing:.2em;
}
.chip{
  background:rgba(8,10,14,.55);
  border:1px solid rgba(220,211,196,.26);
  border-radius:10px;
  backdrop-filter:blur(10px);
  text-shadow:0 1px 3px rgba(6,8,12,.85);
}

/* the static hero's copy: hidden while the scrub runs */
.hero-copy{display:none}

/* ---------- below the hero ---------- */

/* The page rides OVER the pinned video for its last screen of hero. main starts
   one viewport early, so at the moment the film reaches its final frame main's
   top edge is exactly at the bottom of the window; scrolling on lifts it up
   across the still-pinned stage. The stage never moves during this, which is
   what makes it read as parallax rather than as the page simply continuing.
   The shadow is what sells it as a layer with an edge, not a hard cut. */
main{
  position:relative;z-index:2;background:var(--canvas);
  /* main must be able to cover the pinned stage completely once it reaches the
     top, or a page shorter than the window leaves a strip of video showing under
     its bottom edge. Irrelevant once the real sections land, but it costs
     nothing and it cannot regress. */
  min-height:100vh;
}
/* The lift and its shadow belong ONLY to a page that has a hero to slide over.
   Applied to every main, the -100vh dragged interior pages clean off the top of
   the screen: the blog rendered as a nav with the footer tucked underneath it.
   Keyed off the adjacent hero rather than a class, so a new page gets the right
   behaviour by virtue of not having one. */
.hero + main{
  margin-top:calc(var(--hero-hold-vh) * -1vh);
  box-shadow:0 -34px 70px -34px rgba(8,10,14,.62);
}

.kicker{
  margin:0 0 1.1rem;
  font-family:var(--mono);font-size:.7rem;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent-text);
}
.kicker::before{
  content:"";display:inline-block;width:26px;height:1px;
  background:var(--accent);vertical-align:middle;margin-right:.7rem;
}

.settle{
  padding:clamp(5rem,13vh,9rem) var(--gut) clamp(4rem,9vh,7rem);
  max-width:1240px;margin:0 auto;
  display:grid;gap:clamp(2.4rem,6vw,5rem);
  grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  align-items:start;
}
@media (max-width:880px){
  .settle{grid-template-columns:1fr;gap:2.8rem;align-items:start}
}
/* The lead line arrives from the LEFT rather than rising like everything else
   on the page, so the first words under the hero move against the grain.
   The wrapper opts out of the shared .reveal lift: without that its translateY
   and this translateX compound and the text drifts in diagonally. */
.settle .settle-lead{opacity:1;transform:none;transition:none}
.settle .settle-lead > *{
  opacity:0;transform:translate3d(-72px,0,0);
  transition:opacity .85s var(--ease-out),transform 1.05s var(--ease-out);
}
.settle.in .settle-lead > *{opacity:1;transform:none}
.settle.in .settle-lead > *:nth-child(2){transition-delay:.12s}
.settle.in .settle-lead > *:nth-child(3){transition-delay:.22s}
.settle.in .settle-lead > *:nth-child(4){transition-delay:.30s}
.settle.in.done .settle-lead > *{transition-delay:0s}

.settle-stat{
  margin:.85rem 0 0;
  max-width:30ch;
  color:var(--ink-soft);
  font-size:clamp(.95rem,1.5vw,1.1rem);line-height:1.5;
}
.settle-stat b{
  color:var(--accent-text);
  font-family:var(--display);font-weight:400;
  font-size:1.28em;letter-spacing:.004em;
}

.settle-h{
  margin:0;
  font-family:var(--display);font-weight:400;
  /* smaller than it was: sharing the row with the offer means it can no longer
     run the full width, and the old clamp overflowed its column */
  font-size:clamp(2.2rem,5.2vw,4.2rem);
  line-height:.96;letter-spacing:.004em;
  max-width:15ch;
  text-wrap:balance;
}

/* Both columns start on the same line. align-items:start on the grid does the
   work, so no rule is needed to declare the alignment. NO CARD, no divider:
   the two blocks simply share a top edge. */
.grab-h{
  margin:0 0 .8rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.85rem,3.6vw,2.85rem);
  line-height:1.02;letter-spacing:.004em;
  max-width:16ch;
}
.grab-h b{color:var(--accent-text);font-weight:400}
.grab-p{
  margin:0 0 1.3rem;
  color:var(--ink-soft);font-size:.95rem;line-height:1.55;max-width:38ch;
}
.grab-note{
  margin:.85rem 0 0;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);
}

.stub{padding:0 var(--gut) clamp(6rem,16vh,11rem);max-width:1240px;margin:0 auto}
.stub-p{margin:0;color:var(--ink-soft);max-width:56ch}

/* ---------- entrances ---------- */

.reveal > *{
  opacity:0;transform:translateY(22px);
  transition:opacity .9s var(--ease-out),transform .9s var(--ease-out);
}
.reveal.in > *{opacity:1;transform:none}
.reveal.in > *:nth-child(1){transition-delay:0ms}
.reveal.in > *:nth-child(2){transition-delay:110ms}
.reveal.in > *:nth-child(3){transition-delay:220ms}
/* retire the stagger so later hovers do not lag; matches the nth-child specificity */
.reveal.in.done > *:nth-child(1),
.reveal.in.done > *:nth-child(2),
.reveal.in.done > *:nth-child(3){transition-delay:0s !important}

/* ---------- short screens: no room for the small overlays ---------- */

@media (max-height:560px){
  .ident,.cue,.ring{display:none}
  .band-1{top:9vh}
  .band-2{bottom:9vh}
}

/* ---------- the five static-hero gates ----------
   These five strings are character for character identical to GATES in hero.js.
   Change one, change both. */

@media (max-width: 720px),
       (orientation: portrait) and (max-width: 1024px),
       (orientation: portrait) and (pointer: coarse),
       (orientation: landscape) and (pointer: coarse) and (max-height: 560px),
       (prefers-reduced-motion: reduce){

  /* No scrub on phones, so the stage has nothing to pin against inside a
     one-screen hero. Pin the hero itself instead: it sticks to the top of the
     window and main (z-index 2, solid canvas) slides up over the still, which
     is the same slide-over as desktop without the pull-up. margin-top stays 0:
     with the hero already pinned, any overlap would only bury it (Chris, 2-3 Sep). */
  .hero{height:100svh;position:sticky;top:0}
  .stage{position:relative;height:100svh}
  /* no lift shadow on phones: the scrim above already darkens the seam */
  .hero + main{margin-top:0;box-shadow:none}
  /* the static hero has its own tuned scrim below; the wash would double it */
  #hero,.ring,.cue,.bands,.wash{display:none}

  .poster{
    background-image:url('../img/hero-ending.jpg');
    background-position:56% 34%;
  }
  .scrim{
    background:
      /* top only, for the nav. The bottom scrim under the copy is gone (3 Sep):
         with the still pinned under main its dark base sat at main's rising edge
         and read as a heavy drop shadow, and the copy carries on its text-shadow. */
      linear-gradient(180deg,rgba(8,10,14,.52) 0%,rgba(8,10,14,.16) 26%,rgba(8,10,14,0) 46%);
  }

  /* CENTRE HIM.
     The 22% bias exists to push him right and clear the left for the desktop
     captions. On a phone the video is cropped hard on both sides instead, and
     that same 22% slides the visible slice so far left that he is almost off
     the right edge: at 375px only an arm survives. Portrait needs no bias at
     all, because the phone copy sits UNDER him rather than beside him.
     Measured across 22/35/50/62/72: 50 is the only one that centres. */
  .poster,#hero{object-position:50% 50%}
  .poster{background-position:50% 42%}

  .hero-copy{
    display:block;
    position:absolute;left:0;bottom:clamp(5.2rem,15vh,8rem);
    margin:0;padding:0 var(--gut);
    max-width:min(22rem,90vw);
    font-family:var(--display);font-weight:400;
    font-size:clamp(2.1rem,9.4vw,3.5rem);
    text-transform:uppercase;
    line-height:1.04;letter-spacing:.035em;
    color:var(--canvas);
    text-shadow:var(--tshadow);
  }
  /* one designed line each, so the phone shape is fixed like the desktop one */
  .hc-l{display:block}
  .hc-gap{margin-top:.5em}
  .hc-blue{color:var(--hero-blue)}
  .hc-gold{color:var(--hero-gold)}
  .ident{right:auto;left:var(--gut);bottom:2.2rem;font-size:.6rem}
}

/* ---------- reduced motion, honoured completely ---------- */

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    transition-delay:0s !important;
    scroll-behavior:auto !important;
  }
  .reveal > *{opacity:1;transform:none}
  .settle .settle-lead > *{opacity:1;transform:none}
  .env-glow{animation:none}
  .motes{display:none}
}

/* pause every animation, including pseudo-elements, on a hidden tab */
body.paused *,
body.paused *::before,
body.paused *::after{animation-play-state:paused !important}

/* ---------- the offer: full-bleed dark band ---------- */

/* Dark, straight after the light settle, so the page changes rooms rather than
   stacking another pale card. It also puts his footage back on screen in the
   grade the hero established. */
.offer{
  position:relative;
  background:var(--deep);
  color:var(--on-deep);
  padding:clamp(4.5rem,11vh,8rem) var(--gut);
  overflow:hidden;
}
/* one living element, whisper level: the same warm light that fills his kitchen */
.offer::before{
  content:"";position:absolute;inset:-30% -10%;pointer-events:none;
  background:radial-gradient(ellipse 46% 40% at 22% 30%,rgba(247,176,58,.10),transparent 66%),
             radial-gradient(ellipse 40% 44% at 84% 76%,rgba(102,155,188,.09),transparent 68%);
  animation:offerglow 74s var(--ease) -18s infinite alternate;
}
@keyframes offerglow{
  from{transform:translate3d(-1.5%,-1%,0) scale(1.02)}
  to{transform:translate3d(2%,1.5%,0) scale(1.07)}
}

.offer-inner{
  position:relative;z-index:1;
  max-width:1240px;margin:0 auto;
  display:grid;gap:clamp(2.2rem,5vw,4.5rem);
  grid-template-columns:minmax(0,1.22fr) minmax(0,1fr);
  /* top aligned, not centred: the film sits level with the kicker instead of
     floating in the middle of whatever height the text happens to be */
  align-items:start;
}
@media (max-width:900px){
  .offer-inner{grid-template-columns:1fr;gap:2.4rem}
}

/* ---- the player ---- */

.vid{margin:0}
.vid-frame{
  position:relative;
  /* one token switches the whole slot between landscape and upright */
  aspect-ratio:var(--vid-ratio,16/9);
  border-radius:4px;overflow:hidden;
  background:#0E1013;
  box-shadow:0 30px 70px -34px rgba(0,0,0,.85);
}
.vid-poster,.vid-frame video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 32%;
}
.vid-frame video{opacity:0;transition:opacity .5s var(--ease)}
.vid-frame.playing video{opacity:1}
.vid-frame.playing .vid-poster,
.vid-frame.playing .vid-play{opacity:0;pointer-events:none}
.vid-poster{transition:opacity .5s var(--ease),transform 1.1s var(--ease)}
.vid-frame:hover .vid-poster{transform:scale(1.02)}

/* a scrim only under the button, so his face stays lit */
.vid-frame::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 46% 40% at 50% 62%,rgba(6,8,12,.52),transparent 74%);
  transition:opacity .5s var(--ease);
}
.vid-frame.playing::after{opacity:0}

.vid-play{
  position:absolute;left:50%;top:58%;transform:translate(-50%,-50%);
  display:inline-flex;align-items:center;gap:.75rem;
  padding:.8rem 1.4rem .8rem .95rem;
  background:rgba(244,240,233,.94);color:var(--deep);
  border:0;border-radius:999px;cursor:pointer;
  font-family:var(--mono);font-weight:700;font-size:.76rem;
  letter-spacing:.1em;text-transform:uppercase;
  transition:transform .4s var(--ease-out),background-color .35s var(--ease),opacity .4s var(--ease);
  will-change:transform;
}
.vid-play svg{width:22px;height:22px;fill:currentColor;flex:0 0 auto}
.vid-play:hover{transform:translate(-50%,-50%) scale(1.05);background:#fff}
.vid-play:active{transform:translate(-50%,-50%) scale(1)}

.vid-cap{
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  margin:.95rem 0 0;
  font-family:var(--mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(244,240,233,.62);
}
.vid-tr-btn{
  background:none;border:0;padding:0;cursor:pointer;
  font:inherit;letter-spacing:inherit;text-transform:inherit;
  color:rgba(244,240,233,.62);
  border-bottom:1px solid rgba(244,240,233,.34);
  transition:color .3s var(--ease),border-color .3s var(--ease);
}
.vid-tr-btn:hover{color:var(--on-deep);border-bottom-color:var(--on-deep)}
.vid-tr{
  margin-top:1.1rem;padding-top:1.1rem;
  border-top:1px solid rgba(244,240,233,.16);
  font-size:.95rem;line-height:1.65;color:rgba(244,240,233,.8);
  max-width:62ch;
}
.vid-tr p{margin:0 0 .85rem}
.vid-tr p:last-child{margin-bottom:0}

/* ---- the text column ---- */

.offer .kicker{color:var(--accent)}
.offer .kicker::before{background:var(--accent)}

.offer-h{
  margin:0 0 1.4rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(2.1rem,4.6vw,3.5rem);
  line-height:.98;letter-spacing:.004em;
  /* the hero's blue, carried down so the section's headline answers the hook */
  color:var(--hero-blue);
}
.offer-p{
  margin:0 0 1.1rem;
  color:rgba(244,240,233,.82);
  max-width:54ch;
}

/* NO CARDS. A boxed grid here is the single most recognisable tell of a
   generated page, so these sit straight on the band under one hairline rule,
   baseline aligned, separated by space rather than by borders. */
.proof{
  list-style:none;margin:0 0 2.2rem;padding:1.15rem 0 0;
  border-top:1px solid rgba(244,240,233,.2);
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1rem 2rem;
}
.proof li{display:flex;flex-direction:column;gap:.22rem}
.proof-k{
  font-family:var(--mono);font-size:.6rem;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);
}
.proof-v{font-size:.9rem;color:rgba(244,240,233,.86);line-height:1.3}

.offer-cta{font-size:.8rem;padding:.95rem 1.6rem}

/* entrance: the column parts arrive in sequence, retired afterwards */
.reveal .vid-frame,.reveal .vid-cap,
.offer-text.reveal > *{
  opacity:0;transform:translateY(18px);
  transition:opacity .8s var(--ease-out),transform .8s var(--ease-out);
}
.reveal.in .vid-frame,.reveal.in .vid-cap,
.offer-text.reveal.in > *{opacity:1;transform:none}
.offer-text.reveal.in > *:nth-child(1){transition-delay:.04s}
.offer-text.reveal.in > *:nth-child(2){transition-delay:.12s}
.offer-text.reveal.in > *:nth-child(3){transition-delay:.20s}
.offer-text.reveal.in > *:nth-child(4){transition-delay:.28s}
.offer-text.reveal.in > *:nth-child(5){transition-delay:.36s}
.offer-text.reveal.in > *:nth-child(6){transition-delay:.44s}
.offer-text.reveal.in > *:nth-child(7){transition-delay:.52s}
.offer-text.reveal.in > *:nth-child(8){transition-delay:.60s}
.reveal.in .vid-cap{transition-delay:.22s}
/* retire the delays, matching the nth-child specificity, or every later hover lags */
.offer-text.reveal.done > *:nth-child(n){transition-delay:0s}
.reveal.done .vid-cap{transition-delay:0s}

@media (prefers-reduced-motion: reduce){
  .offer::before{animation:none}
  .reveal .vid-frame,.reveal .vid-cap,.offer-text.reveal > *{opacity:1;transform:none}
}

/* the honest state when the clip is not there yet */
.vid-note{
  position:absolute;left:50%;bottom:1.1rem;transform:translateX(-50%);
  margin:0;padding:.5rem .9rem;
  background:rgba(6,8,12,.72);border-radius:2px;
  font-family:var(--mono);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
  color:rgba(244,240,233,.86);white-space:nowrap;
}

/* ---- the three key points: what you actually get ---- */

/* Each point hangs off a short gold rule, which is the layer motif reading
   downward, so the list looks like the method rather than like bullets. */
.keys{
  list-style:none;margin:0 0 1.8rem;padding:0;
  display:flex;flex-direction:column;gap:1.15rem;
}
.keys li{
  position:relative;
  padding-left:1.5rem;
}
.keys li::before{
  content:"";position:absolute;left:0;top:.52em;
  width:.72rem;height:2px;background:var(--accent);
  transform-origin:0 50%;
}
.keys-h{
  display:block;
  font-family:var(--mono);font-weight:700;font-size:.72rem;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-deep);
  margin-bottom:.3rem;
}
.keys-p{
  display:block;
  color:rgba(244,240,233,.74);
  font-size:.96rem;line-height:1.58;
  max-width:46ch;
}


/* The pending marker. Deliberately quiet: the frame already looks like a film
   waiting to play, and this only tells the owner which slot is still open.
   Removing data-pending in the markup hides it and arms the real player. */
.vid-pending{
  position:absolute;left:0;bottom:0;margin:0;
  padding:.42rem .8rem;
  background:rgba(6,8,12,.78);
  color:rgba(244,240,233,.9);
  font-family:var(--mono);font-size:.6rem;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;
}
.vid-frame:not([data-pending="true"]) .vid-pending{display:none}

/* the play pill on narrow screens: never let its label break to two lines */
.vid-play-t{white-space:nowrap}
@media (max-width:560px){
  .vid-play{padding:.62rem 1rem .62rem .78rem;gap:.5rem;font-size:.66rem}
  .vid-play svg{width:18px;height:18px}
  .vid-cap{font-size:.62rem}
}

/* ---- the offer, re-laid: credentials under the film, CTA under the copy ---- */

/* the credential strip now sits in the left column, so it gets the film's width
   and a rule that reads as the film's baseline rather than a floating divider */
.offer-media .proof{
  margin:1.6rem 0 0;
  padding-top:1.25rem;
}
.offer-act{
  margin-top:2.2rem;
  text-align:center;   /* .btn is inline-flex, so this centres it in the column */
}
/* the transcript, when opened, should not shove the credentials sideways */
.offer-media .vid-tr{max-width:none}

/* ---------- the book and the app ---------- */

/* Light canvas straight after the dark offer, and a different skeleton: the offer
   is one wide media block beside one text block, this is two equal siblings split
   by a rule. Neighbouring sections must not read as the same template twice. */
.pair{
  padding:clamp(4.5rem,11vh,8rem) var(--gut);
  background:var(--canvas);
}
.pair-inner{
  max-width:1240px;margin:0 auto;
  display:grid;grid-template-columns:1fr 1px 1fr;
  gap:0 clamp(2.2rem,5vw,4.5rem);
  align-items:start;
}
/* the divider is the middle grid track, so it stretches to the taller column */
.pair-inner::before{
  content:"";grid-column:2;grid-row:1;
  background:var(--hairline);
  justify-self:center;width:1px;height:100%;
}
@media (max-width:820px){
  .pair-inner{grid-template-columns:1fr;gap:3.4rem}
  .pair-inner::before{display:none}
  .pair-col-next{padding-top:3.4rem;border-top:1px solid var(--hairline)}
}

.pair-col{grid-row:1}
.pair-col:first-of-type{grid-column:1}
.pair-col-next{grid-column:3}
@media (max-width:820px){
  .pair-col:first-of-type,.pair-col-next{grid-column:1}
  .pair-col-next{grid-row:auto}
}

.pair-h{
  margin:0 0 1.4rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.9rem,3.9vw,2.9rem);
  line-height:.98;letter-spacing:.004em;
  color:var(--ink);
}
.pair-sub{
  display:block;margin-top:.5rem;
  font-family:var(--mono);font-size:.66rem;font-weight:700;
  letter-spacing:.2em;text-transform:uppercase;
  color:var(--accent-text);
}
.pair-cover{
  width:100%;height:auto;
  margin:0;
  border-radius:2px;
  box-shadow:0 22px 44px -22px rgba(29,33,38,.5);
  transition:transform .7s var(--ease-out);
}
.pair-col:hover .pair-cover{transform:translateY(-4px)}
.pair-p{
  margin:0 0 1rem;
  color:var(--ink-soft);
  max-width:44ch;
}
.pair-words .pair-p:last-child{margin-bottom:0}



/* the visual beside its words, not above them. The cover is a fixed measure so
   the text column keeps a readable line length instead of being squeezed by a
   percentage that shrinks with the section. */
.pair-body{
  display:grid;
  grid-template-columns:clamp(118px,30%,168px) 1fr;
  gap:clamp(1rem,2.2vw,1.6rem);
  align-items:start;
  margin:0 0 1.7rem;
}
.pair-words .pair-p{max-width:none}
/* under about 420px the two-up gets too tight for either half */
@media (max-width:420px){
  .pair-body{grid-template-columns:1fr;gap:1.3rem}
  .pair-cover,.pair-slot{width:min(190px,58%)}
}

/* the app's reserved space: a drawn frame, never an empty hole */
.pair-slot{
  aspect-ratio:232/340;
  width:100%;
  margin:0;
  border:1px dashed var(--rule);
  border-radius:2px;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(150deg,rgba(247,176,58,.05),rgba(47,95,125,.05));
}
.pair-slot svg{width:78%;height:auto}

/* the outlined button: secondary to the amber one, still 3:1 on its border */
.btn-line{
  background:transparent;color:var(--ink);
  border:1px solid var(--rule);
}
.btn-line:hover{background:var(--ink);color:var(--canvas);border-color:var(--ink);transform:translateY(-2px)}

.pair-col.reveal > *{
  opacity:0;transform:translateY(16px);
  transition:opacity .8s var(--ease-out),transform .8s var(--ease-out);
}
.pair-col.reveal.in > *{opacity:1;transform:none}
.pair-col.reveal.in > *:nth-child(1){transition-delay:.04s}
.pair-col.reveal.in > *:nth-child(2){transition-delay:.12s}
.pair-col.reveal.in > *:nth-child(3){transition-delay:.20s}
.pair-col.reveal.in > *:nth-child(4){transition-delay:.28s}
.pair-col.reveal.in > *:nth-child(5){transition-delay:.36s}
.pair-col.reveal.in > *:nth-child(6){transition-delay:.44s}
.pair-col.reveal.done > *:nth-child(n){transition-delay:0s}
@media (prefers-reduced-motion: reduce){
  .pair-col.reveal > *{opacity:1;transform:none}
  .pair-cover{transition:none}
}

/* ===================================================================
   THE PROGRESS GALLERY
   A dark band deliberately identical to .offer. It sits after the light
   book/app pair, so the page alternates dark, light, dark, and the two dark
   bands read as the same voice returning rather than as one long slab.
   The track is padded to the gutter rather than centred: the photos must line
   up under the heading, not float away from it.
   =================================================================== */

.prog{
  position:relative;
  background:var(--deep);
  color:var(--on-deep);
  padding:clamp(4.5rem,11vh,8rem) 0 clamp(3.5rem,8vh,6rem);
  overflow:hidden;
}
/* The plate section's glow, mirrored top to bottom: the gold blob that sits
   low on the left of the plate carries on at the top left here, the blue one
   at the lower right, and nothing drifts, so the seam between the two dark
   bands disappears (Chris, 2 Sep 2026). It used to be the coaching band's
   animated warm/cool swap; that only mattered when they shared a page. */
.prog::before{
  content:"";position:absolute;inset:-30% -10%;pointer-events:none;
  background:radial-gradient(ellipse 40% 44% at 18% 24%,rgba(247,176,58,.07),transparent 68%),
             radial-gradient(ellipse 44% 40% at 70% 60%,rgba(102,155,188,.10),transparent 66%);
}

.prog-head{
  /* a grid cell now: the width cap and gutter live on .prog-inner instead,
     and repeating them here would indent the text a second time */
  position:relative;z-index:1;
}
.prog-head .kicker{color:var(--accent)}
.prog-head .kicker::before{background:var(--accent)}
.prog-h{
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.9rem,4.6vw,3.1rem);
  /* Set in caps, so it needs the opposite of the offer heading's settings.
     All-caps has no descenders to cut a gap between lines, so .98 let the rows
     touch; and negative tracking on a face this condensed closes the counters
     until the words read as one block. Both are opened up here. */
  line-height:1.09;letter-spacing:.015em;text-transform:uppercase;
  margin:.5rem 0 1.1rem;max-width:18ch;
}
/* Two small tints used inside dark-band headings: the hero's blue to carry the
   brand onto one phrase, and the plain canvas to take it back off again. Kept
   generic rather than scoped, because both bands need both. */
.tint-blue{color:var(--hero-blue)}
.tint-plain{color:var(--on-deep)}

.prog-note{
  max-width:52ch;color:rgba(244,240,233,.72);
  font-size:clamp(.95rem,1.5vw,1.05rem);line-height:1.6;margin:0;
}

/* ---- two columns: the words on the left, the evidence on the right ---- */

.prog-inner{
  position:relative;z-index:1;
  max-width:1240px;margin:0 auto;padding:0 var(--gut);
  display:grid;gap:clamp(2rem,5vw,4rem);
  grid-template-columns:minmax(0,1fr) minmax(0,1.08fr);
  align-items:center;
}
@media (max-width:900px){
  .prog-inner{grid-template-columns:1fr;gap:2.4rem}
}

/* ---- the polaroids ----
   Real Polaroid geometry: a narrow even border on three sides and a deep chin
   at the bottom. Built in CSS rather than baked into the JPEGs so the frame
   stays crisp at any size and the caption is real text, not pixels.

   Where each one lands is defined HERE. The script only interpolates between
   the off-screen start and this rest state; it never decides positions. */

.polys{position:relative;aspect-ratio:1/0.95}
@media (max-width:900px){ .polys{aspect-ratio:1/1.06} }

.poly{
  position:absolute;margin:0;
  left:var(--l);top:var(--t);
  width:46%;
  background:#F8F6F1;
  /* Real Polaroid geometry, from the reference: a thin even border on three
     sides and a chin four times deeper at the bottom. Getting this backwards
     is what makes a CSS "polaroid" read as a generic white picture frame.
     NOTE: percentage padding resolves against the CONTAINING BLOCK width, not
     the card, so these are the card's 5.7% and 25.7% multiplied by its own
     46% width. Retune both if that width changes. */
  padding:2.6% 2.6% 0;
  border-radius:2px;
  box-shadow:0 1px 0 rgba(255,255,255,.5) inset,
             0 30px 60px -20px rgba(0,0,0,.95),
             0 6px 16px -6px rgba(0,0,0,.6);
  will-change:transform,opacity;
}
.poly img{
  /* height:auto is load bearing. The <img> carries height="1200" as an
     attribute, which acts as a presentational hint and beats aspect-ratio, so
     without this every photo renders 1200px tall and bursts out of the band. */
  width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;display:block;
  background:#0E1013;
}
/* the chin. 29% of the CONTENT box, which works out to the real thing's 25.7%
   of overall card width. This is the single feature that says Polaroid. */
.poly figcaption{
  height:0;padding-bottom:29%;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;
  color:#4A4640;
}

/* A cascade down and to the right, each photo landing LOWER than the last.
   With the newest on top, stepping down means each one covers only the body of
   the one beneath it, never the face. An earlier version put the last photo
   highest and it buried the middle man's head. */
.polys .poly:nth-child(1){--l:0%;  --t:0%;  --rot:-6deg;  --fx:52vw; --fy:-5vh; z-index:1}
.polys .poly:nth-child(2){--l:26%; --t:10%; --rot:4.5deg; --fx:66vw; --fy:0vh;  z-index:2}
.polys .poly:nth-child(3){--l:52%; --t:20%; --rot:-3deg;  --fx:80vw; --fy:5vh;  z-index:3}

@media (max-width:900px){
  .polys .poly:nth-child(1){--l:0%;  --t:0%;  --fx:70vw}
  .polys .poly:nth-child(2){--l:27%; --t:11%; --fx:84vw}
  .polys .poly:nth-child(3){--l:54%; --t:22%; --fx:96vw}
}

@media (prefers-reduced-motion:reduce){
  .prog::before{animation:none}
  /* no flight: the photos are simply already where they land */
  .poly{transform:rotate(var(--rot))!important;opacity:1!important}
}

/* ===================================================================
   THE NUMBERS
   Calculators left, the adaptation curve right. Light canvas, so it breaks
   the two dark bands either side of it.
   NO CARDS: fields are underlines on the page and results sit under hairlines,
   the same editorial furniture the rest of the site uses.
   =================================================================== */

.calc{
  background:var(--canvas);
  padding:clamp(4.5rem,11vh,8rem) var(--gut);
}
.calc-inner{
  max-width:1240px;margin:0 auto;
  display:grid;gap:clamp(1.4rem,2.4vw,2rem);
  grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  /* stretch, not start: the two panels are a matched pair and unequal heights
     were most of what made this section feel adrift */
  align-items:stretch;
}
@media (max-width:980px){ .calc-inner{grid-template-columns:1fr;gap:1.4rem} }

/* ---- the panels ----
   Cards, against the rule used everywhere else on this site, because two
   instruments side by side need a stated edge. Kept off the usual tells:
   a 3px radius rather than a fat one, a hairline instead of a heavy stroke,
   one soft shadow rather than a floating slab, and paper-on-paper colour so
   they read as a sheet laid on the canvas, not a widget dropped on it. */
.calc-col{
  background:#FBF9F5;
  border:1px solid var(--hairline);
  border-radius:3px;
  padding:clamp(1.6rem,2.8vw,2.4rem);
  box-shadow:0 1px 0 rgba(255,255,255,.7) inset,
             0 18px 40px -28px rgba(29,33,38,.45);
}

.calc-h,.chart-h{
  margin:.5rem 0 .8rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.8rem,3.4vw,2.6rem);
  line-height:1.02;letter-spacing:.004em;
  max-width:18ch;
}
.calc-lead{margin:0 0 1.6rem;color:var(--ink-soft);max-width:46ch;line-height:1.6}
.calc-note{
  margin:1rem 0 0;font-family:var(--mono);font-size:.56rem;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-soft);
}

/* ---- units toggle ---- */
.calc-units{display:flex;gap:0;margin-bottom:1.4rem}
.unit{
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;
  background:transparent;color:var(--ink-soft);
  border:1px solid var(--rule);border-right-width:0;
  padding:.5rem .9rem;cursor:pointer;
  transition:background-color .3s var(--ease),color .3s var(--ease);
}
.unit:last-child{border-right-width:1px}
.unit:hover{color:var(--ink)}
.unit.on{background:var(--ink);color:var(--canvas);border-color:var(--ink)}

/* ---- fields ---- */
.calc-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.1rem 1.4rem}
.field-wide{grid-column:1 / -1}
.field label{
  display:block;margin-bottom:.35rem;
  font-family:var(--mono);font-size:.6rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);
}
.field input,.field select{
  width:100%;
  font-family:var(--body);font-size:1rem;color:var(--ink);
  background:transparent;
  border:0;border-bottom:1px solid var(--rule);
  border-radius:0;padding:.42rem 0;
  transition:border-color .3s var(--ease);
}
.field input:focus,.field select:focus{outline:0;border-bottom-color:var(--accent);border-bottom-width:2px}
.field select{appearance:none;cursor:pointer}
.pair-in{display:flex;align-items:baseline;gap:.5rem}
.pair-in input{flex:1 1 auto;min-width:0}
.pair-in span{
  flex:0 0 auto;font-family:var(--mono);font-size:.62rem;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft);
}

/* ---- results ---- */
.calc-out{margin:2rem 0 0;padding:0;display:grid;gap:1.15rem}
.calc-out > div{border-top:1px solid var(--hairline);padding-top:.85rem}
.calc-out dt{
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);
}
.calc-out dd{
  margin:.15rem 0 .2rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.6rem,3vw,2.2rem);line-height:1;
  letter-spacing:.004em;color:var(--ink);
}
.calc-out dd b{font-family:var(--mono);font-size:.7rem;font-weight:700;letter-spacing:.12em;color:var(--ink-soft)}
.calc-out p{margin:0;color:var(--ink-soft);font-size:.88rem;line-height:1.5;max-width:44ch}

/* ---- the deficit slider ---- */
.slider-l{
  display:block;margin:0 0 .6rem;
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);
}
.slider-l b{color:var(--accent-text);font-size:.78rem}
.slider{
  -webkit-appearance:none;appearance:none;
  width:100%;height:2px;background:var(--rule);
  margin:0 0 1.6rem;cursor:pointer;
}
.slider::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:20px;height:20px;border-radius:50%;
  background:var(--accent);border:2px solid var(--canvas);
  box-shadow:0 2px 10px -2px rgba(138,90,8,.8);cursor:grab;
}
.slider::-moz-range-thumb{
  width:20px;height:20px;border-radius:50%;
  background:var(--accent);border:2px solid var(--canvas);cursor:grab;
}
.slider:focus-visible{outline:3px solid var(--accent);outline-offset:8px}

/* ---- the curve ---- */
.curve{width:100%;height:auto;display:block}
.curve .grid line{stroke:var(--hairline);stroke-width:1}
.curve .line-naive{
  fill:none;stroke:var(--ink-soft);stroke-width:2;
  stroke-dasharray:5 5;opacity:.75;
}
.curve .line-real{
  fill:none;stroke:var(--accent);stroke-width:3;
  stroke-linecap:round;stroke-linejoin:round;
}
.curve .dot{fill:var(--accent);stroke:var(--canvas);stroke-width:2}

.curve-key{display:flex;gap:1.4rem;margin:.7rem 0 1rem;flex-wrap:wrap}
.k{
  font-family:var(--mono);font-size:.58rem;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-soft);
  display:flex;align-items:center;gap:.5rem;
}
.k::before{content:"";width:18px;height:2px;background:currentColor}
.k-naive::before{background:var(--ink-soft)}
.k-real{color:var(--accent-text)}
.k-real::before{background:var(--accent);height:3px}

.curve-out{
  margin:0;color:var(--ink-soft);line-height:1.6;max-width:46ch;min-height:3em;
}
.curve-out b{color:var(--ink);font-weight:600}

@media (prefers-reduced-motion:reduce){
  .curve .line-real,.curve .line-naive,.curve .dot{transition:none}
}

/* ===================================================================
   FOOTER
   The dark band returns one last time to close the page.
   =================================================================== */

.foot{
  position:relative;z-index:2;
  background:var(--deep);
  color:var(--on-deep);
  padding:clamp(3.5rem,8vh,5.5rem) var(--gut) clamp(1.6rem,3vh,2.2rem);
}
.foot-inner{max-width:1240px;margin:0 auto}

.foot-inner{
  display:grid;gap:clamp(2rem,4vw,3.4rem);
  grid-template-columns:minmax(0,1.1fr) minmax(0,1.5fr);
}
@media (max-width:820px){ .foot-inner{grid-template-columns:1fr;gap:2.4rem} }

.foot-logo{
  width:clamp(140px,15vw,186px);height:auto;display:block;
  margin-bottom:1.1rem;
}
.foot-line{
  margin:0;max-width:34ch;
  color:rgba(244,240,233,.62);
  font-size:.92rem;line-height:1.6;
}

.foot-nav{
  display:grid;gap:clamp(1.4rem,3vw,2.6rem);
  grid-template-columns:repeat(3,minmax(0,1fr));
}
@media (max-width:520px){ .foot-nav{grid-template-columns:repeat(2,minmax(0,1fr))} }

.foot-h{
  margin:0 0 .8rem;
  font-family:var(--mono);font-size:.6rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);
}
.foot-col ul{list-style:none;margin:0;padding:0;display:grid;gap:.5rem}
.foot-col a{
  color:rgba(244,240,233,.78);
  text-decoration:none;font-size:.94rem;
  /* an underline that grows rather than appears, so the hover is a movement
     and not a flicker */
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px;background-repeat:no-repeat;background-position:0 100%;
  transition:color .3s var(--ease),background-size .35s var(--ease);
  padding-bottom:2px;
}
.foot-col a:hover{color:var(--on-deep);background-size:100% 1px}
.foot-col a:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
.ext{font-size:.72em;margin-left:.3em;opacity:.7}

.foot-med{
  grid-column:2;
  margin:clamp(1.6rem,4vh,2.4rem) 0 0;
  padding-top:1.4rem;
  border-top:1px solid rgba(244,240,233,.14);
  max-width:82ch;
  color:rgba(244,240,233,.5);
  font-size:.82rem;line-height:1.6;
}

.foot-base{
  grid-column:1 / -1;
  margin-top:1.4rem;padding-top:1.2rem;
  border-top:1px solid rgba(244,240,233,.14);
  display:flex;flex-wrap:wrap;gap:.8rem 1.6rem;
  align-items:baseline;justify-content:space-between;
}
.foot-cr{
  margin:0;line-height:1.9;   /* two lines now: the entity, then the copyright */
  font-family:var(--mono);font-size:.58rem;
  letter-spacing:.13em;text-transform:uppercase;
  color:rgba(244,240,233,.42);
}
.foot-legal{
  list-style:none;margin:0;padding:0;
  display:flex;gap:1.4rem;
}
.foot-legal a{
  font-family:var(--mono);font-size:.58rem;
  letter-spacing:.13em;text-transform:uppercase;
  color:rgba(244,240,233,.42);text-decoration:none;
  transition:color .3s var(--ease);
}
.foot-legal a:hover{color:var(--on-deep)}
.foot-legal a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* the social row, shared with the book site so both properties point at one
   set of accounts */
.foot-social{
  grid-column:1 / -1;
  list-style:none;margin:clamp(1.6rem,4vh,2.4rem) 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:.55rem;
}
.foot-social a{
  display:grid;place-items:center;
  width:40px;height:40px;
  border:1px solid rgba(244,240,233,.18);
  border-radius:50%;
  color:rgba(244,240,233,.7);
  transition:color .3s var(--ease),border-color .3s var(--ease),
             background-color .3s var(--ease),transform .3s var(--ease-out);
}
.foot-social svg{width:17px;height:17px;fill:currentColor;display:block}
.foot-social a:hover{
  color:var(--deep);background:var(--accent);border-color:var(--accent);
  transform:translateY(-2px);
}
.foot-social a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* ---- nav links ----
   They sit over the hero video before the bar sticks, so they carry the same
   drop shadow the logo uses, then drop it and go dark once the bar turns
   opaque. Without that they vanish over the bright countertop. */
.nav-links{
  list-style:none;margin:0 0 0 auto;padding:0;
  display:flex;align-items:center;
  gap:clamp(1rem,2.2vw,2.1rem);
}
.nav-links a{
  font-family:var(--mono);font-size:.68rem;font-weight:700;
  letter-spacing:.15em;text-transform:uppercase;
  color:var(--canvas);text-decoration:none;
  text-shadow:0 1px 6px rgba(8,10,14,.6);
  padding:.3rem 0;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1.5px;background-repeat:no-repeat;background-position:0 100%;
  transition:color .4s var(--ease),background-size .35s var(--ease),text-shadow .4s var(--ease);
}
.nav-links a:hover{background-size:100% 1.5px}
.nav-links a:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:2px}
.nav.stuck .nav-links a{color:var(--ink);text-shadow:none}

/* ---- mobile menu ----
   Below 820px the link list folds into a panel hung under the bar, opened by
   the three-line button at the right edge (hero.js toggles .open on .nav).
   The bar goes opaque while the panel is open so the links read over the
   hero film. Above 820px the button is gone and none of this applies. */
.nav-toggle{display:none}
@media (max-width:820px){
  .nav-toggle{
    display:flex;flex-direction:column;justify-content:center;gap:5px;
    flex:0 0 auto;width:44px;height:44px;margin:0 -10px 0 .2rem;padding:0;
    background:none;border:0;cursor:pointer;
  }
  .nav-toggle span,.nav-toggle::before,.nav-toggle::after{
    content:'';display:block;width:22px;height:2px;margin:0 auto;
    background:var(--canvas);box-shadow:0 1px 4px rgba(8,10,14,.5);
    transition:transform .3s var(--ease),opacity .3s var(--ease),background-color .4s var(--ease);
  }
  .nav.stuck .nav-toggle span,.nav.stuck .nav-toggle::before,.nav.stuck .nav-toggle::after,
  .nav.open .nav-toggle span,.nav.open .nav-toggle::before,.nav.open .nav-toggle::after{background:var(--ink);box-shadow:none}
  .nav.open .nav-toggle span{opacity:0}
  .nav.open .nav-toggle::before{transform:translateY(7px) rotate(45deg)}
  .nav.open .nav-toggle::after{transform:translateY(-7px) rotate(-45deg)}
  .nav-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

  .nav-links{
    display:none;
    position:absolute;top:100%;left:0;right:0;
    flex-direction:column;align-items:stretch;gap:0;
    padding:.2rem var(--gut) .6rem;
    background:var(--canvas);border-bottom:1px solid var(--hairline);
    box-shadow:0 18px 40px -20px rgba(8,10,14,.35);
  }
  .nav.open .nav-links{display:flex}
  .nav.open{background:rgba(244,240,233,.96);border-bottom-color:var(--hairline)}
  .nav.open .nav-logo img{filter:none}
  .nav-links a{
    display:block;padding:.95rem 0;font-size:.78rem;
    color:var(--ink);text-shadow:none;border-bottom:1px solid var(--hairline);
    background-image:none;
  }
  .nav-links li:last-child a{border-bottom:0}
}

/* the footer grew a fourth column */
/* Contact was removed from the footer, so this is three columns now, not
   four - a reserved fourth column just squeezed the other three left. */
.foot-nav{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:900px){ .foot-nav{grid-template-columns:repeat(2,minmax(0,1fr))} }

/* The address is longer than the column it sits in. Let it break rather than
   run off the edge, and drop it a size so it usually does not have to. */
.foot-col a[href^="mailto:"]{
  font-size:.86rem;
  overflow-wrap:anywhere;
}

/* ===================================================================
   PHONES
   Two fixes the desktop layout does not need.

   1. TAP TARGETS. Apple and Google both want 44px; the form controls were
      landing at 31 to 34, and the transcript button at 17. A 17px target is
      a coin flip with a thumb.
   2. MICRO TEXT. The mono labels are set in rem fractions that compute to
      9 and 10px. That is fine on a desk and unreadable on a phone at arm's
      length, so the floor is raised here rather than everywhere.
   =================================================================== */
@media (max-width:820px){

  /* --- form controls to a real thumb size --- */
  .field input,.field select{
    padding:.72rem 0;
    /* 16px minimum, or iOS zooms the whole page in on focus and the visitor
       has to pinch back out to carry on */
    font-size:16px;
    min-height:44px;
  }
  .unit{padding:.8rem 1rem;min-height:44px}

  /* height as two tiny boxes side by side is unusable at 375px, so it gets
     its own row and the feet/inches pair can breathe */
  .calc-grid{grid-template-columns:1fr}

  /* the slider track is 2px, which is a 2px target. Pad the control out to a
     grabbable band without changing how it looks. */
  .slider{
    height:44px;background:transparent;
    /* the visible 2px line is painted by the track pseudo-elements instead */
  }
  .slider::-webkit-slider-runnable-track{height:2px;background:var(--rule)}
  .slider::-moz-range-track{height:2px;background:var(--rule)}
  .slider::-webkit-slider-thumb{margin-top:-11px;width:24px;height:24px}
  .slider::-moz-range-thumb{width:24px;height:24px}

  .vid-tr-btn{padding:.85rem 0;min-height:44px}
  .vid-play{min-height:48px}

  /* --- lift the smallest labels off the floor --- */
  .kicker{font-size:.78rem}
  .calc-note,.grab-note,.k,.foot-cr,.foot-legal a,.flow-hint,.scatter-hint{font-size:.68rem}
  .poly figcaption{font-size:.68rem}
  .proof-k,.foot-h,.field label,.slider-l{font-size:.7rem}
  .ident{font-size:.68rem}
  .calc-out dt{font-size:.7rem}
  .foot-col a{font-size:1rem;padding:.72rem 0;display:inline-block}
  .foot-col ul{gap:0}
  .foot-legal{gap:1.6rem}
  .foot-legal a{padding:.75rem 0;display:inline-block}
  /* 40px circles are just under the line; 44 is the line */
  .foot-social a{width:44px;height:44px}
  .foot-social{gap:.6rem}
}

/* ---- tooltips on the acronyms ----
   They sit on BMR / TDEE / BMI where the reader first meets the words, not
   down on the results. That is where someone looks when a term is unfamiliar.

   A real <button>, not a hover-only span: hover is invisible to a phone and
   unreachable by keyboard, and these carry the actual explanation. */
.calc-lead-tips{position:relative}

.tip-btn{
  display:inline-grid;place-items:center;
  width:17px;height:17px;margin-left:.24rem;
  transform:translateY(-1px);
  font-family:var(--mono);font-size:.6rem;font-weight:700;line-height:1;
  color:var(--accent-text);
  background:transparent;border:1px solid var(--rule);border-radius:50%;
  cursor:pointer;padding:0;
  transition:background-color .25s var(--ease),color .25s var(--ease),border-color .25s var(--ease);
}
.tip-btn:hover,.tip-btn[aria-expanded="true"]{
  background:var(--accent);border-color:var(--accent);color:var(--deep);
}
.tip-btn:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* a <span>, not a <div>: a div inside a <p> makes the browser close the
   paragraph early and the layout falls apart */
.tip{
  display:block;
  position:absolute;z-index:5;
  top:calc(100% + .5rem);left:0;right:0;
  background:var(--deep);color:rgba(244,240,233,.88);
  border-radius:4px;padding:.85rem .95rem;
  font-size:.84rem;line-height:1.5;
  box-shadow:0 20px 44px -18px rgba(0,0,0,.75);
}
.tip[hidden]{display:none}
.tip b{color:var(--on-deep);font-weight:600}

@media (max-width:820px){
  .tip-btn{width:24px;height:24px;font-size:.68rem;margin-left:.3rem;position:relative}
  /* the circle stays 24px; the finger target grows to 44px around it */
  .tip-btn::before{content:"";position:absolute;inset:-10px}
  .tip{font-size:.9rem}
}

/* ===================================================================
   INTERIOR PAGE HEADER
   A type-only band, not a hero. On the homepage the video earns its screen
   because a first impression is the job. Here the job is reading, and a
   banner would push the reason people came below the fold.
   =================================================================== */

.pagehead{
  position:relative;z-index:2;
  background:var(--deep);color:var(--on-deep);
  /* clears the fixed nav, which sits over the top of every page */
  padding:calc(clamp(4.5rem,11vh,7rem) + 3.5rem) var(--gut) clamp(3rem,7vh,4.5rem);
  overflow:hidden;
}
/* the same slow warm/cool drift as the dark bands on the homepage */
.pagehead::before{
  content:"";position:absolute;inset:-30% -10%;pointer-events:none;
  background:radial-gradient(ellipse 46% 40% at 24% 28%,rgba(247,176,58,.10),transparent 66%),
             radial-gradient(ellipse 40% 44% at 82% 74%,rgba(102,155,188,.09),transparent 68%);
  animation:offerglow 74s var(--ease) -30s infinite alternate;
}
.pagehead-in{position:relative;z-index:1;max-width:1240px;margin:0 auto}
.pagehead .kicker{color:var(--accent)}
.pagehead .kicker::before{background:var(--accent)}
.pagehead-h{
  margin:.5rem 0 1rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(2.1rem,5.4vw,4rem);
  line-height:.99;letter-spacing:.004em;
  max-width:18ch;
}
.pagehead-p{
  margin:0;max-width:54ch;
  color:rgba(244,240,233,.72);
  font-size:clamp(1rem,1.6vw,1.12rem);line-height:1.6;
}

/* ---- the post list ----
   NO CARDS. Entries are separated by hairlines, the way a contents page works,
   so the titles carry the page instead of a grid of boxes. */
.posts{background:var(--canvas);padding:clamp(3rem,7vh,5rem) var(--gut) clamp(4rem,10vh,7rem)}
.posts-in{max-width:1240px;margin:0 auto}

.post + .post{border-top:1px solid var(--hairline)}
.post-link{
  display:block;text-decoration:none;color:inherit;
  padding:clamp(1.6rem,3.4vw,2.4rem) 0;
  transition:opacity .3s var(--ease);
}
.post-date{
  display:block;
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);
}
.post-h{
  margin:.5rem 0 .6rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.5rem,3.4vw,2.5rem);
  line-height:1.04;letter-spacing:.004em;
  max-width:24ch;color:var(--ink);
  /* the underline grows on hover instead of blinking on */
  background-image:linear-gradient(var(--accent),var(--accent));
  background-size:0% 3px;background-repeat:no-repeat;background-position:0 100%;
  transition:background-size .45s var(--ease);
  display:inline;
}
.post-link:hover .post-h,
.post-link:focus-visible .post-h{background-size:100% 3px}
.post-x{margin:.8rem 0 .9rem;color:var(--ink-soft);max-width:62ch;line-height:1.6}
.post-more{
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);
}
.post-link:focus-visible{outline:3px solid var(--accent);outline-offset:6px;border-radius:3px}

/* ---- the supplement glossary ----
   Reference material, so it is built to be scanned and Cmd+F'd, not clicked
   through. A <dl>, hairline separated like the post list. NO CARDS. */
.gloss{background:var(--canvas);padding:clamp(3rem,7vh,5rem) var(--gut) clamp(4rem,10vh,7rem)}
.gloss-in{max-width:1240px;margin:0 auto}

.gloss-lede{max-width:64ch;margin:0 0 clamp(2rem,4vw,3rem)}
.gloss-lede p{margin:0 0 1rem;color:var(--ink-soft);line-height:1.65;font-size:clamp(1rem,1.5vw,1.08rem)}
.gloss-lede b{color:var(--ink);font-weight:600}
.gloss-lede-note{
  border-left:3px solid var(--accent);padding-left:1.1rem;
  font-size:.94rem !important;
}

/* ---- filter block ----
   Sticky as one unit so search, verdicts and letters all stay reachable.
   Hidden until gloss.js adds .js, so a dead input never ships. */
.gloss-tools{
  position:sticky;top:0;z-index:3;
  margin:0 0 clamp(1.5rem,3vw,2.5rem);
  background:var(--canvas);
  border-bottom:1px solid var(--hairline);
}
.gloss-tools-row{
  display:none;
  gap:.6rem 1rem;flex-wrap:wrap;align-items:center;
  padding:.85rem 0 .75rem;
  border-bottom:1px solid var(--hairline);
}
.gloss.js .gloss-tools-row{display:flex}

.gloss-search{
  position:relative;display:flex;align-items:center;
  flex:1 1 15rem;min-width:0;
}
.gloss-search-i{
  position:absolute;left:.8rem;width:15px;height:15px;
  fill:var(--ink-soft);opacity:.7;pointer-events:none;
}
.gloss-search input{
  width:100%;min-height:44px;
  padding:.55rem .8rem .55rem 2.3rem;
  font-family:var(--body);font-size:16px;   /* 16px or iOS zooms on focus */
  color:var(--ink);background:#FBF9F5;
  border:1px solid var(--rule);border-radius:3px;
}
.gloss-search input::placeholder{color:var(--ink-soft);opacity:.75}
.gloss-search input:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.gloss-search input::-webkit-search-cancel-button{cursor:pointer}

.gloss-chips{display:flex;flex-wrap:wrap;gap:.4rem}
.gloss-chips::-webkit-scrollbar{height:0}
.g-chip{
  display:inline-flex;align-items:center;gap:.5rem;
  min-height:44px;padding:.45rem .9rem;
  font-family:var(--mono);font-weight:700;font-size:.6rem;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);background:transparent;
  border:1px solid var(--hairline);border-radius:999px;
  cursor:pointer;transition:border-color .2s var(--ease),background .2s var(--ease),color .2s var(--ease);
}
.g-chip:hover{border-color:var(--rule);color:var(--ink)}
.g-chip:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
/* pressed state is a filled background AND a border, never colour alone */
.g-chip[aria-pressed="true"]{background:var(--accent-muted);border-color:var(--rule);color:var(--ink)}

.gloss-count{
  margin:0 0 1.4rem;min-height:1.1em;
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);
}
.gloss-none{
  margin:2rem 0;padding:1.4rem 0;
  border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);
  color:var(--ink-soft);
}

/* sticky so the letters stay reachable through a long scroll */
.gloss-jump{
  display:flex;flex-wrap:wrap;gap:.25rem;
  padding:.6rem 0;
}
/* letters are dead weight once a filter is on */
.gloss.is-filtering .gloss-jump{display:none}
.gloss-jump a.is-off{opacity:.28;pointer-events:none}
.gloss-jump a{
  display:flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;
  font-family:var(--mono);font-weight:700;font-size:.78rem;
  color:var(--ink-soft);text-decoration:none;border-radius:2px;
  transition:background .2s var(--ease),color .2s var(--ease);
}
.gloss-jump a:hover,.gloss-jump a:focus-visible{background:var(--accent-muted);color:var(--ink)}

.gloss-list{margin:0}
.g-letter{
  margin:clamp(2.4rem,5vw,3.6rem) 0 0;
  padding-bottom:.4rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(2.2rem,5vw,3.4rem);line-height:1;
  color:var(--accent);
  border-bottom:2px solid var(--hairline);
  /* clears the sticky letter bar when jumped to */
  scroll-margin-top:7.5rem;
}
.g-letter:first-child{margin-top:0}

.g-item{padding:clamp(1.4rem,3vw,2rem) 0;border-bottom:1px solid var(--hairline)}
.g-term{
  margin:0 0 .7rem;
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.6rem 1rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.35rem,2.8vw,2rem);line-height:1.06;
  color:var(--ink);
}
.g-def{margin:0}
.g-def p{margin:0 0 .7rem;max-width:66ch;color:var(--ink-soft);line-height:1.65}
.g-def p:last-child{margin-bottom:0}
.g-note b{color:var(--ink);font-weight:600}

.gloss-foot{
  margin:clamp(2.5rem,5vw,3.5rem) 0 0;max-width:64ch;
  color:var(--ink-soft);line-height:1.65;font-style:italic;
}

/* The sticky bar earns its space only while it stays short. Below 1100 the six
   chips begin wrapping to a second row, so they become one scrolling row
   instead. At that point the letter strip goes too: it is the part the search
   field already replaces, and keeping it pushed the bar to 191px. Measured,
   not guessed: without any of this it reached 236px at 900px wide. */
@media (max-width:1100px){
  .gloss-chips{
    width:100%;flex-wrap:nowrap;overflow-x:auto;
    scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
    padding-bottom:.15rem;
    /* fades the right edge so it reads as scrollable */
    mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);
  }
  .g-chip{flex:0 0 auto;scroll-snap-align:start;padding:.45rem .8rem}
}
@media (max-width:1100px){
  .gloss-jump{display:none}
  .gloss-tools-row{border-bottom:0}
  .g-letter{scroll-margin-top:5rem}
}
@media (max-width:820px){
  .gloss-tools-row{padding:.7rem 0}
  .g-term{font-size:clamp(1.25rem,5vw,1.6rem)}
}

/* ---- cited evidence under an entry ----
   Set as a margin note, not a box: an amber rule on the left, the source in
   mono underneath. It reads as a footnote, which is what it is. */
.g-cite{
  margin:1rem 0 0 !important;max-width:66ch;
  border-left:3px solid var(--accent);
  padding:.15rem 0 .15rem 1.1rem;
  font-size:.92rem;line-height:1.6;color:var(--ink-soft);
}
.g-cite-k{
  display:block;margin-bottom:.35rem;
  font-family:var(--mono);font-size:.58rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);
}
.g-cite cite{
  display:block;margin-top:.5rem;
  font-family:var(--mono);font-size:.66rem;font-style:normal;
  line-height:1.7;color:var(--ink-soft);
}
.g-cite cite i{font-style:italic}
.g-cite cite a{color:var(--accent-text);text-decoration:none;border-bottom:1px solid var(--hairline)}
.g-cite cite a:hover{border-bottom-color:var(--accent-text)}
.g-cite cite a:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
.g-cite .ext{margin-left:.25em;font-size:.9em}
/* the quoted line from the study, set in the entry's own type so it reads as
   part of the writing, with the citation in mono underneath */
.g-cite q{display:block;quotes:"\201C" "\201D";font-style:italic;color:var(--ink);line-height:1.6}

/* ---- evidence strength ----
   The one label an entry carries: how much is actually known. The verdict
   badge that used to sit beside it is gone - Chris wanted the opinions out. */
.g-tags{display:inline-flex;align-items:center;flex-wrap:wrap;gap:.55rem}

.g-ev{
  display:inline-flex;align-items:center;gap:.45rem;
  font-family:var(--mono);font-weight:700;font-size:.55rem;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);white-space:nowrap;
  padding:.25rem .55rem;border:1px solid var(--hairline);border-radius:2px;
}
/* the bars read as a signal meter, so strength is never colour alone */
.g-ev::before{
  content:"";width:11px;height:9px;flex:none;
  background:
    linear-gradient(var(--m3,transparent) 0 0) 100% 100%/3px 100% no-repeat,
    linear-gradient(var(--m2,transparent) 0 0) 50%  100%/3px 66%  no-repeat,
    linear-gradient(currentColor 0 0)          0    100%/3px 33%  no-repeat;
}
.g-ev-yes{color:var(--accent-text);--m2:currentColor;--m3:currentColor}
.g-ev-mech{--m2:currentColor}
.g-ev-no{color:var(--ink-soft)}

/* an in-entry list, for the rare entry that needs to itemise claims */
.g-sub{margin:1rem 0 .5rem !important;color:var(--ink) !important;font-weight:600}
.g-list{margin:0 0 .2rem;padding:0;list-style:none;max-width:66ch}
.g-list li{
  position:relative;padding:.45rem 0 .45rem 1.1rem;
  color:var(--ink-soft);line-height:1.6;
}
.g-list li + li{border-top:1px solid var(--hairline)}
.g-list li::before{
  content:"";position:absolute;left:0;top:1.05em;
  width:5px;height:1px;background:var(--rule);
}
.g-list b{color:var(--ink);font-weight:600}

/* ============================================================
   THE ASK
   Dark band, so it reads as the end of the page rather than another
   section of it. Two columns: what you get on the left as a numbered
   contents list, the form on the right. No card around either.
   ============================================================ */
.signup{
  position:relative;z-index:2;
  background:var(--deep);color:var(--on-deep);
  padding:clamp(4rem,10vh,7rem) var(--gut);
  overflow:hidden;
}
.signup::before{
  content:"";position:absolute;inset:-30% -10%;pointer-events:none;
  background:radial-gradient(ellipse 46% 40% at 20% 26%,rgba(247,176,58,.11),transparent 66%),
             radial-gradient(ellipse 40% 44% at 84% 76%,rgba(102,155,188,.09),transparent 68%);
  animation:offerglow 74s var(--ease) -12s infinite alternate;
}
.signup-in{
  position:relative;z-index:1;max-width:1240px;margin:0 auto;
  display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(2.5rem,6vw,5.5rem);
  align-items:start;
}
.signup .kicker{color:var(--accent)}
.signup .kicker::before{background:var(--accent)}
.signup-h{
  margin:.5rem 0 1rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(2rem,4.4vw,3.3rem);line-height:1.02;letter-spacing:.004em;
  max-width:16ch;
}
.signup-p{margin:0 0 1.8rem;max-width:46ch;color:rgba(244,240,233,.74);line-height:1.65}

/* the contents of the thing, as a numbered list with its own rules */
.signup-list{margin:0;padding:0;list-style:none;counter-reset:cc;max-width:44ch}
.signup-list li{
  counter-increment:cc;
  position:relative;padding:.6rem 0 .6rem 2.6rem;
  border-top:1px solid rgba(244,240,233,.14);
  color:rgba(244,240,233,.86);font-size:.95rem;line-height:1.4;
}
.signup-list li:last-child{border-bottom:1px solid rgba(244,240,233,.14)}
.signup-list li::before{
  content:counter(cc,decimal-leading-zero);
  position:absolute;left:0;top:.72rem;
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.1em;color:var(--accent);
}

/* ---- the same ten, run as a rail ----
   Only inside the left column: the stage is capped at the list's own 44ch so it
   never reaches across the grid gap into the form. Five cards stand on it at a
   time, the centre one at full size and colour, the four flanking it stepped
   down and faded. No 3D — the row just slides. coverflow.js writes the
   transform and adds .is-cf, so with JS off, or under reduced motion, none of
   this applies and the numbered list stands.  */
.cf{max-width:44ch}
.cf.is-cf{position:relative;height:clamp(150px,17vw,180px);overflow:hidden}
.cf.is-cf .cf-track{position:absolute;inset:0;max-width:none}
.cf.is-cf .cf-track li{
  position:absolute;left:50%;top:50%;
  width:min(30%,152px);height:min(72%,118px);
  display:flex;align-items:center;
  margin:0;padding:1.85rem .85rem .9rem;
  border:1px solid rgba(244,240,233,.16);border-radius:3px;
  background:linear-gradient(160deg,rgba(244,240,233,.075),rgba(244,240,233,.02));
  font-size:clamp(.74rem,1.6vw,.86rem);line-height:1.3;color:rgba(244,240,233,.9);
  transition:transform .6s var(--ease-out),opacity .6s var(--ease-out),border-color .6s;
  will-change:transform;cursor:pointer;
}
.cf.is-cf .cf-track li:last-child{border-bottom:1px solid rgba(244,240,233,.16)}
/* on the rail each card names itself; the plain-list fallback keeps the bare
   number, where its 2.6rem indent has no room for a label this long */
.cf.is-cf .cf-track li::before{
  content:"Cheat code " counter(cc,decimal-leading-zero);
  top:.75rem;left:.85rem;font-size:.6rem;text-transform:uppercase;
}
/* the one facing you carries the accent edge, the way the offer panels do */
.cf.is-cf .cf-track li.is-front{
  border-color:rgba(247,176,58,.55);
  /* darker than the band it sits on, not brighter: the amber edge and the full
     white text are what mark the front card, the fill does not need to shout */
  background:linear-gradient(160deg,rgba(8,9,11,.88),rgba(8,9,11,.62));
  color:var(--on-deep);
}

@media (prefers-reduced-motion:reduce){
  .cf.is-cf .cf-track li{transition:none}
}

/* ---- the form ---- */
.su-field{margin:0 0 1.4rem}
.su-label,.su-legend{
  display:block;margin:0 0 .5rem;padding:0;
  font-family:var(--mono);font-size:.62rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent);
}
.su-input{
  width:100%;min-height:52px;
  padding:.8rem 1rem;
  font-family:var(--body);font-size:16px;   /* 16px or iOS zooms on focus */
  color:var(--on-deep);background:rgba(244,240,233,.06);
  border:1px solid rgba(244,240,233,.28);border-radius:3px;
}
.su-input::placeholder{color:rgba(244,240,233,.42)}
.su-input:focus-visible{outline:3px solid var(--accent);outline-offset:2px;background:rgba(244,240,233,.1)}
.su-input[aria-invalid="true"]{border-color:var(--hero-gold)}
.su-err{
  margin:.55rem 0 0;color:var(--hero-gold);
  font-size:.86rem;line-height:1.45;
}

.su-opts{margin:0 0 1.6rem;padding:0;border:0}
.su-check{
  display:flex;align-items:center;gap:.7rem;
  min-height:44px;cursor:pointer;
  color:rgba(244,240,233,.86);font-size:.95rem;
}
.su-check input{width:19px;height:19px;flex:none;accent-color:var(--accent);cursor:pointer}
.su-check input:focus-visible{outline:3px solid var(--accent);outline-offset:3px}

.su-btn{width:100%;justify-content:center;min-height:52px}
.su-fine{
  margin:1.1rem 0 0;color:rgba(244,240,233,.58);
  font-size:.82rem;line-height:1.6;
}
/* the honeypot is for bots, so it must be gone for everyone else */
.su-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.su-done{
  margin:0;padding:1.3rem 1.4rem;
  border-left:3px solid var(--accent);
  background:rgba(244,240,233,.05);
  color:rgba(244,240,233,.88);line-height:1.65;
}
.su-done b{color:var(--on-deep)}

@media (max-width:900px){
  .signup-in{grid-template-columns:1fr;gap:2.5rem}
  .signup-h{max-width:none}
}

/* ---- the privacy page: one column of plain prose, nothing else ---- */
.legal{padding:clamp(3rem,8vh,5rem) var(--gut) clamp(4rem,10vh,7rem);background:var(--canvas)}
.legal-in{max-width:68ch;margin:0 auto}
.legal h2{
  margin:2.6rem 0 .7rem;font-family:var(--display);font-weight:400;
  font-size:clamp(1.35rem,2.6vw,1.8rem);line-height:1.1;color:var(--ink);
}
.legal h2:first-child{margin-top:0}
.legal p{margin:0 0 1.1rem;color:var(--ink-soft);line-height:1.7}
.legal b{color:var(--ink);font-weight:600}
.legal ul{margin:0 0 1.1rem;padding:0;list-style:none}
.legal li{
  position:relative;padding:.7rem 0 .7rem 1.4rem;
  border-top:1px solid var(--hairline);color:var(--ink-soft);line-height:1.7;
}
.legal li:last-child{border-bottom:1px solid var(--hairline)}
.legal li::before{content:"";position:absolute;left:0;top:1.35rem;width:.72rem;height:2px;background:var(--accent)}
.legal-addr{
  margin:0 0 1.1rem;padding:1rem 1.2rem;
  border-left:3px solid var(--accent);background:rgba(25,26,30,.04);
  font-family:var(--mono);font-size:.78rem;line-height:1.9;color:var(--ink);
}
.legal-date{margin-top:2.6rem;font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--line-dead)}

/* ============================================================
   THE PLATE — blueprint diagram, revealed on scroll
   Drawn rather than filmed, so it stays sharp, weighs almost nothing,
   and the labels are selectable text. Dark band, drafting-paper blue.
   ============================================================ */
.plate{
  position:relative;z-index:2;
  background:var(--deep);color:var(--on-deep);
  padding:clamp(4.5rem,11vh,8rem) var(--gut);
  overflow:hidden;
}
.plate::before{
  content:"";position:absolute;inset:-30% -10%;pointer-events:none;
  background:radial-gradient(ellipse 44% 40% at 70% 40%,rgba(102,155,188,.10),transparent 66%),
             radial-gradient(ellipse 40% 44% at 18% 76%,rgba(247,176,58,.07),transparent 68%);
}
.plate-inner{
  position:relative;z-index:1;max-width:1240px;margin:0 auto;
  display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.plate .kicker{color:var(--hero-blue)}
.plate .kicker::before{background:var(--hero-blue)}
.plate-h{
  margin:.5rem 0 1rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.9rem,4.4vw,3.2rem);line-height:1.02;letter-spacing:.004em;
  max-width:16ch;
}
.plate-p{margin:0;max-width:44ch;color:rgba(244,240,233,.72);line-height:1.65}

.plate-stage{position:relative}
/* the drawing and the food layered on it share one box, so the food's
   percentage positions track the plate rather than the whole section */
.plate-draw{position:relative}
.plate-svg{display:block;width:100%;height:auto;color:var(--hero-blue)}
/* the badge layer, sitting on top of the food rather than under it */
.plate-badges{position:absolute;top:0;left:0;display:block;width:100%;height:100%;pointer-events:none}

/* the drawing itself */
.pl-grid{color:var(--hero-blue)}
.pl-plate ellipse{fill:none;stroke:var(--hero-blue);stroke-width:1.5;opacity:.5}
.pl-food{fill:rgba(159,198,222,.10);stroke:var(--hero-blue);stroke-width:2;stroke-linejoin:round}
.pl-food-line{stroke:var(--hero-blue);stroke-width:1.5;opacity:.6;fill:none;stroke-linecap:round}
.pl-lead{stroke:var(--hero-blue);stroke-width:1;opacity:.55}
/* Each course carries its own colour and number. That pairing is what lets
   the phone layout drop the connecting lines entirely — the reader matches
   badge to box by number and colour instead of following a line. */
.pl-badge circle{fill:var(--deep);stroke:currentColor;stroke-width:1.5}
.pl-badge text{
  fill:currentColor;font-family:var(--mono);font-weight:700;font-size:13px;
  text-anchor:middle;letter-spacing:.06em;
}
.pl-1{color:var(--hero-blue)}
.pl-2{color:var(--plate-veg)}
.pl-3{color:var(--hero-gold)}
.pl-item .pl-food{stroke:currentColor}
.pl-item .pl-food-line,.pl-item .pl-lead{stroke:currentColor}
.pl-1 .pl-food{fill:rgba(159,198,222,.10)}
.pl-2 .pl-food{fill:rgba(143,201,168,.10)}
.pl-3 .pl-food{fill:rgba(255,216,122,.10)}

/* --- the reveal. Each item draws itself in, one after the next. --- */
.pl-item{opacity:0;transition:opacity .5s var(--ease)}
.pl-item .pl-lead{
  stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset .7s var(--ease);
}
.plate-stage.in .pl-item{opacity:1}
.plate-stage.in .pl-item .pl-lead{stroke-dashoffset:0}
.plate-stage.in .pl-1{transition-delay:.05s}
.plate-stage.in .pl-2{transition-delay:.45s}
.plate-stage.in .pl-3{transition-delay:.85s}
.plate-stage.in .pl-1 .pl-lead{transition-delay:.15s}
.plate-stage.in .pl-2 .pl-lead{transition-delay:.55s}
.plate-stage.in .pl-3 .pl-lead{transition-delay:.95s}

/* --- the callouts. Positioned against the drawing on desktop. --- */
.plate-notes{
  list-style:none;margin:0;padding:0;
  position:absolute;inset:0;pointer-events:none;
}
.plate-note{
  position:absolute;width:30%;
  padding:.7rem .9rem;
  border-right:3px solid var(--hero-blue);
  /* text runs up against its tab, so the box reads as pointing at the plate */
  text-align:right;
  background:rgba(25,26,30,.72);
  opacity:0;transform:translateX(-10px);
  transition:opacity .55s var(--ease),transform .55s var(--ease);
}
.plate-stage.in .plate-note{opacity:1;transform:none}
.plate-stage.in .pn-1{transition-delay:.2s}
.plate-stage.in .pn-2{transition-delay:.6s}
.plate-stage.in .pn-3{transition-delay:1s}
/* percentages track the SVG's own 720x560 grid, so they hold position as it
   scales. Spread wide enough that three stacked boxes cannot touch.
   pn-2 sits at 32%, not 37%: the outer two are fixed, so the middle box is
   centred in the band between them, which is where equal gaps land. At 37% the
   two-line vegetable copy pushed the lower gap down to 4% against 14% above and
   the column read as top-heavy.
   ponytail: measured for the current copy (gaps come out 8.9% either side at
   1440 and 1280). If any of the three descriptions gains a line, re-measure —
   CSS cannot centre against sibling heights on its own. */
.pn-1{left:0; top:2%}
.pn-2{left:0; top:32%}
.pn-3{left:0; top:71%}
.pn-1{border-right-color:var(--hero-blue)}
.pn-2{border-right-color:var(--plate-veg)}
.pn-3{border-right-color:var(--hero-gold)}

.pn-n{
  display:block;
  font-family:var(--mono);font-size:.58rem;font-weight:700;
  letter-spacing:.18em;color:var(--hero-blue);
}
.pn-1 .pn-n{color:var(--hero-blue)}
.pn-2 .pn-n{color:var(--plate-veg)}
.pn-3 .pn-n{color:var(--hero-gold)}
.pn-t{display:block;margin-top:.2rem;font-weight:600;font-size:.95rem;color:var(--on-deep)}
/* each callout's title in its own course colour, matching its number and bar */
.pn-1 .pn-t{color:var(--hero-blue)}
.pn-2 .pn-t{color:var(--plate-veg)}
.pn-3 .pn-t{color:var(--hero-gold)}
.pn-d{display:block;margin-top:.15rem;font-size:.85rem;color:rgba(244,240,233,.66);line-height:1.5}

/* --- phone: the callouts cannot live around the plate, so they go under it --- */
@media (max-width:820px){
  .plate-inner{grid-template-columns:1fr;gap:2rem}
  .plate-notes{position:static;display:grid;gap:.6rem;margin-top:1.5rem}
  /* full-width boxes: right-aligned copy leaves a ragged left edge and a gap,
     and the tab no longer points at anything. Back to left where it reads. */
  .plate-note{position:static;width:auto;transform:translateY(10px);text-align:left}
  .plate-draw{max-width:26rem;margin:0 auto}
  /* the badges match the boxes by number and colour, so the lines that
     pointed at callouts sitting alongside now point at nothing */
  .pl-lead{display:none}
}

/* --- motion off: show the finished drawing, skip the animation --- */
@media (prefers-reduced-motion: reduce){
  .pl-item,.plate-note{opacity:1;transform:none;transition:none}
  .pl-item .pl-lead{stroke-dashoffset:0;transition:none}
}

/* the drawn foods, laid over the blueprint and tinted by their item colour */
.plate-foods{position:absolute;inset:0;pointer-events:none}
.pl-img{
  position:absolute;
  left:var(--l);top:var(--t);width:var(--w);height:var(--h);
  /* white line art on transparency used as a stencil: the PNG supplies the
     shape, the background-color supplies the colour, so one asset serves
     any palette and never needs regenerating */
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:center;  mask-position:center;
  -webkit-mask-size:contain;     mask-size:contain;
  /* the foods pop in from far away, one after another - the same bp-pop the
     supplements blueprint uses, so the three blueprints move alike */
  opacity:0;
}
.pl-img-1{-webkit-mask-image:url(../img/plate/steak.png);   mask-image:url(../img/plate/steak.png);   background:var(--hero-blue)}
.pl-img-2{-webkit-mask-image:url(../img/plate/broccoli.png);mask-image:url(../img/plate/broccoli.png);background:var(--plate-veg)}
.pl-img-3{-webkit-mask-image:url(../img/plate/potato.png);  mask-image:url(../img/plate/potato.png);  background:var(--hero-gold)}
.plate-stage.in .pl-img{animation:bp-pop .75s cubic-bezier(.34,1.56,.64,1) both}
.plate-stage.in .pl-img-1{animation-delay:.1s}
.plate-stage.in .pl-img-2{animation-delay:.5s}
.plate-stage.in .pl-img-3{animation-delay:.9s}
@media (prefers-reduced-motion: reduce){
  .pl-img{opacity:1;animation:none}
}

/* ============================================================
   ABOUT
   A prose column and one before/after pair.
   NO CARDS: the two photographs sit straight on the canvas with a
   hairline between them. The weights are set in the display face so the
   numbers carry the comparison — a box around each picture would make it
   a product grid, which is exactly what the page is arguing against.
   The pair stays two-up at every width. Stacking them would destroy the
   only thing they are there to do, which is be looked at side by side.
   ============================================================ */
.ab{padding:clamp(3rem,7vh,4.5rem) var(--gut) clamp(4rem,9vh,6rem)}
.ab-in{max-width:1240px;margin:0 auto}
/* The prose column and the quote beside it. The right third of this section
   used to be empty all the way down, which is what made four paragraphs read
   as a wall - there was nothing else on the page to look at. */
/* The quote column carries a floor. Without one, between 900 and ~1100px
   the prose took its full 64ch and left the quotes a 49px sliver: one word
   per line, 1900px tall, and the centring sank the prose 500px into it. */
.ab-cols{
  display:grid;grid-template-columns:minmax(0,64ch) minmax(17rem,1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.ab-body{max-width:64ch}
.ab-pull{margin:0}
.ab-pull p{
  margin:0;padding-top:1.5rem;
  border-top:3px solid var(--accent);
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.5rem,2.5vw,2.1rem);line-height:1.12;
  letter-spacing:.005em;color:var(--ink);
}
/* stacked, each under its own rule, so the gold lines do the separating */
.ab-pull p + p{margin-top:clamp(1.6rem,3vw,2.4rem)}
@media (max-width:900px){
  /* one column: the quote falls to the end and closes the section instead */
  .ab-cols{grid-template-columns:1fr;gap:2.4rem}
  .ab-pull p{font-size:clamp(1.4rem,5vw,1.8rem)}
}
.ab-body p{
  margin:0 0 1.15rem;
  color:var(--ink-soft);line-height:1.65;
  font-size:clamp(1rem,1.5vw,1.08rem);
}
.ab-body p:last-child{margin-bottom:0}
.ab-body b{color:var(--ink);font-weight:600}

/* the pair sits inside the prose measure's left edge but runs wider, so it
   reads as evidence set into the text rather than a separate gallery */
.ba{margin:clamp(2.2rem,5vw,3.2rem) 0;max-width:820px}
.ba-pair{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(.9rem,2.6vw,1.8rem);
}
/* The hairline goes on the second column, so the padding that clears it has to
   be mirrored on the first. Without the mirror the two photographs render at
   different widths (367px against 337px at desktop) and the "after" comes out
   smaller than the "before" — which is exactly the kind of thing that makes a
   real transformation look staged. */
.ba-fig{margin:0;padding-right:clamp(.9rem,2.6vw,1.8rem)}
.ba-fig+.ba-fig{
  border-left:1px solid var(--hairline);
  padding-right:0;
  padding-left:clamp(.9rem,2.6vw,1.8rem);
}
.ba-fig img{
  display:block;width:100%;height:auto;
  background:var(--deep);
}
.ba-cap{margin:.75rem 0 0}
.ba-lab{
  display:block;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft);
}
.ba-n{
  display:block;margin-top:.2rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.5rem,4.2vw,2.3rem);line-height:1;
  color:var(--ink);
}
.ba-n span{font-size:.42em;letter-spacing:.02em;color:var(--ink-soft)}
.ba-note{
  margin:1.1rem 0 0;
  border-left:3px solid var(--accent);padding-left:1.1rem;
  font-size:.94rem;line-height:1.55;color:var(--ink-soft);
}
/* three client pairs on one line (coaching page). Six photographs do not fit
   the 68ch prose measure, so the row breaks out of it and centres on the page.
   Inside a pair the hairline and its mirrored padding go: at this size they
   would eat a third of each photograph. */
.ba-row{
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1rem,3vw,2.5rem);
  width:min(1100px,calc(100vw - 2*var(--gut)));
  margin:clamp(2.2rem,5vw,3.2rem) 0 clamp(2.2rem,5vw,3.2rem) 50%;
  transform:translateX(-50%);
}
.ba-row .ba{margin:0;max-width:none}
.ba-row .ba-pair{gap:.6rem}
.ba-row .ba-fig,.ba-row .ba-fig+.ba-fig{padding:0;border-left:0}
/* one pair per line on phones; the pair itself stays two-up (standing rule) */
@media (max-width:720px){.ba-row{grid-template-columns:1fr;gap:2rem}}

/* ---- the about section's own head, now that it lives on the homepage ---- */
/* the nav is sticky, so an #about jump has to stop short of it or the kicker
   and the first line of the heading land underneath the bar */
#about{scroll-margin-top:7.5rem}
.ab-h{
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.9rem,4.4vw,3rem);line-height:1.04;
  letter-spacing:.005em;color:var(--ink);
  /* the lede used to carry the gap under this. It is gone, so the heading owns
     its own space now, or it sits straight on the first line of the story. */
  margin:.5rem 0 1.7rem;max-width:22ch;
}

/* ---- breaking up the about copy ----
   Reverted on 31 Aug: the split paragraph, the standfirst and the teach-you
   list were all tried and taken back out. His four paragraphs stand as written.
   The break comes from the photograph above and the pulled quote beside it
   instead - both of which leave the copy completely alone. */



/* ---- the two estimated numbers, in the dark progress band ----
   NO CARDS. Each metric is a hairline, a mono label, one big number and a bar
   sitting straight on the band, which is how the rest of the page argues. A box
   around each would turn the evidence into a product grid.
   Styled for the dark band only, because that is the only place they appear —
   a second light theme nobody renders is just something else to keep in step.
   Both bars and both counters run once, off .metric.in from the shared reveal
   observer, so they arrive with the photographs beside them. */
.metrics{
  margin:clamp(1.6rem,4vw,2.2rem) 0 0;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.2rem,3vw,2rem);
  max-width:52ch;
}
.metric{border-top:1px solid rgba(244,240,233,.16);padding-top:.9rem}
.m-lab{
  margin:0;font-family:var(--mono);font-size:.58rem;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(244,240,233,.62);
}
.m-read{margin:.5rem 0 0;display:flex;align-items:baseline;gap:.5rem}
.m-was{
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.05rem,2.2vw,1.4rem);line-height:1;
  color:rgba(244,240,233,.5);
  text-decoration:line-through;text-decoration-thickness:1px;
}
.m-now{
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.7rem,4.2vw,2.5rem);line-height:1;
  color:var(--on-deep);font-variant-numeric:tabular-nums;
}
/* triangles, not glyphs: no font to wait on and no baseline surprises */
.m-arr{
  width:0;height:0;align-self:center;
  border-left:.34em solid transparent;border-right:.34em solid transparent;
}
.m-arr.down{border-top:.46em solid var(--hero-blue)}
.m-arr.up{border-bottom:.46em solid var(--accent)}

.m-bar{margin-top:.7rem;height:6px;background:rgba(244,240,233,.14);overflow:hidden}
.m-bar i{
  display:block;height:100%;width:var(--was);
  transition:width 1.1s var(--ease);
}
.metric.in .m-bar i{width:var(--now)}
/* the band's own two tints: blue for what came down, gold for what went up */
[data-metric="fat"] .m-bar i{background:var(--hero-blue)}
[data-metric="muscle"] .m-bar i{background:var(--accent)}

@media (max-width:900px){
  .metrics{max-width:none}
}
@media (max-width:520px){
  .metrics{grid-template-columns:1fr;gap:1.4rem}
}
/* motion off: show the finished bars, skip the sweep. The counters are held at
   their final value by the same check in hero.js. */
@media (prefers-reduced-motion: reduce){
  .m-bar i{width:var(--now);transition:none}
}

/* ---- the about section's photographic header ----
   His name set over the left of the frame. Three things make that legible on a
   photograph rather than a flat panel:
     - the shot itself: he stands well right of centre with open path behind him
     - a gradient scrim from the left, weighted to the type and fading to nothing
       before it reaches him, so the picture is never flatly darkened
     - the heading in the display face at canvas colour, which is the same pairing
       the hero uses over film
   object-position holds him in frame as the crop narrows. */
.ab-head{
  position:relative;margin:0 0 clamp(2rem,5vw,3.2rem);
  overflow:hidden;background:var(--deep);
}
.ab-head img{
  display:block;width:100%;height:100%;
  aspect-ratio:1922/818;object-fit:cover;object-position:72% 50%;
}
.ab-head::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,
    rgba(13,17,23,.86) 0%, rgba(13,17,23,.72) 26%,
    rgba(13,17,23,.34) 48%, rgba(13,17,23,0) 68%);
}
.ab-head-copy{
  position:absolute;z-index:1;left:0;bottom:0;
  padding:clamp(1.4rem,4vw,2.8rem) clamp(1.4rem,4vw,3rem);
  max-width:min(60%,34rem);
}
.ab-head-copy .kicker{color:var(--accent)}
.ab-head-copy .kicker::before{background:var(--accent)}
.ab-head-copy .ab-h{
  color:var(--canvas);margin:.5rem 0 0;
  text-shadow:0 2px 18px rgba(8,10,14,.55);
  font-size:clamp(1.5rem,3.4vw,2.7rem);
}
/* the frame goes taller and the type gets the full width as the page narrows,
   or a 2.35:1 band leaves no room to set a three line name over it */
@media (max-width:820px){
  .ab-head img{aspect-ratio:4/3;object-position:64% 42%}
  .ab-head-copy{max-width:none}
  .ab-head::after{
    background:linear-gradient(0deg,
      rgba(13,17,23,.9) 0%, rgba(13,17,23,.55) 38%, rgba(13,17,23,0) 72%);
  }
}

/* ===== somatypes, coaching.html =====
   The plate section's device reused: blueprint grid, white line art as a CSS
   mask so the colour is a token, numbered badges. Three figures in a row, so
   no leader lines - see the note in coaching.html. */
.soma{
  position:relative;z-index:2;
  background:var(--deep);color:var(--on-deep);
  padding:clamp(3.5rem,9vh,6rem) var(--gut);
  overflow:hidden;
}
.soma::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(244,240,233,.055) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(244,240,233,.055) 1px,transparent 1px);
  background-size:24px 24px;
  -webkit-mask-image:radial-gradient(ellipse 70% 62% at 50% 46%,#000 38%,transparent 78%);
          mask-image:radial-gradient(ellipse 70% 62% at 50% 46%,#000 38%,transparent 78%);
}
.soma-in{position:relative;z-index:1;max-width:1240px;margin:0 auto}
.soma .kicker{color:var(--accent)}
.soma .kicker::before{background:var(--accent)}
.soma-h{
  font-family:'Anton',Impact,sans-serif;font-weight:400;
  font-size:clamp(1.9rem,4.4vw,3rem);line-height:1.04;letter-spacing:.006em;
  margin:0 0 1rem;max-width:20ch;
}
.soma-p{margin:0 0 clamp(2.2rem,5vh,3.4rem);max-width:56ch;color:rgba(244,240,233,.74);line-height:1.65}

/* two columns: the labels read as a list on one side, the figures stand
   together on the other so the width difference between them is the point */
.soma-grid{
  display:grid;grid-template-columns:.92fr 1.08fr;
  gap:clamp(1.6rem,4vw,3.4rem);align-items:center;
}
.soma-notes{margin:0;padding:0;list-style:none}
.soma-notes li{
  display:grid;grid-template-columns:auto 1fr;gap:0 .9rem;
  padding:1.1rem 0;border-top:1px solid rgba(244,240,233,.14);
}
.soma-notes li:last-child{border-bottom:1px solid rgba(244,240,233,.14)}
.soma-row{
  margin:0;padding:0;list-style:none;
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(.6rem,1.6vw,1.2rem);
  align-items:end;
}
.soma-fig{display:flex;flex-direction:column;align-items:center;text-align:center}

/* the figure: PNG gives the shape, background gives the colour, exactly as
   the plate foods work. All three masks share a baseline and a height. */
.soma-img{
  display:block;width:100%;max-width:172px;aspect-ratio:640/1441;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:bottom center; mask-position:bottom center;
  -webkit-mask-size:contain; mask-size:contain;
}
.sf-1 .soma-img{-webkit-mask-image:url(../img/soma/ecto.png);mask-image:url(../img/soma/ecto.png);background:var(--hero-blue)}
.sf-2 .soma-img{-webkit-mask-image:url(../img/soma/meso.png);mask-image:url(../img/soma/meso.png);background:var(--plate-veg)}
.sf-3 .soma-img{-webkit-mask-image:url(../img/soma/endo.png);mask-image:url(../img/soma/endo.png);background:var(--hero-gold)}
/* the figures pop in from far away once the section is on screen, the same
   bp-pop as the other two blueprints; the notes still slide with the scroll */
.soma.in .soma-fig{animation:bp-pop .75s cubic-bezier(.34,1.56,.64,1) both}
.soma.in .sf-1{animation-delay:.1s}
.soma.in .sf-2{animation-delay:.3s}
.soma.in .sf-3{animation-delay:.5s}

.soma-n{
  display:grid;place-items:center;width:32px;height:32px;margin:0;
  grid-row:span 2;align-self:start;
  border:1px solid currentColor;border-radius:50%;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:.72rem;font-weight:700;
}
.sn-1 .soma-n{color:var(--hero-blue)}
.sn-2 .soma-n{color:var(--plate-veg)}
.sn-3 .soma-n{color:var(--hero-gold)}
.soma-t{
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:.82rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  margin:.35rem 0 .4rem;
}
.soma-d{color:rgba(244,240,233,.62);font-size:.92rem;line-height:1.6}

.soma-caveat{
  /* full width under both columns, deliberately - it is the correction to
     everything above it, so it should not read as another column */
  margin:clamp(2.4rem,6vh,3.6rem) 0 0;padding:1.4rem 0 0;
  border-top:1px solid rgba(244,240,233,.16);
  color:rgba(244,240,233,.74);line-height:1.7;
}
.soma-caveat b{color:var(--on-deep)}

@media (max-width:860px){
  .soma-grid{grid-template-columns:1fr;gap:clamp(2rem,5vh,2.6rem)}
  .soma-row{order:-1}
  .soma-img{max-width:120px}
}
@media (prefers-reduced-motion: reduce){
  .soma-fig{opacity:1;animation:none}
}


/* ---- coaching page: headline and the ask side by side ----
   The form is the point of the page, so it sits in the header rather than at
   the foot of it. Everything below is the reason to fill it in. */
.pagehead-split .pagehead-in{
  display:grid;grid-template-columns:1.02fr .98fr;
  gap:clamp(2rem,5vw,4.5rem);align-items:start;
}
.pagehead-split .pagehead-h{max-width:14ch}
.pagehead-split .pagehead-p{max-width:44ch}
.pagehead-form{
  padding:clamp(1.4rem,3vw,2rem);
  border:1px solid rgba(244,240,233,.16);
  background:rgba(244,240,233,.035);
}
/* the ask, sitting under the headline rather than over the form, and set at
   the same sizes as the headline and intro above it so the column reads as
   one piece of writing rather than two */
.ph-formh{
  margin:clamp(1.8rem,4vh,2.6rem) 0 1rem;
  font-family:var(--display);font-weight:400;
  font-size:clamp(2.1rem,5.4vw,4rem);
  line-height:.99;letter-spacing:.004em;max-width:14ch;
}
.ph-formp{
  margin:0;max-width:44ch;color:rgba(244,240,233,.72);
  font-size:clamp(1rem,1.6vw,1.12rem);line-height:1.6;
}
.su-area{min-height:118px;resize:vertical;font-family:inherit}
@media (max-width:900px){
  .pagehead-split .pagehead-in{grid-template-columns:1fr;gap:clamp(2rem,5vh,2.8rem)}
  .pagehead-split .pagehead-h,.pagehead-split .pagehead-p{max-width:100%}
}

/* Links inside the dark form column were never styled, so they fell back to the
   browser's default blue. --accent is fill-only (1.65:1 as text), so the text
   yellow is --hero-gold, which clears contrast on --deep. */
.pagehead-form a,.su-fine a{
  color:var(--hero-gold);
  text-underline-offset:.18em;
}
.pagehead-form a:hover,.su-fine a:hover{color:var(--on-deep)}
.pagehead-form a:focus-visible,.su-fine a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* soma.js sets is-live, so these start hidden only when something will move
   them. The transform is set per frame from the scroll handler. */
.soma.is-live .soma-notes li,
.soma.is-live .soma-fig{opacity:0;will-change:opacity,transform}

/* links in the dark page header (thanks.html) - same reasoning as the form
   column: unstyled they fall back to the browser blue */
.pagehead-p a{color:var(--hero-gold);text-underline-offset:.18em}
.pagehead-p a:hover{color:var(--on-deep)}

/* The nav CTA. space-between on .nav already pushes it to the right edge; the
   auto margin on .nav-links keeps the links bunched beside it rather than
   spread across the middle. Stays visible under 820px, where the link list
   hides - it is the one thing a phone visitor should still be able to reach. */
.nav-cta{font-size:.66rem;padding:.6rem 1rem;margin-left:clamp(1rem,2.2vw,2.1rem)}
.nav-cta[aria-current="page"]{box-shadow:0 0 0 2px rgba(244,240,233,.55)}
.nav.stuck .nav-cta[aria-current="page"]{box-shadow:0 0 0 2px rgba(29,33,38,.35)}
@media (max-width:820px){ .nav-cta{margin-left:auto} }

/* Sits over the waitlist button: says why there is a waitlist at all, so the
   button reads as joining a queue rather than booking a slot that is free. */
.offer-full{
  margin:0 0 .9rem;
  font-family:var(--mono);font-size:.72rem;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--hero-gold);
}

/* Contact is an envelope now, not a spelled-out address. Sized and bordered
   like the social row so the footer has one icon language, but it lives in the
   link column, so the underline-on-hover of .foot-col a has to be cancelled. */
/* The envelope now sits in the icon row itself, so .foot-social a already
   gives it its size, border and hover. Nothing extra needed. */
/* Heading and icons are one block: both span the grid, the space above the
   pair lives on the heading, and the row sits directly under it. */
/* Second row of the footer grid: icons under the brand, disclaimer under the
   nav columns. Both were full-width bands before, which left the whole right
   half of the footer empty and pushed the page a screen taller than it needed
   to be. The rule they share is drawn across both so the row still reads as
   one band rather than two stacked blocks. */
.foot-touch{
  grid-column:1;
  margin-top:clamp(1.6rem,4vh,2.4rem);
  padding-top:1.4rem;
  border-top:1px solid rgba(244,240,233,.14);
}
.foot-touch-h{margin:0 0 .85rem}
.foot-social{margin-top:0}

@media (max-width:820px){
  .foot-touch,.foot-med{grid-column:1}
  .foot-med{margin-top:0}
}

/* ---- supplements page: the blueprint beside the headline ----
   The soma section's device in the page header: grid, masked white line art
   coloured by token. No notes, no badges - see the comment in supplements.html.
   The row is a .reveal, so hero.js staggers the three in for free. */
.ph-bp{
  position:relative;align-self:stretch;min-height:260px;
  display:flex;align-items:center;
  padding:clamp(1.4rem,3vw,2.2rem);
}
/* no frame - the grid fades out on its own, so the objects sit on the page */
.ph-bp::before{
  content:"";position:absolute;inset:-12% -8%;pointer-events:none;opacity:.7;
  background-image:linear-gradient(rgba(244,240,233,.055) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(244,240,233,.055) 1px,transparent 1px);
  background-size:24px 24px;
  -webkit-mask-image:radial-gradient(ellipse 72% 70% at 50% 50%,#000 40%,transparent 80%);
          mask-image:radial-gradient(ellipse 72% 70% at 50% 50%,#000 40%,transparent 80%);
}
.ph-bp-row{
  position:relative;z-index:1;width:100%;margin:0;padding:0;list-style:none;
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(.8rem,2vw,1.6rem);
  align-items:end;
}
.ph-bp-fig{display:flex;justify-content:center}
.ph-bp-img{
  display:block;width:100%;max-width:150px;aspect-ratio:1;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:bottom center; mask-position:bottom center;
  -webkit-mask-size:contain; mask-size:contain;
}
/* the bottle stands half again as tall as the others and leans back a touch;
   a transform so the grid columns stay equal and the reveal still runs on the li */
.pb-1 .ph-bp-img{-webkit-mask-image:url(../img/supp/bottle.png);mask-image:url(../img/supp/bottle.png);background:var(--hero-blue);
  transform:translateY(18%) scale(1.5) rotate(-15deg);transform-origin:50% 90%}
/* the scoop lifts so the three sit in a shallow arch */
.pb-2 .ph-bp-img{transform:translateY(-24%)}
.pb-2 .ph-bp-img{-webkit-mask-image:url(../img/supp/scoop.png);mask-image:url(../img/supp/scoop.png);background:var(--plate-veg)}
.pb-3 .ph-bp-img{-webkit-mask-image:url(../img/supp/capsules.png);mask-image:url(../img/supp/capsules.png);background:var(--hero-gold)}
/* the pop: each object starts tiny, as if far away, and lands with an
   overshoot. Replaces the row's slide-up reveal; the .in class from hero.js
   still fires it, one after the other. */
.ph-bp-row > *{opacity:0;transition:none}
.ph-bp-row.in > *{animation:bp-pop .75s cubic-bezier(.34,1.56,.64,1) both}
.ph-bp-row.in > :nth-child(1){animation-delay:.05s}
.ph-bp-row.in > :nth-child(2){animation-delay:.22s}
.ph-bp-row.in > :nth-child(3){animation-delay:.39s}
@keyframes bp-pop{
  0%{opacity:0;transform:scale(.12) translateY(10px)}
  55%{opacity:1;transform:scale(1.14)}
  75%{transform:scale(.94)}
  100%{opacity:1;transform:none}
}
@media (max-width:900px){
  .ph-bp{min-height:0}
  .ph-bp-img{max-width:110px}
}
@media (prefers-reduced-motion: reduce){
  .ph-bp-row > *{opacity:1}
  .ph-bp-row.in > *{animation:none}
}

/* ---- blog page: the drafting sheet, the fourth blueprint ----
   Same .ph-bp panel and bp-pop entrance as the supplements header, one object
   instead of three. Then the sheet letters itself in: every .sh-ln is a wipe
   from the left, ordered by its --i, starting once the pop has landed.
   Title block first (0-3), then the notes (4-8). Words are the newest post's,
   set from the list below; update both when a post goes up. */
.ph-bp-sheet .ph-bp-row{grid-template-columns:1fr;align-items:center;justify-items:center}
.sheet{
  position:relative;width:100%;max-width:520px;aspect-ratio:4/3;
  padding:clamp(1.1rem,2.6vw,1.6rem) clamp(1.2rem,2.8vw,1.8rem) 0;
  border:1px solid rgba(244,240,233,.34);
  background:rgba(244,240,233,.035);
  color:rgba(244,240,233,.72);
}
/* the inner margin line every drafting sheet carries */
.sheet::before{content:"";position:absolute;inset:6px;border:1px solid rgba(244,240,233,.14);pointer-events:none}
.sh-kicker{
  margin:0 0 .5rem;
  font-family:var(--mono);font-size:.6rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--hero-gold);
}
.sh-h{
  margin:0 0 .8rem;max-width:18ch;
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.25rem,2.4vw,1.7rem);line-height:1.02;letter-spacing:.004em;
  color:var(--hero-blue);
}
.sh-notes{
  margin:0;padding:0;max-width:34ch;list-style:decimal inside; /* inside: the wipe clips the li box, so the number has to live in it */
  font-size:clamp(.72rem,1.15vw,.82rem);line-height:1.55;
}
.sh-notes li::marker{font-family:var(--mono);color:var(--hero-gold);font-size:.85em}
/* title block: bottom right, boxed cells, the way a real sheet is signed off */
.sh-tb{
  position:absolute;right:6px;bottom:6px;margin:0;
  display:flex;border-top:1px solid rgba(244,240,233,.34);border-left:1px solid rgba(244,240,233,.34);
  font-family:var(--mono);
}
.sh-tb > div{padding:.4rem .7rem;border-right:1px solid rgba(244,240,233,.14)}
.sh-tb > div:last-child{border-right:0}
.sh-tb dt{font-size:.5rem;letter-spacing:.16em;text-transform:uppercase;color:rgba(244,240,233,.5)}
.sh-tb dd{margin:.1rem 0 0;font-size:.68rem;font-weight:700;color:var(--hero-gold);white-space:nowrap}
/* the lettering: hidden until the row is in, then wiped on in --i order */
.sh-ln{clip-path:inset(0 100% 0 0)}
.ph-bp-row.in .sh-ln{animation:sh-ink .5s var(--ease) both;animation-delay:calc(.7s + var(--i) * .13s)}
@keyframes sh-ink{to{clip-path:inset(0 0 0 0)}}
@media (max-width:900px){
  .sheet{aspect-ratio:auto;padding-bottom:3.6rem}
  .sh-notes{max-width:none}
}
@media (prefers-reduced-motion: reduce){
  .sh-ln,.ph-bp-row.in .sh-ln{clip-path:none;animation:none}
}
/* sheet number and revision beside the date in the post list */
.post-meta{margin:0;display:flex;flex-wrap:wrap;gap:0 1.4em}
.post-meta .post-date{display:inline}
.post-no{color:rgba(29,33,38,.55)}

/* BLOG POST PAGES (blog/*.html) — the body rides on the .legal prose rules
   above; these are only the extras a post needs. */
.article-meta{margin:0 0 2.2rem;font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--line-dead)}
.article h3{margin:2rem 0 .5rem;font-family:var(--body);font-weight:600;font-size:1.05rem;color:var(--ink)}
.article p a{color:var(--accent-text);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px}
.article p a:hover{color:var(--ink)}
.article-cta{margin-top:2.6rem;padding-top:1.8rem;border-top:1px solid var(--hairline);text-align:center}
.article-cta > p{max-width:52ch;margin-left:auto;margin-right:auto}
.article-cta .btn{margin:.2rem auto 2.6rem}
.article-book{display:grid;grid-template-columns:minmax(0,190px) 1fr;gap:1.8rem;align-items:center;text-align:left}
.article-book-link{display:block}
.article-book-cover{display:block;width:100%;height:auto;box-shadow:0 18px 40px -18px rgba(25,26,30,.55)}
.article-book-words p:last-child{margin-bottom:0}
@media (max-width:600px){.article-book{grid-template-columns:1fr;justify-items:center;text-align:center}.article-book-link{width:min(100%,200px)}}
.article-src{margin-top:2.6rem;padding-top:1rem;border-top:1px solid var(--hairline);font-family:var(--mono);font-size:.7rem;line-height:1.8;color:var(--line-dead)}
.article-back{margin-top:1.6rem;font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}
.article-back a{color:var(--ink);text-decoration:none;border-bottom:2px solid var(--accent)}
