/* ==========================================================================
   MEAN TRUTH FITNESS
   Implements DESIGN.md. Palette, typefaces, motifs and motion rules are
   treated as locked. Mobile first, authored against 390px.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   Neutral ramp and text colours are brand level. The accent is written per
   page by build.js onto [data-protocol], so a new protocol is a colourway
   swap and nothing else (DESIGN.md section 9).
   -------------------------------------------------------------------------- */
:root {
  /* DESIGN.md section 2. Seven colours. Locked. */
  --black: #070707;      /* page background            */
  --onyx: #0d0d0d;       /* alternating sections, cards */
  --carbon: #1b1b1b;     /* hairlines, borders          */
  --parchment: #f2efe9;  /* headlines, primary text     */
  --olive: #8b8681;      /* body copy                   */
  --struck: #4a4642;     /* darkened olive, struck text */

  /* Fallbacks. build.js overrides these on the page root. */
  --accent: #dd0a0a;     /* Racing Red */
  --accent-deep: #8c0808;/* Blood Red  */

  --display: 'Anton', 'Arial Narrow', 'Haettenschweiler', sans-serif;
  --body: 'Barlow Condensed', 'Arial Narrow', sans-serif;

  /* Motion. MOTION_INTENSITY 5: heavy and deliberate, never elastic.
     No spring, no overshoot, no bounce (DESIGN.md section 6). */
  --ease: cubic-bezier(0.2, 0.6, 0.2, 1);
  --t-fast: 180ms;
  --t-mid: 320ms;
  --t-reveal: 620ms;

  --gut: 20px;           /* mobile gutter */
  --maxw: 1240px;

  /* Height of the fixed buy bar: 1px top border, 10px padding, a 44px control,
     10px padding, plus the home indicator inset. Measured at 65px, not the 64
     the padding and control alone suggest. The footer reserves this much at
     its foot so the bar never covers the last of the page. Nothing else does:
     sections scroll under the bar like everything else. */
  --buybar-h: calc(65px + env(safe-area-inset-bottom, 0px));

  /* Section spacing. One scale, top and bottom the same, used by every .sec
     on the homepage and the legal pages. Under 600px 28px, so content to
     content is about 56 to 64px; 600 to 1099 44px; 1100 and up 56px, about
     112px content to content. The hero keeps its own top for the fold. */
  --sec-pad: 28px;

  --z-grain: 60;
  --z-nav: 70;
  --z-buybar: 80;
  --z-skip: 90;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

/* DESIGN.md section 4: square corners only. No rounded corners anywhere. */
*,
input,
button,
select,
textarea { border-radius: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;   /* native only. No smooth scroll library. */
  scroll-padding-top: 76px;
}

body {
  background: var(--black);
  color: var(--olive);
  font-family: var(--body);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

button,
input { font: inherit; color: inherit; background: none; border: none; }

button { cursor: pointer; }

a { color: inherit; text-decoration: none; }

ul, ol { list-style: none; }

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

/* Keyboard focus. Visible against near black without using a new hue. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   3. Type primitives
   DESIGN.md section 3. Two families only. Anton always uppercase, 0.92
   line height. Barlow Condensed for everything else.
   -------------------------------------------------------------------------- */
.display {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 0.92;
  letter-spacing: 0.005em;
  color: var(--parchment);
}

/* Eyebrow: Barlow Condensed 13px / 700 / .3em / uppercase / Blood red. */
.eyebrow {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent-deep);
  /* Blood Red on near black is low contrast at this size, so the eyebrow is
     never the only carrier of meaning. It always sits above a Parchment
     heading that repeats it. */
}

.num { font-variant-numeric: tabular-nums; }

/* Two part heading construction (DESIGN.md section 3).
   Line one upright in Parchment. Line two red and skewed -9deg, backed by a
   Blood Red offset so the red carries depth rather than sitting flat. */
.h2 { margin-bottom: 22px; }

.h2 .h-top,
.hero-lockup .h-top {
  display: block;
  color: var(--parchment);
}

.h2 .h-bot,
.hero-lockup .h-bot {
  display: block;
  color: var(--accent);
  transform: skewX(-9deg);
  transform-origin: left bottom;
  text-shadow: 2px 3px 0 var(--accent-deep);
}

.h2 .h-top,
.h2 .h-bot {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 0.92;
  font-size: clamp(1.95rem, 8.8vw, 4.75rem);
}

.h2 .h-bot { margin-top: 0.02em; }

.lede {
  max-width: 62ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--olive);
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   4. Motifs
   DESIGN.md section 4.
   -------------------------------------------------------------------------- */

/* Claw marks. The primary structural marker above each section heading.
   Traced from the supplied artwork to a single path, defined once as
   #mt-claw and referenced here. Box height and the 16px below it are
   unchanged; width now follows the artwork's own aspect. */
.claw {
  display: flex;
  align-items: flex-end;
  height: 30px;
  margin-bottom: 16px;
  color: var(--accent);
}
/* currentColor, so the mark inherits `color` above. That is the page accent
   by default and the Lean Blueprint accent inside #lean-blueprint, which
   already overrides --accent for its own subtree. */
.claw__i {
  height: 100%;
  width: auto;
  overflow: visible;
}

/* The symbol definition itself must never occupy layout. */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* Red slash rule. A 74px red bar, skewed, under headings. */
.slash {
  width: 74px;
  height: 5px;
  background: var(--accent);
  transform: skewX(-22deg);
  margin: 20px 0 22px 3px;
}
.slash--sm { width: 46px; height: 3px; margin: 14px 0 16px 2px; }

/* Cell scale claw, for the spec grid. Same mark, smaller box. */
.claw--sm { height: 19px; margin-bottom: 11px; }

/* Grain. A fine noise overlay across the whole page at roughly 9%.
   Fixed, non interactive, and switched off for reduced motion users only
   where it would otherwise animate. It never animates here. */
.grain {
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.09;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* Hairline panels. 1px Carbon Black borders on near black fills. */
.panel {
  border: 1px solid var(--carbon);
  background: var(--onyx);
}

/* Grid determinism: a 1px gap over a Carbon parent draws razor thin rules
   without per cell border maths. */
.hairgrid {
  display: grid;
  gap: 1px;
  background: var(--carbon);
  border: 1px solid var(--carbon);
}
.hairgrid > * { background: var(--onyx); }

/* --------------------------------------------------------------------------
   5. Layout
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
}

section { position: relative; }

/* One rule, every section. The bar clearance lives on the footer only. */
.sec { padding-block: var(--sec-pad); }
@media (min-width: 600px) { :root { --sec-pad: 44px; } }
@media (min-width: 1100px) { :root { --sec-pad: 56px; } }

/* Alternating sections use Onyx over the Black page (DESIGN.md section 2).
   Backgrounds stay near black throughout. There are no light sections. */
.sec--onyx { background: var(--onyx); }
.sec--onyx .hairgrid > * { background: var(--black); }

.sec-head { margin-bottom: 34px; }

/* Clipped to nothing until focused, rather than moved off screen with a
   transform. A transform is fragile: any rule that neutralises transforms,
   and some capture tools, put it back on screen. Clip cannot be undone by
   accident, and it is the technique the rest of the site already uses for
   .visually-hidden. */
.skip {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: var(--z-skip);
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  background: var(--accent);
  color: var(--parchment);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 13px;
}
.skip:focus {
  width: auto;
  height: auto;
  padding: 10px 16px;
  margin: 0;
  overflow: visible;
  clip: auto;
  clip-path: none;
}

/* --------------------------------------------------------------------------
   6. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 26px;
  font-family: var(--display);
  font-size: 20px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  border: 1px solid transparent;
  transition: background var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

/* Parchment on Racing Red is 5.1:1. Safe. */
.btn--primary {
  background: var(--accent);
  color: var(--parchment);
}
.btn--primary:hover { background: var(--accent-deep); }
.btn--primary:active { transform: translateY(1px); }

.btn--ghost {
  border-color: var(--carbon);
  color: var(--parchment);
  background: transparent;
}
.btn--ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn--ghost:active { transform: translateY(1px); }

/* Hairline panel. DESIGN.md section 2 reserves Racing Red fills for buy
   actions, so a control that needs weight without being one takes section 4's
   panel instead: 1px Carbon Black on a near-black fill, Parchment label. */
.btn--panel {
  background: var(--onyx);
  border-color: var(--carbon);
  color: var(--parchment);
}
.btn--panel:hover { background: var(--carbon); }
.btn--panel:active { transform: translateY(1px); }


/* --------------------------------------------------------------------------
   7. Navigation
   -------------------------------------------------------------------------- */
/* Solid, and edge to edge. No translucency, no blur, no gradient and no
   hairline: the bar is a black band, and anything lighter along its edge read
   as a seam against the page it sits on. */
.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: #070707;
  border-bottom: 0;
}
.nav__in {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 58px;
}
.nav__brand {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-right: auto;
}
.nav__mark { width: 26px; height: 26px; object-fit: contain; }
.nav__name {
  font-family: var(--display);
  font-size: 17px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--parchment);
  line-height: 1;
}
.nav__name b { color: var(--accent); font-weight: 400; }
.nav__links { display: none; gap: 26px; }
.nav__links a {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--olive);
  transition: color var(--t-fast) var(--ease);
}
.nav__links a:hover,
.nav__links a[aria-current='true'] { color: var(--parchment); }
.nav__cta {
  min-height: 38px;
  padding: 0 18px;
  font-size: 16px;
}
/* Login in the header carries no outline at all. It is the same solid black
   as the bar it sits in, with Parchment type, and it answers a hover or a
   focus by turning the type Racing Red rather than by drawing a border back
   in. The focus ring is the one exception, because that is the browser's
   accessibility affordance and not decoration. */
.nav .btn--ghost.nav__cta {
  background: #070707;
  border-color: transparent;
  color: var(--parchment);
}
.nav .btn--ghost.nav__cta:hover,
.nav .btn--ghost.nav__cta:focus,
.nav .btn--ghost.nav__cta:focus-visible,
.nav .btn--ghost.nav__cta:active {
  background: #070707;
  border-color: transparent;
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   8. Hero
   Buy button is inside the first viewport. DESIGN.md section 6 target:
   reachable within three scrolls.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: 44px 54px;
  border-bottom: 1px solid var(--carbon);
}

/* Static background plate. No parallax, no scroll transform. */
.hero__plate {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* The video is 1280 native. 1280 x 1.15 = 1472, so past this the plate
     stops growing and the black page background extends either side rather
     than the video stretching further. margin-inline centres it against the
     inset. */
  max-width: 1472px;
  margin-inline: auto;
}
/* Still and video share one rule, so the crop, position, opacity and filter
   are identical whichever one is showing. The gradient is an ::after and
   paints over whichever it is. */
/* <picture> is only a selector wrapper here; the img is absolutely positioned,
   so the picture box itself must not participate in layout. */
.hero__plate picture { display: contents; }

/* Top aligned, not centred, because the animal is right at the top of its own
   frame. Measured rather than judged: across every frame of the loop the
   whitest fur of the ears never starts lower than 1.11% down the frame, and
   the two stills are the same at 1.11% and 0.83%. A centred cover crop takes
   2.84% off the top at 1280 and 8.99% from 1600 up, so the ears were being
   cut at every desktop width. At 0% the crop comes off the bottom instead,
   where the frame is the floor of the gym, and the head is whole at any
   width the plate is ever given. */
.hero__plate img,
.hero__plate video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0%;
  opacity: 0.42;
  filter: grayscale(0.3) contrast(1.08);
}

.hero__plate video {
  /* Let the compositor resample normally. Any smoothing hint here would only
     make an upscaled frame look worse, not sharper. */
  image-rendering: auto;
}

/* Exactly one layer renders at a time. The still is the background on its own
   below 768px and under reduced motion; once the video mounts the still is
   taken out entirely rather than left underneath it. Nothing is stacked and
   nothing is composited, so the subject cannot ghost against itself.
   The video carries the same file as its poster attribute, so it has an image
   to show from the moment it exists and hiding the still cannot flash. */
.hero__plate.has-video img {
  display: none;
}

/* Belt and braces. The script is what actually keeps the video off small
   screens and reduced-motion sessions, by never giving it a source. These
   only matter if that ever fails. */
@media (max-width: 767px) {
  .hero__plate video { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__plate video { display: none; }
}
/* The mask is horizontal now, not a flat vertical darkener plus a vignette.
   The old pair dimmed the whole frame evenly across its width, which is what
   washed the subject out: the right side was paying for contrast the headline
   needed on the left.

   Layer one carries the headline. It holds roughly the darkening the old mask
   produced where the type sits, about 0.55 effective at 26% across, then
   falls away through the centre to almost nothing over the right half so the
   tiger and the red rim light keep their saturation.

   Layer two is bottom only. It grounds the section into the black page and
   keeps the telemetry strip legible. It starts at 62%, well below the
   headline, so it costs the subject nothing.

   The stats are unaffected either way: their cells are opaque Onyx, so their
   contrast never depended on this mask. */
.hero__plate::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg,
      rgba(7,7,7,0.60) 0%,
      rgba(7,7,7,0.54) 32%,
      rgba(7,7,7,0.30) 50%,
      rgba(7,7,7,0.12) 66%,
      rgba(7,7,7,0.04) 82%,
      rgba(7,7,7,0.02) 100%),
    /* Bottom fade. It reaches full black at the last pixel rather than
       stopping short, so the plate meets the page instead of ending on a
       visible edge. Only the last stretch changes; the stop at 88% is where
       it was, so the subject is not darkened any further. */
    linear-gradient(180deg,
      rgba(7,7,7,0) 62%,
      rgba(7,7,7,0.45) 88%,
      rgba(7,7,7,0.78) 96%,
      rgba(7,7,7,1) 100%);
}

/* Past the cap the plate no longer reaches the viewport edges, so its own left
   and right edges would read as hard vertical seams against the black. This
   feathers them, and only at the widths where those edges exist: at 1472 and
   below the plate is full bleed and this never applies. z-index lifts it over
   the video, which is a positioned sibling painted after it. */
@media (min-width: 1473px) {
  .hero__plate::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(90deg,
      rgba(7,7,7,0.92) 0%,
      rgba(7,7,7,0) 4.5%,
      rgba(7,7,7,0) 92%,
      rgba(7,7,7,0.92) 100%);
  }
}

.hero__in { position: relative; z-index: 1; }

.hero-lockup { margin: 14px 0 0; }
/* One scale for both lines, so they read as a block rather than a stepped
   pair.

   Derived by measurement, not by eye: a binary search for the largest size at
   which both parts still fit the lead column, at 320, 360, 390, 430, 768,
   1024, 1280 and 1600. The vw term comes from the 320px case, which binds,
   and the ceiling from the widest layout, where the lead column stops growing.

   Each part wraps within itself. The two parts are 27 and 21 characters now,
   and holding each on a single line, as the ten character lines this replaced
   did, would put the heading at about 30px on a phone. Wrapping keeps it at
   about 55px there, at two rows per part. Neither part may overflow its
   column: tools/probe-hero.js reports the room left at every width.

   The ceiling is a desktop measurement, not a round number. Above 76px the
   second part wraps and the heading becomes four rows, which pushes the
   subtext and the buttons past the fold at 1280x800, where the sticky buy bar
   takes the bottom 65px of the screen. That 76px was found by walking the
   band at 1280x800 and at 1440x900; the ceiling sits just under it, so a
   difference in font metrics cannot tip the second part onto a second line. */
/* One row, three parts: YOU in Parchment, VS skewed in Racing Red, YOU again.
   Ten characters, which is what the size below was derived for.

   The parts are inline-block rather than block, because the whole lockup is
   one line now. Neither of the two rules they inherit from the h2 pair still
   fits a row, so both are restated here.

   The skew does not change the box the browser lays out, only what is drawn
   in it, so VS is given its own side margins: at the top of a 140px line a
   -9deg lean reaches about 22px sideways, which is enough to touch the Y
   beside it. The margins carry that in em, so the clearance scales with the
   type. */
/* One size drives the lockup and the three lines under it, so they cannot
   drift apart. It is the size this heading had when it was last ten
   characters: derived by measurement, the vw term from the 320px case and the
   ceiling from the 1100px layout, where the lead column stops growing at
   638px. tools/probe-hero.js asserts the row never wraps at any width, and
   reports the room left in the column. */
.hero__lead {
  --lockup: clamp(3.2rem, 19.6vw, 140px);
}
.hero-lockup {
  font-size: var(--lockup);
  white-space: nowrap;
}
.hero-lockup .h-top,
.hero-lockup .h-bot {
  display: inline-block;
  font-family: var(--display);
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: baseline;
}
.hero-lockup .h-top {
  font-size: 1em;
  line-height: 0.9;
  letter-spacing: -0.005em;
}
.hero-lockup .h-bot {
  font-size: 1em;
  line-height: 0.9;
  margin: 0 0.2em 0 0.16em;
  transform-origin: 50% 50%;
  /* The Blood Red offset was drawn for a 45px line. At 140px it doubles the
     red area of the largest red element on the page, so it scales with the
     type rather than staying a fixed 3px slab. */
  text-shadow: 0.015em 0.02em 0 var(--accent-deep);
}

/* The three lines under the lockup, read as one block with it.

   Barlow Condensed rather than Anton, so the lockup keeps the weight, and
   sized by the same measurement: the longest of the three, FOUR TRAINING
   SEASONS, fills the lead column the way YOU VS YOU does above it, which is
   what gives the heading, these lines and the paragraph below one right edge.

   The last line is the skewed Racing Red line the hero already had. It keeps
   its lean, its colour and its offset, and takes the size of the block it now
   sits in. */
.hero__sub {
  margin: 0.12em 0 0;
  font-family: var(--body);
  font-weight: 700;
  /* 0.43 of the lockup, which is the ratio at which the longest of the three,
     FOUR TRAINING SEASONS, comes out the same width as YOU VS YOU above it.
     Measured at both ends of the range, 0.430 at 320px and 0.433 at 1280px,
     so one fraction holds everywhere and the two read as a single block with
     a shared right edge. */
  font-size: calc(var(--lockup) * 0.43);
  line-height: 1.04;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--parchment);
}
.hero__sub-l {
  display: block;
  white-space: nowrap;
}
.hero__sub-red {
  color: var(--accent);
  transform: skewX(-9deg);
  transform-origin: left bottom;
  text-shadow: 0.015em 0.02em 0 var(--accent-deep);
}

/* Full width of the lead column, so its right edge lands where the lockup and
   the three lines above it end rather than stopping short of them. */
.hero__positioning {
  margin-top: 18px;
  font-size: 17px;
  line-height: 1.5;
  color: var(--olive);
}
/* Stacked on mobile so neither label truncates, and so the primary action is
   a full width tap target. Side by side from 800px. */
/* Content width, not full bleed. A 350px solid red slab across a 390px
   screen is the wallpaper DESIGN.md section 2 rules out, and on its own it
   was 5.5% of the viewport against a 10% budget for the whole page. The
   buttons still clear 44px and still sit one per row on a phone. */
.hero__cta {
  margin-top: 26px;
  display: grid;
  gap: 12px;
  /* One action now. It takes the width of its own label and sits at the left
     edge of the column, which is where the lockup, the three lines and the
     paragraph all start. On a phone it is the full column instead, so the tap
     target is the whole width rather than a label sized slab. */
  width: 100%;
  max-width: 100%;
  justify-items: stretch;
}
.hero__cta .btn { width: 100%; }

@media (min-width: 560px) {
  .hero__cta { width: max-content; }
}

/* Key stats. Hairline grid, 2 up on mobile. */
.stats {
  margin-top: 34px;
  grid-template-columns: repeat(2, 1fr);
}
/* Source order is semantic (term then value). Reversed here so the numeral
   reads first, which is what the eye wants. */
.stat {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  padding: 16px 14px;
}
.stat__v {
  font-family: var(--display);
  font-size: clamp(2.1rem, 10vw, 3.1rem);
  line-height: 0.9;
  color: var(--accent-deep);       /* Blood Red carries numerals */
  font-variant-numeric: tabular-nums;
}
.stat__l {
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--olive);
  line-height: 1.25;
}

/* --------------------------------------------------------------------------
   9. Strikethrough. The signature interaction (DESIGN.md section 5).
   -------------------------------------------------------------------------- */
.strikes { margin-top: 8px; }

.strike {
  padding: 26px 0;
  border-top: 1px solid var(--carbon);
}
/* The last pair ends the section on its own words: no rule under it and no
   padding holding the rule off, so the section's own spacing is the only
   space below it. */
.strike:last-child { padding-bottom: 0; }

/* inline-block, not inline: the red rule is absolutely positioned against
   this box, and an inline box that wraps would only be covered on its first
   line fragment. */
.strike__lie {
  position: relative;
  display: inline-block;
  font-family: var(--display);
  font-size: clamp(1.5rem, 7.2vw, 2.6rem);
  line-height: 1.06;
  text-transform: uppercase;
  color: var(--struck);            /* darkened Grey Olive, same hue family */
}

/* The red line is a separate element so it can draw across, rather than a
   text-decoration which cannot be animated. */
.strike__rule {
  position: absolute;
  left: -2px;
  right: -2px;
  top: 52%;
  height: 4px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  pointer-events: none;
}
.strike.is-in .strike__rule {
  transform: scaleX(1);
  transition: transform 460ms var(--ease);
}

.strike__truth { margin-top: 14px; }
/* Each sentence is its own inline-block, so a pair sits on one line wherever
   the column is wide enough and the second drops whole when it is not. A
   sentence cannot break in the middle that way: it only wraps inside itself
   if it is wider than the column on its own. Flush left, unbalanced, which is
   what keeps the left edge hard against the rule above it. */
.strike__truth span {
  display: inline-block;
  margin-right: 0.3em;
  font-family: var(--display);
  /* 5.4vw rather than 5.8, which is what puts all six pairs on one line at
     390 without going under the 20px floor the clamp already holds. Above
     800 the 2rem cap governs, so a desktop is untouched. */
  font-size: clamp(1.25rem, 5.4vw, 2rem);
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--parchment);
  opacity: 0;
  transform: translateY(10px);
}
/* The correction lands after the strike, not with it. */
.strike.is-in .strike__truth span {
  opacity: 1;
  transform: none;
  transition: opacity 380ms var(--ease), transform 380ms var(--ease);
  transition-delay: calc(420ms + var(--i, 0) * 90ms);
}

/* --------------------------------------------------------------------------
   8b. The platform. The introduction video.

   A poster and a play button until it is asked for, then the browser's own
   player in the same box. Square corners, no rounding, and no custom controls:
   seeking, volume and full screen are the platform's, which is also what makes
   them keyboard accessible without a line of script.
   -------------------------------------------------------------------------- */
.player {
  margin: 26px 0 0;
  border: 1px solid var(--carbon);
  background: var(--black);
  line-height: 0;
}
.player__go {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.player__poster { display: block; width: 100%; height: auto; }
/* A veil under the mark, so the mark holds against a bright frame without
   dimming the whole still. */
.player__go::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(closest-side at 50% 50%, rgba(7, 7, 7, 0.55), rgba(7, 7, 7, 0) 70%);
}
.player__mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  background: var(--accent);
  color: var(--parchment);
}
.player__mark svg { width: 38px; height: 38px; }
.player__go:hover .player__mark { background: var(--accent-deep); }
.player__go:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.player video {
  display: block;
  width: 100%;
  height: auto;
  background: var(--black);
}

@media (min-width: 800px) {
  .player { margin-top: 30px; }
  .player__mark { width: 104px; height: 104px; }
  .player__mark svg { width: 46px; height: 46px; }
}

/* --------------------------------------------------------------------------
   9b. The trial band. A call to action, not a section of the argument, so it
   carries no claw mark and no rule under its heading.

   The artwork is placed, not decorated: on a phone it is a band of its own
   above the copy, which is the only arrangement where type can never be read
   over the animal. From 800px it takes the right half and is cropped from the
   right, so the tiger, who stands in the right of the frame, stays whole. The
   copy is held to 46% of the wrap, and the crop puts his leading edge at
   about 63% of the viewport, so the two cannot meet at any width.

   The veil is a horizontal gradient rather than a flat darkener, for the same
   reason the hero's is: a flat one would take the contrast out of the subject
   to buy legibility the left side already has.
   -------------------------------------------------------------------------- */
.cta-band {
  position: relative;
  overflow: hidden;
  background: var(--black);
}
.cta-band__art { position: relative; }
.cta-band__art img {
  display: block;
  width: 100%;
  height: auto;
}
/* Phone: the band sits above the copy, under a veil that keeps it in the
   page's register rather than glowing out of it. */
.cta-band__art::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(7,7,7,0.30) 0%, rgba(7,7,7,0.45) 55%, var(--black) 100%);
}
.cta-band__in { position: relative; z-index: 1; padding-top: 30px; }
.cta-band__copy { margin-top: 16px; }
.cta-band__act {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 18px;
}
.cta-band__act .btn { width: 100%; }
.cta-band__note {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 15px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--olive);
}
.cta-band__note .tick {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--accent);
}

@media (min-width: 560px) {
  .cta-band__act .btn { width: auto; }
}

@media (min-width: 800px) {
  .cta-band__art {
    position: absolute;
    inset: 0 0 0 auto;
    width: 50%;
  }
  .cta-band__art picture,
  .cta-band__art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 100% 50%;
  }
  .cta-band__art::after {
    background: linear-gradient(90deg,
      var(--black) 0%,
      rgba(7,7,7,0.86) 18%,
      rgba(7,7,7,0.42) 44%,
      rgba(7,7,7,0.10) 74%,
      rgba(7,7,7,0.00) 100%);
  }
  .cta-band__in { padding-top: 0; }
  .cta-band__in > * { max-width: 46%; }
}

/* --------------------------------------------------------------------------
   9c. The questions. Native details and summary, one column.

   No script. The open and closed states, the keyboard, the focus ring and the
   screen reader announcement are all the element's own; this only draws the
   plus and turns it into a minus, from the open attribute, which cannot fall
   out of step with the thing it describes.
   -------------------------------------------------------------------------- */
.qa {
  margin-top: 26px;
  border-top: 1px solid var(--carbon);
}
.qa__item { border-bottom: 1px solid var(--carbon); }
.qa__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-size: clamp(1.1rem, 4.6vw, 1.45rem);
  line-height: 1.15;
  text-transform: uppercase;
  color: var(--parchment);
}
/* Safari draws its own triangle without this, on top of the mark. */
.qa__q::-webkit-details-marker { display: none; }
.qa__q:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.qa__item:hover .qa__q { color: var(--accent); }
.qa__text { min-width: 0; }

/* The plus: two bars, the upright one rotated away when the item opens, which
   leaves the minus. Racing Red only while it is open, so a page of closed
   questions carries no red at all. */
.qa__mark {
  position: relative;
  flex: none;
  width: 18px;
  height: 18px;
}
.qa__mark::before,
.qa__mark::after {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  width: 18px;
  height: 2px;
  background: var(--parchment);
  transition: transform var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.qa__mark::after { transform: rotate(90deg); }
.qa__item[open] .qa__mark::before,
.qa__item[open] .qa__mark::after { background: var(--accent); }
.qa__item[open] .qa__mark::after { transform: rotate(0deg); }

.qa__a {
  margin: 0;
  padding: 0 0 20px;
  max-width: 68ch;
  font-size: 16px;
  line-height: 1.55;
  color: var(--olive);
}

@media (prefers-reduced-motion: reduce) {
  .qa__mark::before,
  .qa__mark::after { transition: none; }
}

@media (min-width: 800px) {
  .qa__q { padding: 22px 0; }
  .qa__a { padding-bottom: 24px; font-size: 17px; }
}

/* --------------------------------------------------------------------------
   10. Contents. The 18 chapters.
   -------------------------------------------------------------------------- */
.chapters { border-top: 1px solid var(--carbon); }

/* The cover sits in the space beside the heading, so it only shows from
   900px, where there is space to sit in. Below that the section is exactly as
   it was.

   Note this hides it but does not stop it downloading: measured at 390px the
   image still loads despite display: none and loading="lazy". Gating the
   fetch would mean the data-attribute and script treatment the hero video
   uses. See README. */
.contents__cover { display: none; }
.chapter {
  display: grid;
  grid-template-columns: 34px 1fr auto;
  align-items: baseline;
  gap: 12px;
  padding: 13px 4px;
  border-bottom: 1px solid var(--carbon);
  transition: background var(--t-fast) var(--ease);
}
.chapter:hover { background: var(--onyx); }
.sec--onyx .chapter:hover { background: var(--black); }
.chapter__n {
  font-family: var(--display);
  font-size: 19px;
  color: var(--accent-deep);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.chapter__t {
  font-family: var(--display);
  font-size: clamp(1rem, 4.4vw, 1.35rem);
  text-transform: uppercase;
  color: var(--parchment);
  line-height: 1.08;
  transition: color var(--t-fast) var(--ease);
}
.chapter:hover .chapter__t { color: var(--accent); }
.chapter__p {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--olive);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   11. What you get. One anchor card, then a grid of cropped details.
   -------------------------------------------------------------------------- */

/* The intro sits directly on the anchor, with no gap between them. The 34px
   is on the shared .sec-head, so it is zeroed for this section only. */
#inside .sec-head { margin-bottom: 0; }

/* The anchor: the single large proof card. */
.anchor {
  border: 1px solid var(--carbon);
  background: var(--black);
  padding: 26px 20px 30px;
}
.anchor__t {
  font-family: var(--display);
  font-size: clamp(1.5rem, 6.6vw, 2.3rem);
  text-transform: uppercase;
  line-height: 0.96;
  color: var(--parchment);
  margin-bottom: 16px;
}
.anchor__list li {
  position: relative;
  padding: 9px 0 9px 24px;
  border-top: 1px solid var(--carbon);
  font-size: 16px;
  color: var(--olive);
  line-height: 1.4;
}
.anchor__list li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 17px;
  width: 9px;
  height: 3px;
  background: var(--accent);
  transform: skewX(-22deg);
}

.anchor__fig { margin-top: 24px; border: 1px solid var(--carbon); background: var(--black); }
.anchor__link { display: block; }
.anchor__link img { width: 100%; }
.anchor__cap {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 12px;
  border-top: 1px solid var(--carbon);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--olive);
}
/* Signals that the card opens, with no script and no library behind it. */
.anchor__open {
  color: var(--accent);
  white-space: nowrap;
  transition: color var(--t-fast) var(--ease);
}
.anchor__fig:hover .anchor__open { color: var(--parchment); }

/* Part 2. The measurement grid. */
.measure {
  border: 1px solid var(--carbon);
  border-top: 0;
  background: var(--black);
  padding: 26px 20px 30px;
}
.measure__line {
  font-size: 16px;
  line-height: 1.45;
  color: var(--olive);
  max-width: 52ch;
}
/* The crop is wide, so it runs the full width of the block rather than sitting
   in a column beside the copy. */
.measure__fig {
  margin-top: 22px;
  border: 1px solid var(--carbon);
  background: var(--black);
}
.measure__fig img { width: 100%; }

/* Part 3. Text only. Six hairline panels: claw mark, Anton label, one line of
   Barlow Condensed. One column here, two from 560px, three from 900px. */
.spec {
  display: grid;
  gap: 1px;
  background: var(--carbon);
  border: 1px solid var(--carbon);
  border-top: 0;
}
.spec__cell {
  background: var(--onyx);
  padding: 20px 18px 22px;
}
/* The numeral the claw used to occupy, in the corner, as the member area
   does it. Racing Red, tabular, so a column of them lines up. */
.spec__n {
  font-family: var(--display);
  font-size: 0.95rem;
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  margin-bottom: 12px;
}
.spec__label {
  font-family: var(--display);
  font-size: 1.15rem;
  text-transform: uppercase;
  line-height: 1;
  color: var(--parchment);
}
.spec__line {
  margin-top: 7px;
  font-size: 15px;
  line-height: 1.4;
  color: var(--olive);
}

.route {
  margin-top: 22px;
  padding: 16px 18px;
  border: 1px solid var(--carbon);
  background: var(--onyx);
}
.sec--onyx .route { background: var(--black); }
.route p { color: var(--olive); font-size: 16px; }
.route a {
  display: inline-block;
  margin-top: 6px;
  font-family: var(--display);
  font-size: 1.05rem;
  text-transform: uppercase;
  color: var(--parchment);
  border-bottom: 2px solid var(--accent);
  padding-bottom: 2px;
  transition: color var(--t-fast) var(--ease);
}
.route a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   13. Buy
   -------------------------------------------------------------------------- */
.buy { display: grid; gap: 1px; background: var(--carbon); border: 1px solid var(--carbon); }
.buy__col { --buy-gap: 26px; background: var(--black); padding: var(--buy-gap) 20px 30px; }
.sec--onyx .buy__col { background: var(--onyx); }

.price {
  font-family: var(--display);
  font-size: clamp(2.4rem, 12vw, 4rem);
  line-height: 0.92;
  text-transform: uppercase;
  color: var(--parchment);
}
/* The left column reads price, button, reassurance, refund, tight together. */
/* One gap, used three times: above the price block the column's own padding
   provides it, then the same again to the button and to the banner. It read
   unbalanced because these were 12, 18 and 22. */
.buy__cta {
  display: flex;
  width: 100%;
  margin-top: var(--buy-gap);
}
.buy__format {
  margin-top: 12px;
  /* 17px and 1.5, the floor DESIGN.md sets for body copy on a marketing page
     under 800px. It was 16px when this line was a four word fragment, which
     is short enough that the check did not read it as body copy. It is a
     sentence now. */
  font-size: 17px;
  line-height: 1.5;
  color: var(--olive);
}
.buy__includes li {
  position: relative;
  padding: 10px 0 10px 26px;
  border-top: 1px solid var(--carbon);
  font-size: 16px;
  color: var(--parchment);
  line-height: 1.4;
}
.buy__includes li::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 18px;
  width: 10px;
  height: 3px;
  background: var(--accent);
  transform: skewX(-22deg);
}
/* START WITH THE MUSCLE PRIMER is the longest heading on the site, and the
   shared clamp sizes it to overflow its column at every width from 320 up to
   about 960. The two part heading may only break between its parts, never
   inside one, so it is sized down rather than allowed to wrap. 6.5vw keeps the
   line inside the gutters the whole way up, and the 4.75rem ceiling is the
   shared one, so on a wide desktop it matches every other section. */
#trial .h2 .h-top,
#trial .h2 .h-bot {
  font-size: clamp(1.3rem, 6.5vw, 4.75rem);
}
/* Above 800 the band puts the copy in a 46% column beside the artwork, so the
   room stops growing with the viewport and the line has to come down again.
   Smaller than the other section headings on a desk, which is the price of a
   28 character red line, and the alternative was widening the column across
   the tiger. */
@media (min-width: 800px) {
  #trial .h2 .h-top,
  #trial .h2 .h-bot {
    font-size: clamp(1.6rem, 3.3vw, 2.6rem);
  }
}

/* The four lines under the Muscle Primer copy. The buy list's skewed red tick
   and hairline, because it is the page's list style and this section had none
   of its own. The label is the display face, the note Grey Olive after it. */
.cta-band__list {
  list-style: none;
  margin: 22px auto 0;
  padding: 0;
  max-width: 44ch;
  text-align: left;
}
.cta-band__list li {
  position: relative;
  padding: 10px 0 10px 26px;
  border-top: 1px solid var(--carbon);
  font-size: 17px;
  line-height: 1.5;
  color: var(--olive);
}
.cta-band__list li::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 18px;
  width: 10px;
  height: 3px;
  background: var(--accent);
  transform: skewX(-22deg);
}
.cta-band__list li b {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-size: 17px;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--parchment);
}

.buy__smallprint {
  margin-top: 8px;
  font-size: 14px;
  color: var(--olive);
  line-height: 1.5;
  max-width: 52ch;
}

/* --------------------------------------------------------------------------
   14. Lean Blueprint
   DESIGN.md section 2: the Lean Blueprint blue colourway never appears on a
   Mass Protocol page. This teaser therefore runs in the Mass Protocol
   neutrals and is deliberately quieter than everything above it.
   -------------------------------------------------------------------------- */
.lean { border-top: 1px solid var(--carbon); }
.lean .h2 .h-bot { text-shadow: 2px 3px 0 var(--accent-deep); }
.lean__tag {
  font-family: var(--display);
  font-size: clamp(1rem, 4.4vw, 1.3rem);
  text-transform: uppercase;
  color: var(--parchment);
  margin-bottom: 12px;
}
.phases { margin-top: 26px; grid-template-columns: 1fr; }
.phase { padding: 20px 18px 22px; }
.phase__n {
  font-family: var(--display);
  font-size: 2.6rem;
  line-height: 0.86;
  color: var(--accent-deep);
  font-variant-numeric: tabular-nums;
}
.phase__name {
  margin-top: 6px;
  font-family: var(--display);
  font-size: 1.4rem;
  text-transform: uppercase;
  color: var(--parchment);
  line-height: 1;
}
.phase__weeks {
  margin-top: 5px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--olive);
}
.phase__points { margin-top: 14px; }
.phase__points li {
  padding: 7px 0 7px 20px;
  border-top: 1px solid var(--carbon);
  font-size: 15px;
  color: var(--olive);
  position: relative;
}
.phase__points li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 15px;
  width: 8px;
  height: 2px;
  background: var(--accent-deep);
  transform: skewX(-22deg);
}

/* --------------------------------------------------------------------------
   15. Forms. Newsletter and notify.
   -------------------------------------------------------------------------- */
.form { margin-top: 22px; max-width: 480px; }
.form__row { display: grid; gap: 10px; }
.form__field {
  width: 100%;
  min-height: 52px;
  padding: 0 15px;
  background: var(--black);
  border: 1px solid var(--carbon);
  color: var(--parchment);
  font-size: 17px;
  transition: border-color var(--t-fast) var(--ease);
}
.sec--onyx .form__field { background: var(--black); }
.form__field::placeholder { color: var(--olive); }
.form__field:hover { border-color: var(--olive); }
.form__field:focus { border-color: var(--accent); outline: none; }
.form__field[aria-invalid='true'] { border-color: var(--accent); }

.form__err,
.form__ok {
  margin-top: 10px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  min-height: 1.2em;
}
.form__err { color: var(--accent); }
.form__ok { color: var(--parchment); }

.form__smallprint {
  margin-top: 12px;
  font-size: 13px;
  color: var(--olive);
}

/* Replaces the form on success. Parchment, per DESIGN.md section 2. */
.form__done {
  margin-top: 22px;
  font-family: var(--display);
  font-size: clamp(1.25rem, 5.4vw, 1.6rem);
  text-transform: uppercase;
  line-height: 1;
  color: var(--parchment);
}

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */
.footer {
  border-top: 1px solid var(--carbon);
  background: var(--black);
  padding-block: 44px calc(40px + var(--buybar-h));
}
.footer__top { display: grid; gap: 30px; }
.footer__brand { display: flex; align-items: center; gap: 10px; }
.footer__mark { width: 34px; height: 34px; object-fit: contain; }
.footer__name {
  font-family: var(--display);
  font-size: 1.2rem;
  text-transform: uppercase;
  color: var(--parchment);
  line-height: 1;
}
.footer__name b { color: var(--accent); font-weight: 400; }

.footer__colh {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--olive);
  margin-bottom: 12px;
}
.footer__list li { padding: 5px 0; }
.footer__list a {
  font-size: 16px;
  color: var(--parchment);
  transition: color var(--t-fast) var(--ease);
}
.footer__list a:hover { color: var(--accent); }

.legal {
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--carbon);
  display: grid;
  gap: 20px;
}
.legal h3 {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--olive);
  margin-bottom: 8px;
}
.legal p,
.legal li {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--olive);
  max-width: 68ch;
}
.footer__copy {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--carbon);
  font-size: 13px;
  color: var(--olive);
  letter-spacing: 0.06em;
}

/* --------------------------------------------------------------------------
   17. Sticky buy bar. Keeps the buy action one tap away on mobile without
   hijacking the scroll.
   -------------------------------------------------------------------------- */
.buybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-buybar);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px var(--gut) calc(10px + env(safe-area-inset-bottom, 0px));
  /* Solid, for the same reason as the header. */
  background: #070707;
  border-top: 0;
  transform: translateY(110%);
  transition: transform var(--t-mid) var(--ease);
}
.buybar.is-shown { transform: translateY(0); }
.buybar__l { flex: 1; min-width: 0; }
.buybar__t {
  font-family: var(--display);
  font-size: 1.05rem;
  text-transform: uppercase;
  color: var(--parchment);
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.buybar__s {
  margin-top: 3px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--olive);
}
.buybar .btn { min-height: 44px; padding: 0 20px; font-size: 17px; }

/* --------------------------------------------------------------------------
   18. Motion
   DESIGN.md section 6. Permitted: scroll triggered reveals, the strike
   animation, hover transitions, staggered entrances. Everything here is
   opacity and transform only. There is no parallax, no scroll jacking, no
   scroll sequence, no cursor follower and no preloader.
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  will-change: opacity, transform;
}
.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--t-reveal) var(--ease),
              transform var(--t-reveal) var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}

/* Reduced motion: content still appears, it simply does not travel. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  .reveal { opacity: 1; transform: none; }
  .strike__rule { transform: scaleX(1); }
  .strike__truth span { opacity: 1; transform: none; }

  /* The buy bar is NOT forced open here. It used to be, which pinned it over
     the hero from the top of the page for anyone with reduced motion set: a
     second buy button eighty pixels under the first, and the observer that
     decides when the bar is useful bypassed entirely.

     Its transform is its visibility, not an animation. The animation is the
     transition, and the blanket rule above has already reduced that to
     nothing, so the bar now appears instantly at the point it should rather
     than being visible from the start. */
}

/* --------------------------------------------------------------------------
   19. Breakpoints
   Authored at 390px first. Everything below is an addition, never a repair.
   -------------------------------------------------------------------------- */
@media (min-width: 560px) {
  :root { --gut: 28px; }
  .stats { grid-template-columns: repeat(4, 1fr); }
  .spec { grid-template-columns: repeat(2, 1fr); }   /* tablet */
  .form__row { grid-template-columns: 1fr auto; }
  .footer__top { grid-template-columns: 1.4fr 1fr 1fr; }
  .legal { grid-template-columns: repeat(2, 1fr); gap: 26px 34px; }
}

@media (min-width: 800px) {
  :root { --gut: 40px; }
  body { font-size: 18px; }

  .nav__links { display: flex; }
  .nav__in { min-height: 68px; }
  html { scroll-padding-top: 86px; }

  /* The hero carries three more lines of type than it did, so it takes less
     air above them. 54px is what keeps the paragraph and the button inside
     1280x800, which is the tightest desktop the design is held to, with the
     sticky buy bar taking the bottom 65px. */
  .hero { padding-block: 54px var(--sec-pad); }
  .hero__positioning { font-size: 19px; }

  /* Contents runs two up. The list is long and the density is the point. */
  /* Column major. The explicit row track count plus grid-auto-flow: column
     fills the left column top to bottom before starting the right, instead of
     the default row major flow which ran the numbering across the pair.
     --rows comes from build.js, so the split follows the chapter count. */
  .chapters {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(var(--rows, 9), auto);
    grid-auto-flow: column;
    column-gap: 40px;
  }

  /* Anchor. The card column is sized by the card, not by a 50/50 split, and
     the card is capped by height so the two columns finish close together.
     The copy then stretches to meet it, which is what removes the dead space:
     previously the text ran 259px inside an 803px row. */
  .anchor {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 44px;
    padding: 42px 36px 46px;
  }
  .anchor__body { display: flex; flex-direction: column; }
  .anchor__list { flex: 1; display: flex; flex-direction: column; }
  .anchor__list li { flex: 1; display: flex; align-items: center; padding-block: 0; }
  .anchor__list li::before { top: 50%; margin-top: -1.5px; }
  .anchor__fig { margin-top: 0; align-self: start; }
  .anchor__link img { max-height: 430px; width: auto; }

  .measure { padding: 42px 36px 46px; }

  .spec__cell { padding: 24px 22px 26px; }
  .spec__label { font-size: 1.3rem; }
  .spec__line { font-size: 15px; }


  .buy { grid-template-columns: 1fr 1fr; }
  .buy__col { padding: 42px 36px 46px; }

  .phases { grid-template-columns: repeat(3, 1fr); }

  .strike { padding: 40px 0; }
}

/* The signature pair reads across instead of down: the struck lie on the left,
   the correction level with it on the right, across the full content width.
   Columns are uneven because the content is: the lies are short, the
   corrections run to two lines.

   align-items: baseline, not start. The two sit at different type sizes, so
   sharing a baseline is what actually reads as aligned. The initial
   translateY on the correction is a transform, so it does not disturb the
   baseline it is measured from.

   Nothing here touches the strike rule or the correction's entrance: the
   animation is driven by .is-in on .strike, which is unaffected by the
   container becoming a grid. */
@media (min-width: 900px) {
  .spec { grid-template-columns: repeat(3, 1fr); }   /* desktop */

  .strike {
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    gap: 44px;
    align-items: baseline;
  }
  .strike__truth { margin-top: 0; }

  /* Contents: the cover fills the space to the right of the heading. Sized to
     land near the height of the heading block beside it, so it reads as a
     product shot rather than an image the section is built around. The bottom
     margin moves to the wrapper so the gap before the chapter list is the same
     34px whichever of the two columns is taller. */
  .contents__head {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 48px;
    align-items: start;
    margin-bottom: 34px;
  }
  .contents__head .sec-head { margin-bottom: 0; }

  .contents__cover {
    display: block;
    justify-self: end;
    /* Its real aspect is 692:1000, so width alone drives it and the cover is
       never stretched. */
    width: clamp(185px, 16vw, 240px);
    border: 1px solid var(--carbon);
  }
  .contents__cover img { width: 100%; }
}

@media (min-width: 1100px) {
  .hero__in { display: grid; grid-template-columns: 1.35fr 1fr; gap: 50px; align-items: end; }
  .hero__lead { grid-column: 1; }
  .hero__side { grid-column: 2; }
  .stats { margin-top: 0; grid-template-columns: repeat(2, 1fr); }
}

/* From 1600 up the plate has stopped growing: it is capped at 1472, the video's
   own width plus the 15% it takes without falling apart. A 1472 wide frame is
   828 tall at 16:9, so a hero that tall shows the whole thing and crops
   nothing at all, top or bottom. Below 1600 the hero keeps the height it has,
   because the fold at 1280x800 and 1440x900 is what sets it and the buttons
   have only 142px of room to spare there.

   The content is centred in the taller section rather than left at the top,
   so the extra height reads as air around the lockup instead of a gap under
   it. The plate is positioned absolutely, so it is not a flex item and the
   centring cannot move it. */
@media (min-width: 1600px) {
  .hero {
    min-height: 828px;
    display: flex;
    align-items: center;
  }
  .hero__in { width: 100%; }
}

/* --------------------------------------------------------------------------
   20. Mobile pass
   Everything here is scoped to max-width so no desktop rule is touched. Two
   things only: a 16px floor on body copy, and 44px touch targets.

   Not raised, because they are labels and micro type rather than body copy:
   .eyebrow (DESIGN.md section 3 fixes it at 13px), .tele, .stat__l,
   .chapter__p, .anchor__cap, .phase__weeks, .footer__colh,
   .legal h3, .footer__copy, and .form__smallprint (specified at 13px).
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  /* Portrait crop. Wherever the plate is taller than 3:4 the full image height
     is already shown and this is inert, which is the case at every phone width
     measured. It takes over on short viewports, a landscape phone or heavy
     in-app browser chrome, where it keeps the head in the upper third instead
     of centring on the torso. */
  .hero__plate img { object-position: 50% 22%; }
}

@media (max-width: 799px) {
  .spec__line,
  .phase__points li,
  .buy__smallprint,
  .legal p,
  .legal li { font-size: 16px; }

  /* The route link keeps its underline hugging the text; the hit area is
     grown behind it instead, so the design does not change. */
  .route a { position: relative; }
  .route a::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }

  /* Footer links cannot use the same trick: at a 29px pitch, 44px hit areas
     would overlap each other. They are spaced out instead. The 5px li padding
     leaves 10px between adjacent targets. */
  .footer__list a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* The nav sits outside every <section>, so the section-by-section audit
     never reached it and these were left at 38px and 26px. Both are tappable
     links and both were under the minimum. */
  .nav__cta { min-height: 44px; }
  .nav__brand { min-height: 44px; }
}

/* --------------------------------------------------------------------------
   21. Legal documents
   Long form prose, which no marketing section needed. Parchment headings,
   Grey Olive body, Carbon hairlines on near black, square corners. No new
   colour and no third typeface: headings are Anton, everything else Barlow
   Condensed, exactly as DESIGN.md section 3 requires.
   -------------------------------------------------------------------------- */
.doc { max-width: 70ch; }

.doc__meta {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--olive);
  padding-bottom: 18px;
  border-bottom: 1px solid var(--carbon);
}

.doc__sec { padding-top: 34px; }

.doc__h2 {
  font-family: var(--display);
  font-size: clamp(1.35rem, 5.6vw, 1.7rem);
  text-transform: uppercase;
  line-height: 1;
  color: var(--parchment);
  margin-bottom: 14px;
}

.doc__h3 {
  font-family: var(--body);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--parchment);
  margin: 22px 0 8px;
}

.doc p {
  font-size: 17px;
  line-height: 1.62;
  color: var(--olive);
  margin-bottom: 14px;
  text-wrap: pretty;
}

/* The clauses that decide whether someone gets their money back. A hairline
   panel, not a colour, because Racing Red is reserved for buy actions. */
.doc__note {
  padding: 18px 20px;
  margin: 6px 0 20px;
  border: 1px solid var(--carbon);
  border-left: 3px solid var(--accent);
  background: var(--onyx);
  color: var(--parchment);
}

.doc__list { margin: 4px 0 18px; }
.doc__list li {
  position: relative;
  padding: 9px 0 9px 24px;
  border-top: 1px solid var(--carbon);
  font-size: 17px;
  line-height: 1.45;
  color: var(--olive);
}
.doc__list li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 17px;
  width: 9px;
  height: 3px;
  background: var(--accent);
  transform: skewX(-22deg);
}

.doc__company {
  margin-top: 4px;
  border-top: 1px solid var(--carbon);
}
.doc__company li {
  padding: 9px 0;
  border-bottom: 1px solid var(--carbon);
  font-size: 17px;
  color: var(--parchment);
}

@media (min-width: 800px) {
  .doc__sec { padding-top: 44px; }
  .doc__meta { padding-bottom: 22px; }
}

/* --------------------------------------------------------------------------
   18. The year. The map, and the six panels named.

   The artwork is the same file the member area renders on a member's
   dashboard, so what a buyer is shown before joining is what they get after.
   -------------------------------------------------------------------------- */
.map {
  margin-top: 26px;
  border: 1px solid var(--carbon);
  background: var(--black);
  overflow: hidden;
}
.map img { display: block; width: 100%; height: auto; }
.map__hint { display: none; }
/* A short arrow after the word, pointing the way the map scrolls. */
.map__arrow { width: 24px; height: 12px; flex: none; color: var(--accent); }

/* Under 768px the map becomes a horizontally scrollable strip rather than a
   1600px wide image squeezed to 350px, where six panels of detail collapse
   into a smear. Each of the six panels gets about 220px, so the artwork is
   1320px wide and keeps its own proportions.

   Native scrolling only. No snap points, no drag handler, no momentum
   library: DESIGN.md section 6 rules out anything that takes the scroll away
   from the reader, and that applies sideways as well as down. */
@media (max-width: 767px) {
  .map {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .map img {
    width: 1320px;
    max-width: none;
    height: auto;
  }
  /* The figure keeps its own top margin on a desktop, where nothing sits
     between it and the standfirst. Here the hint does, and the 10px belongs
     to the hint. */
  .map { margin-top: 0; }
  .map__hint {
    display: flex;
    align-items: center;
    gap: 8px;
    /* Above the map, 10px clear of it, flush left with the words above. */
    margin: 0 0 10px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--olive);
  }
}

.seasons {
  margin-top: 26px;
  border: 1px solid var(--carbon);
  border-bottom: 0;
  list-style: none;
}
.season {
  padding: 20px 18px 22px;
  border-bottom: 1px solid var(--carbon);
  background: var(--black);
}
.season:nth-child(even) { background: var(--onyx); }

.season__range {
  margin-top: 7px;
  font-family: var(--display);
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-deep);        /* Blood Red carries numerals */
  font-variant-numeric: tabular-nums;
}
/* The name is Parchment for every season. Nothing here says one of them is the
   one you can train today, because the card describes the year rather than the
   build. */
.season__name {
  margin-top: 4px;
  font-family: var(--display);
  font-size: clamp(1.35rem, 6vw, 1.9rem);
  line-height: 1;
  text-transform: uppercase;
  color: var(--parchment);
}
/* The ordinal carries the season's own identity colour, the four from
   DESIGN.md section 2, which is the one place on this page they appear: the
   same colour a member meets when the map and the member area hand them that
   season. It is a label, not chrome, and it is the smallest type on the card,
   so four hues here read as identity rather than as noise. */
.season__ord {
  display: block;
  font-family: var(--body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--olive);
}
.season[data-season='mass-protocol'] .season__ord { color: #DD0A0A; }
.season[data-season='lean-blueprint'] .season__ord { color: #2B6EE3; }
.season[data-season='hybrid-method'] .season__ord { color: #25A05A; }
.season[data-season='fighting-fit'] .season__ord { color: #E07A1B; }
.season__line {
  margin-top: 9px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--olive);
  max-width: 58ch;
}
.seasons__closer {
  margin-top: 20px;
  font-size: 16px;
  line-height: 1.45;
  color: var(--parchment);
  max-width: 52ch;
}

/* One order at every width: the ordinal, the name, the levels it covers, then
   what the season is. The timetable layout that put the range in a left hand
   column is gone with it, because the ordinal now leads the card. */
@media (min-width: 700px) {
  .season { padding: 26px 24px 28px; }
  .season__line { margin-top: 11px; }
}

/* --------------------------------------------------------------------------
   20. Join. The two states of the price column, and the retry line.
   -------------------------------------------------------------------------- */

/* Doors shut. The launch date replaces the price as the headline, and the
   price drops to the supporting line, so nothing looks clickable that is not. */
/* One display heading per section, and the section heading is already the
   skewed red one. So the launch line is Anton in Parchment, upright, with no
   red: it is a statement of fact, not a second headline competing with the
   first. Balanced wrapping keeps it to one line on desktop and two on a
   phone rather than breaking after a single word. */
.price--soon {
  font-family: var(--display);
  font-size: clamp(1.45rem, 5.6vw, 2rem);
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--parchment);
  text-wrap: balance;
}

/* The includes list takes a Grey Olive eyebrow rather than a second skewed
   heading inside the card. */
.buy__includes-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--olive);
  margin-bottom: 14px;
}

.form--join { margin-top: 18px; }

.buy__retry {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--carbon);
  font-size: 14px;
  line-height: 1.45;
  color: var(--olive);
}


/* The Companies Act trading disclosure on /terms and /contact. */
.doc__trader {
  padding: 14px 16px;
  border: 1px solid var(--carbon);
  background: var(--onyx);
  font-size: 15px;
  line-height: 1.5;
  color: var(--parchment);
}

/* --------------------------------------------------------------------------
   21. The newsletter slide-in.

   A card bottom right on desktop, a bottom sheet on a phone. Deliberately not
   a modal: no scroll lock, no focus trap, no full page dim. DESIGN.md section
   6 is blunt that anything getting between a reader and the page costs sales,
   and most of this traffic arrives inside an in-app browser.

   It ships with the `hidden` attribute and the script removes it at the
   trigger point, so with JavaScript off it never appears rather than sitting
   open with no way to shut it.
   -------------------------------------------------------------------------- */
.slidein {
  position: fixed;
  z-index: 60;
  background: var(--carbon);
  /* The one red on the panel. A 3px top border, not a fill: the red fill is
     reserved for buy actions. */
  border-top: 3px solid var(--accent);
  color: var(--parchment);
  padding: 20px 18px 18px;
  box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.55);
}
.slidein[hidden] { display: none; }

/* Phone: a bottom sheet, full width, never taller than 40% of the viewport.
   The cap is the point. A sheet that grows past its content would cover the
   page a reader is in the middle of. */
@media (max-width: 719px) {
  .slidein {
    left: 0;
    right: 0;
    /* Above the sticky buy bar, never under it. The script publishes the
       bar's height as --mt-bar and sets it to 0 when the bar is hidden. */
    bottom: var(--mt-bar, 0px);
    max-height: 40vh;
    overflow-y: auto;
    /* Clear of the sticky buy bar, and of the home indicator on an iPhone. */
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    transform: translateY(100%);
  }
}

/* Desktop: a 360px card in the bottom right corner. */
@media (min-width: 720px) {
  .slidein {
    right: 20px;
    bottom: calc(20px + var(--mt-bar, 0px));
    width: 360px;
    max-width: calc(100vw - 40px);
    border: 1px solid var(--carbon);
    border-top: 3px solid var(--accent);
    transform: translateY(calc(100% + 28px));
  }
}

/* 200ms, under the 250ms ceiling. Transform and opacity only, so it composites
   rather than reflowing the page under it. */
.slidein {
  opacity: 0;
  transition: transform 200ms ease, opacity 200ms ease;
  will-change: transform;
}
.slidein.is-open {
  transform: translateY(0);
  opacity: 1;
}

.slidein__x {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 44px target, per the mobile pass. */
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--olive);
  cursor: pointer;
}
.slidein__x:hover,
.slidein__x:focus-visible { color: var(--parchment); }

.slidein__eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent-deep);
  padding-right: 40px;
}
.slidein__h {
  margin-top: 8px;
  font-family: var(--display);
  font-size: clamp(1.3rem, 5vw, 1.6rem);
  line-height: 0.98;
  text-transform: uppercase;
  color: var(--parchment);
  padding-right: 40px;
}
.slidein__line {
  margin-top: 8px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--olive);
}
.slidein__form {
  display: grid;
  gap: 9px;
  margin-top: 14px;
}
.slidein__form .form__field { width: 100%; }
.slidein__form .form__err:empty { display: none; }

/* Parchment on Carbon with a Racing Red hairline. Not a red fill: DESIGN.md
   section 2 reserves that for buy actions, and this is not one. */
.btn--outline {
  background: var(--carbon);
  border-color: var(--accent);
  color: var(--parchment);
}
.btn--outline:hover { background: var(--black); }
.btn--outline:active { transform: translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .slidein { transition: none; }
}

/* The line that stands where a form would be while its list is unconfigured.
   Stated plainly, in Parchment: the visitor is told when it opens rather than
   given a field that accepts an address and discards it. */
.news__launch {
  margin-top: 20px;
  font-family: var(--display);
  font-size: clamp(1.3rem, 5vw, 1.75rem);
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--parchment);
}

/* The hero's second slot while the waitlist is gated. There is no second
   action to offer, only a date, so it is stated as text rather than dressed as
   a button that goes nowhere useful. */
.hero__when {
  font-family: var(--display);
  font-size: clamp(1rem, 3.6vw, 1.2rem);
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--olive);
  padding: 6px 0;
}

/* ==========================================================================
   The mobile pass.

   One block, at the end, so it wins over the rules above it without raising
   their specificity, and so the whole pass reads in one place. Everything
   that changes a phone is inside max-width: 799px; the type floor is the one
   rule that applies at every width, because nothing anywhere goes under 13px.
   tools/verify-mobile.js holds all of it in place.
   ========================================================================== */

/* The type floor. Labels and eyebrows are 13px at the smallest. */
.stat__l,
.season__ord,
.map__hint,
.buy__includes-label,
.buybar__s,
.footer__colh,
.legal h3,
.slidein__eyebrow { font-size: 13px; }

/* A button label never wraps. */
.btn { white-space: nowrap; }

/* The slide-in carries the newsletter heading's two part treatment at the
   panel's own size, not the section's display size. */
.slidein .h2 { margin-bottom: 0; }
.slidein .h2 .h-top,
.slidein .h2 .h-bot { font-size: inherit; line-height: inherit; }

@media (max-width: 799px) {
  /* The hero ends on its stats and takes the same bottom as every section,
     so hero to platform is the same join as every other pair. The footer
     clears whatever is on the bottom edge. */
  .hero { padding-bottom: var(--sec-pad); }
  .footer { padding-bottom: calc(40px + var(--mt-bottom, var(--buybar-h))); }

  /* Body copy: 17px and a 1.5 line height on the marketing pages. */
  .season__line,
  .seasons__closer { font-size: 17px; line-height: 1.5; }
  .lede,
  .legal p,
  .doc p,
  .doc li { line-height: 1.5; }

  /* FAQ questions sit 8px apart, so a thumb meant for one does not land on
     the next. */
  .qa__item + .qa__item { margin-top: 8px; }

  /* The slide-in on a phone: the bottom bar's place, one compact block no
     taller than 120px. Eyebrow and heading above, the address and SUBSCRIBE
     on one line, no body. */
  .slidein {
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    bottom: 0;
    max-height: 120px;
    overflow: hidden;
    border: 0;
    border-top: 3px solid var(--accent);
    padding: 10px var(--gut) calc(10px + env(safe-area-inset-bottom, 0px));
    transform: translateY(100%);
  }
  .slidein__x { top: 2px; right: 4px; }
  .slidein__eyebrow { padding-right: 48px; line-height: 1.2; }
  .slidein__h {
    margin-top: 3px;
    padding-right: 48px;
    font-size: clamp(15px, 4.6vw, 20px);
    line-height: 1.15;
    white-space: nowrap;
  }
  .slidein .h2 .h-top { display: inline; }
  .slidein .h2 .h-bot { display: inline-block; margin-left: 0.3em; text-shadow: none; }
  .slidein__line { display: none; }
  .slidein__form {
    grid-template-columns: 1fr auto;
    gap: 8px;
    margin-top: 8px;
  }
  .slidein__form .form__field { min-height: 44px; font-size: 16px; }
  .slidein__form .btn { min-height: 44px; padding: 0 14px; font-size: 16px; }
  body.mt-slidein-open .buybar { transform: translateY(110%); }
  /* A 120px sheet and a header cannot both fit inside 22% of a 568px or
     740px screen. The sheet only ever shows past the FAQ, at the end of the
     page, so the header steps out of the way while it is open and returns
     the moment it is dismissed or tucked away. */
  .nav { transition: transform var(--t-mid) var(--ease); }
  body.mt-slidein-open .nav { transform: translateY(-100%); }
}

@media (max-width: 599px) {
  /* The header is one row and it carries the offer: the mark, the full
     MEAN TRUTH FITNESS wordmark with FITNESS in red as on desktop, LOGIN as
     plain type, and JOIN FREE as a compact Racing Red button. The wordmark
     takes the room it needs down to a 13px floor; LOGIN giving up its button
     box is what buys the rest. */
  .nav__name { white-space: nowrap; font-size: clamp(13px, 3.9vw, 15px); }
  .nav__in { gap: 8px; min-height: 52px; }
  .nav__brand { gap: 6px; }
  .nav__mark { width: 22px; height: 22px; }
  /* Plain type, not a box. It keeps a 44px tap target with no padding of its
     own, so it costs the row only its own words. */
  .nav .btn--ghost.nav__cta {
    padding: 0;
    border: 0;
    /* 44px wide so the tap target holds, though the type is all that shows. */
    min-width: 44px;
    font-size: 15px;
    letter-spacing: 0.06em;
  }
  /* 40px tall, a 15px label, and never wrapped. */
  .nav .btn--primary.nav__cta--join {
    display: inline-flex;
    width: auto;
    min-height: 40px;
    padding-inline: 12px;
    font-size: 15px;
    white-space: nowrap;
  }
}

/* At 320 the row is 2px over with the mark at 22, so the mark steps down to
   18 and the mark to wordmark gap to 4. The gap between LOGIN and JOIN FREE
   stays at 8, which is the minimum between two tap targets, and the wordmark
   never shrinks below its 13px floor or loses FITNESS. */
@media (max-width: 340px) {
  .nav__mark { width: 18px; height: 18px; }
  .nav__brand { gap: 4px; }

  /* Primary buttons are the full width of their column, 52px tall, with a
     label of at least 16px on one line. */
  .btn--primary {
    width: 100%;
    min-height: 52px;
    padding-inline: 16px;
    font-size: clamp(16px, 5.2vw, 20px);
  }
  /* The bar's button sits beside the bar's text, so its column is its own. */
  .buybar { padding-block: 6px calc(6px + env(safe-area-inset-bottom, 0px)); }
  .buybar .btn--primary { width: auto; min-height: 52px; font-size: 17px; padding-inline: 18px; }
}

/* A phone turned on its side. The platform player followed the page width to
   764 by 390 at 844 by 390, taller than the space under the 68px header, so
   its top was always covered. Here it takes the width the height allows, at
   the poster's own 1240 by 632, and sits centred. */
@media (orientation: landscape) and (max-height: 500px) {
  .player {
    width: min(100%, calc((100vh - 92px) * 1240 / 632));
    margin-inline: auto;
  }
}

/* ==========================================================================
   Homepage and login changes.
   ========================================================================== */

/* Each part of a two part heading is unbreakable: under 800 a heading may
   break between its parts and nowhere else. */
.h2 .h-top,
.h2 .h-bot { white-space: nowrap; }

/* The trial band's heading is exactly two lines at every width:
   START WITH 7 DAYS in Parchment, ON US FOR FREE. skewed in Racing Red. */
.cta-band .h2 .h-top,
.cta-band .h2 .h-bot { display: block; }

/* The artwork under START THE PRIMER: the width of the pricing column,
   square corners. */
.buy__art {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--buy-gap, 26px);
  border-radius: 0;
}

/* FAQ answers run the full width of their item: from the question's left
   edge to the plus sign's right edge. */
.qa__a { max-width: none; }

/* The newsletter, centred as one block: claw, eyebrow, heading, body and a
   form no wider than 560px. */
#newsletter .sec-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
#newsletter .h2 .h-bot { transform-origin: center bottom; }
/* The head gives up its margin here because the form under it is hidden
   until the function answers. The form carries the space itself, so a hidden
   form leaves nothing under the standfirst. */
#newsletter .sec-head { margin-bottom: 0; }
/* A flex column, so the heading's margin and the rule's do not collapse the
   way they do in every other head. The heading's margin is the gap alone. */
#newsletter .sec-head .slash { margin-top: 0; }
#newsletter .form {
  margin-top: 34px;
  max-width: 560px;
  margin-inline: auto;
  text-align: center;
}

@media (min-width: 800px) {
  /* Every two part section heading on one line: Parchment, then the skewed
     Racing Red part inline. The newsletter's ONE HARD TRUTH. NO SUGAR
     COATING. is the longest, and holds one line at 1024 at 66.5px, so the
     size is the content column times 0.0705, never above the 76px it was. */
  .sec-head .h2 .h-top,
  .sec-head .h2 .h-bot {
    display: inline;
    font-size: min(76px, calc((min(100vw, 1240px) - 80px) * 0.0705));
  }
  .sec-head .h2 .h-bot {
    display: inline-block;
    margin-left: 0.25em;
  }

  /* Standfirsts run the full width of the content column, at 22px so the
     longer line stays readable. No empty right hand half under a heading. */
  .sec-head .lede {
    max-width: none;
    font-size: 22px;
    line-height: 1.5;
  }

  /* The trial band's two lines share its 46% text column with the art, so
     they scale with that column: START WITH 7 DAYS is the longer line. */
  .cta-band .h2 .h-top,
  .cta-band .h2 .h-bot {
    font-size: min(76px, calc((min(100vw, 1240px) - 80px) * 0.0636));
  }
}

/* THE PLATFORM video plays muted on its own, and this is the way to sound: a
   square Racing Red button in the player's lower left, 48px tall, gone once
   the sound is on. It is a single small block, so it stays well inside the
   page's red budget. */
.player { position: relative; }
.player__sound {
  position: absolute;
  left: 12px;
  bottom: 56px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 18px;
  border: 0;
  border-radius: 0;
  background: var(--accent);
  color: var(--parchment);
  font-family: var(--display);
  font-size: 18px;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.player__sound:hover { background: var(--accent-deep); }
.player__sound:focus-visible { outline: 2px solid var(--parchment); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   Section head on phones. The stack of claw, eyebrow, heading, red rule and
   standfirst takes about a third less air: claw to eyebrow 16px to 10px,
   heading to rule and rule to standfirst 22px to 14px.

   The eyebrow's line box used to be closed up to its type as well, at 1.1.
   At 13px with this letter spacing the ink wants all 14px of that box, so
   the cap tops sat flush with its top edge and JOIN read as cut off rather
   than as type. It gets its leading back; the 4px that costs is taken off
   the claw above it, so the stack is the same height as it was.
   -------------------------------------------------------------------------- */
@media (max-width: 599px) {
  .sec-head .claw { margin-bottom: 6px; }
  .sec-head .eyebrow { line-height: 1.45; margin-bottom: 2px; }
  .sec-head .h2 { margin-bottom: 14px; }
  .sec-head .slash { margin-top: 14px; margin-bottom: 14px; }
}

/* --------------------------------------------------------------------------
   Season row artwork. Each row of the year carries its season's tiger,
   cut by tools/season-art.js. Decorative: the words say it all.

   Phone: a 220px band across the top of the row, bled to its hairline
   borders, fading into the row's own colour at the bottom, with the words
   below it and never over it. The picture is top aligned, so the head is
   never clipped: under 560px the phone crop, from 560px the wide cut.
   Finish shows its whole master at 3:2 instead, glows and fists and all.

   800 and up, the seated rows: the words stay where they are, on the left,
   and the wide cut fills the right 60% of the row, anchored right so the
   tiger is never trimmed on his side, fading into the row's colour on its
   left edge. The cut runs from above the ears to the wrapped hands, 2.02
   to 1, and rows are at least 304px tall to 1099 and 344px from 1100: the
   widest band is then never wider than the cut, so none of it is trimmed
   top or bottom.

   800 and up, Finish: the finale. The cut runs across the full width of a
   460px row, from above his ears to just below the four season glows,
   fitted to the row's width and sitting on its foot, so the glows are low
   on the left and he stands on the right at every width. Where the row is
   taller than the picture, its top edge fades into the row's colour. The
   words sit top left over the dark sky, with nothing behind them.
   -------------------------------------------------------------------------- */
.season { position: relative; overflow: hidden; --season-bg: var(--black); }
.season:nth-child(even) { --season-bg: var(--onyx); }
.season__art {
  position: relative;
  margin: -20px -18px 16px;
  height: 220px;
  background: var(--season-bg);
}
.season[data-season='finish'] .season__art { height: auto; aspect-ratio: 900 / 600; }
.season__art picture { display: contents; }
.season__art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
.season__art::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent 45%, var(--season-bg) 100%);
}
@media (min-width: 560px) {
  .season__art img { object-position: right top; }
  .season[data-season='finish'] .season__art img { object-position: center; }
}
@media (min-width: 700px) {
  .season__art { margin: -26px -24px 18px; }
}
@media (min-width: 800px) {
  .season { min-height: 304px; }
  .season > :not(.season__art) { position: relative; }
  .season__art {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 60%;
    height: auto;
    margin: 0;
    aspect-ratio: auto;
  }
  .season__art img { object-position: right center; }
  /* The words run to about 57% of the row at 800, so the first 30% of the
     band stays the row's own colour and the art arrives after them. */
  .season__art::after {
    background: linear-gradient(to right, var(--season-bg) 0%, var(--season-bg) 30%, transparent 62%);
  }
}
@media (min-width: 1100px) {
  .season { min-height: 344px; }
  /* From 1100 the words end before the band starts, so the fade is short. */
  .season__art::after {
    background: linear-gradient(to right, var(--season-bg) 0%, var(--season-bg) 6%, transparent 48%);
  }
}
@media (min-width: 800px) {
  .season[data-season='finish'] { min-height: 460px; }
  .season[data-season='finish'] .season__art {
    width: 100%;
    left: 0;
    aspect-ratio: auto;
  }
  .season[data-season='finish'] .season__art img {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: auto;
    object-fit: fill;
    /* Where the row is taller than the picture, its top edge fades in
       rather than stopping on a line. The ears sit 5% down, below it. */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 4%);
    mask-image: linear-gradient(to bottom, transparent 0, #000 4%);
  }
  /* No wash behind the words. The sky there is dark enough on its own:
     the paragraph measures 4.9 to 5.1 to 1 with nothing behind it, from 800
     to 1920, and verify-season-art holds it at 4.5. */
  .season[data-season='finish'] .season__art::after { background: none; }
}

/* --------------------------------------------------------------------------
   Two part headings on a phone. They were a block each, so every one of them
   broke in two however short it was, and THE PLATFORM read as THE above
   PLATFORM. They now run on one line whenever the pair fits the content
   column at the size the phone already uses, and break between the two parts
   when it does not. Each part is nowrap, so a break can only ever land
   between them, at the <wbr> build.js puts there. Sizes are untouched, so a
   heading that only fits by shrinking still breaks. Desktop is unchanged: it
   sets these inline from 800 up already.
   -------------------------------------------------------------------------- */
@media (max-width: 799px) {
  main .h2:not(.h2--block) .h-top,
  main .h2:not(.h2--block) .h-bot {
    display: inline;
    white-space: nowrap;
  }
  main .h2:not(.h2--block) .h-bot {
    display: inline-block;
    margin-left: 0.22em;
  }
}

/* --------------------------------------------------------------------------
   The trial band's note on a phone. The button runs the full width of the
   column, so a line left aligned under it hangs off to one side. The row
   becomes a column under 600: the button, then the tick and its words
   centred together as one unit, 12px under it. From 600 the button hugs its
   words again and the note sits beside it, as it does on a desktop.
   -------------------------------------------------------------------------- */
@media (max-width: 599px) {
  .cta-band__act {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .cta-band__act .btn { width: 100%; }
  .cta-band__note { justify-content: center; }
}
