/* ==========================================================================
   TFCS.AFRIC — The Film & Content School Africa
   Black ground, white type, one accent. Yellow appears in exactly one
   place: the Apply CTA. Nowhere else.
   ========================================================================== */

/* ---------- FONTS ----------
   Delight, by Måns Grebäck / supplied by the client. fsType=0 (installable,
   no embedding restriction). NOTE: fsType is the font's technical permission
   bit, NOT the EULA — confirm the webfont licence separately. See README. */
@font-face {
  font-family: 'Delight';
  src: url('assets/fonts/delight-regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Delight';
  src: url('assets/fonts/delight-bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Delight';
  src: url('assets/fonts/delight-black.woff2') format('woff2');
  font-weight: 900; font-style: normal; font-display: swap;
}

/* ---------- THE HEADLINE AMPERSAND — BLOCKED, see README ----------
   The & in "The Film & Content School Africa" is meant to be Mezzotint CF.
   Mezzotint CF is Adobe-Fonts-activated on this machine (The Type Founders);
   that licence covers desktop use and Adobe's own web CDN, NOT self-hosting a
   subset. Nothing has been extracted. Until a webfont licence lands, the &
   renders in Delight, which looks correct — just not distinct.

   To enable: drop a licensed assets/fonts/mezzotint-amp.woff2 (subset to
   U+0026 only, 2-4KB) in place and uncomment this whole block.

   @font-face {
     font-family: 'Mezzotint CF';
     src: url('assets/fonts/mezzotint-amp.woff2') format('woff2');
     unicode-range: U+0026;
     font-display: block;
   }
   .hero-amp {
     font-family: 'Mezzotint CF', var(--sans);
     font-weight: 400;
     font-size: 1.12em;
     vertical-align: -0.015em;
     letter-spacing: 0.012em;
   }
   Those last four are a starting point. A serif ampersand dropped into a
   heavy sans line reads small and floats high — tune by eye against the
   comp, not by matching the numeric size.
   ------------------------------------------------------------------- */

/* ---------- TOKENS ---------- */
:root {
  /* Three colours and a text-on-accent. That is the whole system. */
  --ground:    #000000;
  --paper:     #FFFFFF;
  --accent:    #FFEA33;  /* sampled from the supplied comp */
  --on-accent: #000000;  /* 17.07:1 on accent. NEVER white — white is 1.23:1 */

  /* Supporting ladder, re-derived against pure black. */
  --body:    #E9E9E9;  /* running text        17.30:1 */
  --mute:    #949494;  /* captions, labels     6.92:1  / boundary 6.92:1 */
  --rule:    #303030;  /* hairlines — decorative only */
  --surface: #262626;  /* raised fill  — timeline: your track */
  --sunk:    #141414;  /* recessed fill — timeline: quiet */

  --sans: 'Delight', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --t-2: 0.6875rem;
  --t-1: 0.8125rem;
  --t0:  clamp(1rem, 0.965rem + 0.15vw, 1.0625rem);
  --t1:  clamp(1.125rem, 1.06rem + 0.3vw, 1.3125rem);
  --t2:  clamp(1.375rem, 1.24rem + 0.6vw, 1.75rem);
  --t3:  clamp(1.75rem, 1.5rem + 1.05vw, 2.375rem);
  --t4:  clamp(2.125rem, 1.72rem + 1.75vw, 3.125rem);
  --t5:  clamp(2.5rem, 1.9rem + 2.6vw, 4rem);

  /* ---------- THE FRAME ----------
     25px on the left, the right AND the top. 40px at the foot, for the hero
     partner strip only — that asymmetry is deliberate, do not normalise it.
     The frame is not the measure: text caps live on the text (--measure,
     30ch on the subhead), never on the gutter. */
  --edge:        25px;
  --edge-bottom: 40px;
  /* landscape notch must never clip content */
  --edge-l: max(var(--edge), env(safe-area-inset-left, 0px));
  --edge-r: max(var(--edge), env(safe-area-inset-right, 0px));
  --measure: 34rem;   /* body copy cap, independent of the gutter */

  --sec:  clamp(3rem, 5.6vw, 5.25rem);
  /* The mark is set as a ratio of the frame, not a fixed height: ~9.5vw,
     floored at 80 and capped at 150. That is a shade under the comp's 11.4%
     because the comp has no header furniture and this one carries the pill. */
  --head-mark-h: clamp(80px, 9.5vw, 150px);
  --head-mark-compact: 44px;          /* also the minimum tap target */
  /* Notch guard. The side gutters already do this via --edge-l/--edge-r. */
  --head-pad-top: max(var(--edge), env(safe-area-inset-top, 0px));
  /* --head-h is GONE. It used to be a literal px value that script.js
     parse-ed, and it had to be re-derived by hand at four breakpoints. Now
     that the header changes height on scroll, a hand-maintained literal
     would go stale the moment the compact state kicked in and every anchor
     would land short. This is derived instead, so it is right by
     construction — including on a notched device, where --head-pad-top
     grows and this grows with it.

     It is deliberately the COMPACT height: every anchor target sits more
     than 120px down the page, so the header is always compact by the time
     a jump lands. The taller resting header only exists over the hero,
     where nothing anchors. */
  --head-compact-h: calc(var(--head-pad-top) + var(--head-mark-compact) + var(--edge));

  --lane-w: 92px;
  --week-w: 84px;
  --lane-h: 118px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------- RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  background: var(--ground);
  color: var(--body);
  font-family: var(--sans);
  font-size: var(--t0);
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; }

/* ---------- FOCUS ----------
   White ring, never accent. The black halo keeps it visible where the ring
   lands on the hero image or on the yellow pill (white on yellow is 1.23:1). */
:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
  box-shadow: 0 0 0 6px rgba(0,0,0,0.75);
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

.skip {
  position: absolute; left: 0; top: 0; transform: translateY(-120%);
  background: var(--paper); color: var(--ground);
  padding: .75rem 1.25rem; z-index: 200;
  font-size: var(--t-1); font-weight: 700; text-decoration: none;
}
.skip:focus { transform: translateY(0); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- LAYOUT ---------- */
/* No max-width: the 25px frame runs edge to edge at every width. Long lines
   are held by per-element measure caps, not by a centred container. */
.wrap { width: 100%; max-width: none; margin-inline: auto; padding-inline: var(--edge-l) var(--edge-r); }
/* full-bleed media ignores the gutter and runs to 0 */
.wrap .slot-bleed { margin-inline: calc(-1 * var(--edge-l)) calc(-1 * var(--edge-r)); }
.wrap-narrow { max-width: 820px; }
.sec { padding-block: var(--sec); }

/* ---------- TYPE ---------- */
.h2 {
  font-size: var(--t4); font-weight: 900; line-height: 1.0;
  letter-spacing: -0.032em; color: var(--paper); text-wrap: balance;
}
.h2-big { font-size: var(--t5); }
.h3 {
  font-size: var(--t2); font-weight: 700; line-height: 1.1;
  letter-spacing: -0.022em; color: var(--paper);
}
.eyebrow, .track-n, .tag, .tl-lane-n, .blk-t, .blk-w, .tl-hint, .kit-h, .partners-label {
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700; font-size: var(--t-2);
}
.sec-head { margin-bottom: clamp(1.75rem, 3.4vw, 2.5rem); }
.sec-intro { color: var(--mute); font-size: var(--t1); margin-top: 1rem; max-width: 46ch; line-height: 1.45; }
.cap { color: var(--mute); font-size: var(--t-1); line-height: 1.55; }

/* ---------- HEADER — floats over everything, always ----------
   No fill, no blur, no border, no shadow, in either state. The mark and the
   pill are the only fixed elements on the page; legibility over light content
   is carried by the mark's own drop-shadow (see .head-mark), not by a bar. */
.site-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  padding-top: var(--head-pad-top);
  padding-bottom: var(--edge);
  background: none; border: 0;
  /* the bar is invisible, so it must not eat clicks meant for the content
     running underneath it. The two real controls opt back in. */
  pointer-events: none;
}
.head-inner { display: flex; align-items: flex-start; gap: 1rem; min-height: var(--head-mark-h); }
.head-mark, .site-head .btn { pointer-events: auto; }
.head-mark { margin-right: auto; display: block; line-height: 0; }
.head-logo { height: var(--head-mark-h); width: auto; }

/* Two stacked shadows: a tight one for edge definition, a wide soft one for
   ambient density. On the SVG mark drop-shadow follows the alpha channel, so
   it traces the crocodile and reel outline instead of boxing them.

   The values are SCALED to the state. Tested at 3x over a blown-out frame:
   the 16px ambient blur is right against a 150px mark and reads as a lift,
   but against the 44px compact mark it is 36% of the mark's own height and
   turns into a grey cloud. The linework survives either way — the spokes and
   teeth stay separate — but the compact mark is visibly cleaner on the
   smaller pair. A fixed shadow cannot serve a mark that changes size 3.4x. */
.head-mark, .head-nav a {
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.55))
          drop-shadow(0 4px 16px rgb(0 0 0 / 0.45));
}

/* ---------- COMPACT — scroll distance only ----------
   Triggered at 120px of scroll, released at 96px. The 24px dead band is there
   so parking on the threshold cannot flutter the 200ms transition; it is still
   a pure function of scrollY, with no dependence on scroll direction and no
   dependence on which section is in view. */
.site-head.is-compact { --head-mark-h: var(--head-mark-compact); }
.site-head.is-compact .head-mark, .site-head.is-compact .head-nav a {
  filter: drop-shadow(0 1px 1.5px rgb(0 0 0 / 0.60))
          drop-shadow(0 2px 6px rgb(0 0 0 / 0.50));
}
.site-head.is-compact .btn-apply {
  min-height: var(--head-mark-compact);
  padding-inline: 1.3rem;
  font-size: var(--t-1);
}
.head-logo { transition: height .2s var(--ease); }
.head-mark { transition: filter .2s var(--ease); }
/* prefers-reduced-motion zeroes every transition-duration globally further
   down, so under that setting the header simply snaps between the two states. */

/* ---------- BUTTONS ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 52px; padding: 0 1.9rem;
  font-size: var(--t0); font-weight: 700; letter-spacing: -0.005em;
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  border-radius: 999px;
  transition: background-color .22s var(--ease), color .22s var(--ease),
              border-color .22s var(--ease), filter .22s var(--ease);
}
/* THE ONE PLACE YELLOW APPEARS */
.btn-apply { background: var(--accent); color: var(--on-accent); }
.btn-apply:hover { filter: brightness(1.07); }
.btn-apply:active { filter: brightness(0.94); }

.btn-outline { border-color: var(--paper); color: var(--paper); background: transparent; }
.btn-outline:hover { background: var(--paper); color: var(--ground); }
.btn-outline .arr { flex: none; }
.btn-sm { min-height: 44px; padding: 0 1.35rem; font-size: var(--t-1); }
/* The header pill is full-size at rest and never drops below 44x44 compact —
   42px, its old height, was already under the tap-target floor. */
.site-head .btn-apply {
  min-height: 52px; padding-inline: 1.9rem; font-size: var(--t0);
  transition: background-color .22s var(--ease), filter .22s var(--ease),
              min-height .2s var(--ease), padding .2s var(--ease),
              font-size .2s var(--ease);
}
.btn-block { width: 100%; }

/* ==========================================================================
   HERO
   ========================================================================== */
/* Mobile is full-bleed too: the image fills the whole viewport height exactly
   as it does on desktop, and every piece of content sits over it. The >=1024
   query below only RETUNES this layout (crop, scrim shape, headline scale,
   the subhead grid) — it no longer switches a stacked block into an overlay. */
.hero { position: relative; background: var(--ground); min-height: 100svh; display: flex; }

.hero-media { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; background: var(--ground); }
.hero-media picture { display: block; width: 100%; height: 100%; }
.hero-media img, .hero-media video { width: 100%; height: 100%; object-fit: cover; }
/* Mobile crops much tighter than desktop: the portrait frame throws away the
   sides and fills with head and shoulders. 60% holds the face just left of
   the crop's centre so it clears the bottom stack; the 30% is a no-op on tall
   phone viewports (the landscape master never overflows vertically there) but
   keeps the intent explicit and takes effect on shorter/landscape frames.
   Desktop restores 65% 50% in the >=1024 block. */
.hero-img { object-position: 60% 30%; }

/* Bottom-anchored scrim — a floor the type stands on, not a full-frame dim.
   The whole lower half of the frame is the subject's LIT gray jacket (sampled
   maxL ~0.52, rgb ~199) — white type over it measured ~1.9:1 raw, so the
   plain to-top/0.85/0.6/0 wedge the brief sketched was not enough. This holds
   density right through the headline / subhead / button / strip band, then
   fades out across the near-black gap under the chin (30–45% from the top,
   sampled maxL ~0.02) and is fully gone by 72% up — so the face and the
   header both sit on untouched image. Measured composited ratios are in the
   commit message; every element clears 4.5:1. Re-tune if the image changes. */
.hero-scrim { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top,
    rgb(0 0 0 / 0.90)  0%,
    rgb(0 0 0 / 0.80) 22%,
    rgb(0 0 0 / 0.68) 38%,
    rgb(0 0 0 / 0.55) 52%,
    rgb(0 0 0 / 0.28) 60%,
    rgb(0 0 0 / 0)    72%);
}

/* Content hugs the bottom over the image. 40px at the foot, not 25 — the
   partner strip is the last child, so this padding IS the strip bottom offset.
   The top pad clears the resting (non-compact) header; with justify flex-end
   the stack grows up from the foot and lands its top near ~55% of the frame. */
.hero-inner {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; justify-content: flex-end;
  width: 100%; min-height: 100svh;
  /* Foot holds the 40px strip offset ABOVE the home indicator: on a notched
     device the safe-area inset is added so the strip is never clipped; it is
     0 elsewhere, so the offset stays a true 40px. */
  padding-block: calc(var(--head-pad-top) + var(--head-mark-h) + 1.5rem)
                 calc(var(--edge-bottom) + env(safe-area-inset-bottom, 0px));
}
.hero-lede { position: relative; }

.hero-headline {
  /* Sized so the longest line, "School Africa", fills the gutter width and
     stays on ONE line (three lines total), which is what the comp shows. At
     375 that measured a 50.7px ceiling before it wraps; 13vw lands just under
     it (~48.7px) with margin for the webfont, and the raised 3rem floor holds
     the same size below 369px. Bigger than this wraps the third line to four.
     Desktop overrides this below. */
  font-size: clamp(3rem, 13vw, 7.5rem);
  font-weight: 900;
  line-height: 0.92;
  letter-spacing: -0.035em;
  color: var(--paper);
}
.hero-amp { font-family: var(--sans); }

.hero-sub {
  /* Sits close under the headline on mobile — tighter than desktop's spacing.
     ~4 lines at this width. Desktop re-pins it to the headline's optical
     middle in the grid below (margin-top:0, width 30ch). */
  margin-top: .85rem;
  font-size: var(--t-1); font-weight: 700; line-height: 1.45;
  color: var(--paper); max-width: 30ch;
}
/* See all tracks runs near full-width inside the gutter on mobile and is
   noticeably taller than the desktop pill. Desktop restores auto width / 52px. */
.hero-actions { margin-top: clamp(1.5rem, 4vw, 2rem); display: flex; }
.hero-actions .btn-outline { width: 100%; min-height: 60px; }

/* ---------- SUPPORTED BY ----------
   Four supplied wordmarks, white on black. Each SVG is drawn at its own
   intrinsic height (--h, set inline) times --logo-u, a shared px-per-unit
   scale — so the four keep their relative optical weight at every width
   instead of being force-fitted to one box height. */
.partners { margin-top: clamp(2.25rem, 6vw, 3.5rem); }
.partners-label { color: var(--paper); opacity: .6; margin-bottom: .9rem; }
.partner-list {
  /* Four marks on ONE row, gutter to gutter, as the comp shows — a credit
     line, so they render small and that is correct. --logo-u is floored low
     enough that all four (widest is Clan Yujo at 192u) plus the gaps clear
     375's inner width; space-between spreads them and holds the left mark on
     the 25px line. The >=560 rule below lifts --logo-u back up. */
  --logo-u: 0.55px;
  display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between;
  gap: clamp(.5rem, 2.5vw, 1.2rem);
}
.partner { display: flex; align-items: center; min-width: 0; }
.partner-logo {
  display: block; width: auto; max-width: 100%;
  height: calc(var(--h, 24) * var(--logo-u));
  object-fit: contain; object-position: left center;
}

/* ---------- WHY: one line, standing alone ---------- */
.pull-standalone {
  font-size: var(--t3); font-weight: 700; line-height: 1.14;
  letter-spacing: -0.026em; color: var(--paper); max-width: 30ch; text-wrap: pretty;
}

/* ---------- TRACKS ---------- */
.sec-tagline { font-size: var(--t1); font-weight: 700; color: var(--paper); margin-top: .85rem; letter-spacing: -0.015em; }

.foundation {
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: clamp(1.75rem, 4vw, 2.5rem) clamp(1.25rem, 3vw, 2rem);
}
.foundation .track-n { color: var(--mute); margin-bottom: .85rem; }
.foundation .h3 { margin-bottom: clamp(1.5rem, 3vw, 2rem); }
/* ==========================================================================
   CURRICULUM MARQUEE
   Three rows of interlocking chevron tags, one per track, alternating
   direction. Texture, not a ticker — a full cycle is 66-84s.

   Full bleed on purpose: no gutter, the cut-off at both edges is the point,
   so .marq sits outside .wrap in the markup.
   ========================================================================== */
.marq {
  --chev: 24px;      /* depth of the point, and of the notch that receives it */
  --chev-gap: 6px;   /* daylight left between a point and the notch it sits in */
  margin-block: clamp(2rem, 5vw, 3.25rem);
}
.marq-row { overflow: clip; }
/* Uneven vertical rhythm between the four rows, so they read as a band
   rather than a grid. Per row, not by sibling depth. */
.marq-row + .marq-row { margin-top: 10px; }
.marq-row:nth-child(2) { margin-top: 14px; }
.marq-row:nth-child(3) { margin-top: 6px; }
.marq-row:nth-child(4) { margin-top: 12px; }

/* Each row holds the same set twice and shifts by exactly one set width
   (-50% of the pair), so the loop has no seam. */
.marq-seq {
  display: flex; width: max-content;
  will-change: transform;
  animation: marq-shift var(--dur, 75s) linear infinite;
}
.marq-rtl .marq-seq { animation-direction: normal; }   /* content travels left */
.marq-ltr .marq-seq { animation-direction: reverse; }  /* content travels right */
@keyframes marq-shift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
.marq:hover .marq-seq,
.marq:focus-within .marq-seq { animation-play-state: paused; }

.marq-set { display: flex; width: max-content; }
.chev {
  flex: none;
  background: var(--paper); color: var(--ground);
  font-weight: 900;
  font-size: clamp(0.875rem, 1.05vw, 1.125rem);
  line-height: 1.15; letter-spacing: -0.014em;
  white-space: nowrap;
  padding-block: clamp(.7rem, 1.4vw, .95rem);
  /* clear the point on one side and the notch on the other, then some */
  padding-inline: calc(var(--chev) + clamp(.9rem, 1.6vw, 1.5rem));
  /* pull the next tag back into this one's notch — this is the interlock */
  margin-right: calc(var(--chev-gap) - var(--chev));
}
/* The point leads, so it follows the row's direction of travel. */
.marq-rtl .chev {   /* travelling left: point on the left, notch on the right */
  clip-path: polygon(100% 0, var(--chev) 0, 0 50%, var(--chev) 100%,
                     100% 100%, calc(100% - var(--chev)) 50%);
}
.marq-ltr .chev {   /* travelling right: point on the right, notch on the left */
  clip-path: polygon(0 0, calc(100% - var(--chev)) 0, 100% 50%,
                     calc(100% - var(--chev)) 100%, 0 100%, var(--chev) 50%);
}

.tracks { display: grid; gap: 1px; background: var(--rule); border-bottom: 1px solid var(--rule); }
.track { background: var(--ground); display: flex; flex-direction: column; padding: clamp(1.75rem, 4vw, 2.5rem) clamp(1.25rem, 3vw, 2rem); }
.track-n { color: var(--mute); margin-bottom: .85rem; }
.track-days { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.tag { display: inline-block; padding: .4rem .65rem; background: var(--sunk); border: 1px solid var(--rule); color: var(--body); }
.tag-q { background: transparent; color: var(--mute); font-feature-settings: 'tnum' 1; }

.track-dl { margin-top: 1.75rem; }
.track-dl dt {
  font-size: var(--t-2); text-transform: uppercase; letter-spacing: .12em; font-weight: 700;
  color: var(--mute); padding-top: 1.1rem; margin-top: 1.1rem; border-top: 1px solid var(--rule);
}
.track-dl dt:first-child { padding-top: 0; margin-top: 0; border-top: 0; }
.track-dl dd { margin-top: .6rem; color: var(--body); text-wrap: pretty; }
.track-out { font-size: var(--t1); font-weight: 700; line-height: 1.25; color: var(--paper) !important; letter-spacing: -0.018em; }
.track-note { margin-top: 1.5rem; padding: .85rem 1rem; background: var(--sunk); border-left: 2px solid var(--rule); color: var(--mute); font-size: var(--t-1); line-height: 1.5; }

.track-pull {
  padding-top: 1.15rem; border-top: 1px solid var(--rule);
  font-size: var(--t2); font-weight: 700; line-height: 1.14;
  letter-spacing: -0.026em; color: var(--paper); text-wrap: pretty;
}
.track:not(:has(.track-pull)) .track-dl { display: flex; flex-direction: column; flex: 1; }
.track:not(:has(.track-pull)) .track-dl dt:last-of-type { margin-top: auto; }
.track > .track-pull { margin-top: auto; }
.track > .track-note { margin-top: auto; }
.track > .track-note + .track-pull { margin-top: 1.15rem; }

.reassure {
  margin-top: clamp(2rem, 4vw, 3rem);
  font-size: var(--t2); font-weight: 700; line-height: 1.18;
  color: var(--paper); letter-spacing: -0.026em; max-width: 26ch;
}

/* ==========================================================================
   MEDIA SLOTS
   Every slot holds its ratio with aspect-ratio, so nothing shifts when a real
   asset lands. Placeholders never carry the accent — a page of yellow dashed
   boxes would burn it. Each slot is a self-contained <figure>: delete it and
   the layout closes up. See SHOW_MEDIA_PLACEHOLDERS in script.js.
   ========================================================================== */
.slot { width: 100%; }
/* the ratio box. Kept separate from the <figure> so a caption can sit
   outside the clipped area. */
.slot-box {
  position: relative;
  aspect-ratio: var(--ar, 16/9);
  width: 100%;
  overflow: hidden;
  background: #0A0A0A;
}
.slot-box > img, .slot-box > video { width: 100%; height: 100%; object-fit: cover; display: block; }

.slot-ph {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; text-align: center; padding: 1rem;
  background: #0A0A0A;
  border: 1px dashed #444;
}
.slot-meta {
  font-size: 12px; line-height: 1.35; color: #888;
  text-transform: uppercase; letter-spacing: .1em; font-weight: 700;
}
.slot-desc { font-size: 12px; line-height: 1.45; color: #888; max-width: 34ch; font-weight: 400; }
.slot-path { font-size: 12px; line-height: 1.35; color: #888; font-weight: 400; opacity: .8; }

/* very small slots drop the description rather than overflow */
.slot-ph { container-type: inline-size; }
@container (max-width: 240px) { .slot-desc { display: none; } }

.slot-cap { margin-top: .6rem; font-size: 12px; line-height: 1.4; color: #888; }

/* play control — mobile and reduced-motion get the poster plus this */
.slot-play {
  position: absolute; left: 50%; bottom: .75rem; transform: translateX(-50%);
  display: none; align-items: center; gap: .45rem;
  min-height: 40px; padding: 0 1rem;
  background: rgba(0,0,0,.72); border: 1px solid var(--paper); border-radius: 999px;
  color: var(--paper); font-size: var(--t-2); font-weight: 700; cursor: pointer;
  text-transform: uppercase; letter-spacing: .1em;
}
.slot.has-control .slot-play { display: inline-flex; }

/* ---------- pull line: loop behind the copy ----------
   This is the one slot used as a cover backdrop rather than a ratio-locked
   block: 21:9 is the shooting spec, the display crops to the band. Layout
   shift is zero by construction — the media is absolutely positioned, so the
   section height never depends on it. */
.sec-why { position: relative; overflow: hidden; display: grid; align-items: center; }
.why-media { position: absolute; inset: 0; z-index: 0; }
.why-media .slot, .why-media .slot-box { height: 100%; aspect-ratio: auto; }
.why-media .slot-ph { border: 0; }
/* 75% ground over the loop. Over a pure-white frame that leaves #404040,
   which carries white text at 9.74:1. */
.why-scrim { position: absolute; inset: 0; background: rgba(0,0,0,0.75); }
.sec-why .wrap { position: relative; z-index: 1; }

/* ---------- foundation pair ---------- */
.slot-pair {
  display: grid; gap: clamp(.75rem, 1.5vw, 1rem);
  align-items: start;   /* the two ratios differ; do not stretch either */
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
}

/* ---------- track panels ---------- */
.slot-track { margin-top: 1.25rem; }
/* The vertical track slot holds 9:16 exactly, but at full column width that is
   ~660px tall — it would dictate the height of all three panels. Capping the
   height and letting width follow keeps the ratio exact and the row balanced. */
.slot-track[data-slot="track-content"] .slot-box { height: min(380px, 96vw); width: fit-content; max-width: 100%; }

/* ---------- showcase ---------- */
.sec-showcase { border-top: 1px solid var(--rule); }
.showcase-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: thin; scrollbar-color: var(--rule) transparent; }
.showcase-scroll::-webkit-scrollbar { height: 6px; }
.showcase-scroll::-webkit-scrollbar-thumb { background: var(--rule); }
.showcase { display: flex; gap: 1rem; width: max-content; align-items: start; }
.showcase-scroll .showcase { padding-inline: var(--edge-l) 0; }
.showcase .slot { width: 62vw; max-width: 340px; }
.showcase .sc-02, .showcase .sc-05 { width: 42vw; max-width: 230px; }

/* ---------- production strip ---------- */
.sec-prod { border-top: 1px solid var(--rule); }
.prod-scroll {
  overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
  /* scroll band: starts on the --edge line, bleeds to 0 on the right */
  padding-inline: var(--edge-l) 0;
  scrollbar-width: thin; scrollbar-color: var(--rule) transparent;
}
.prod-scroll::-webkit-scrollbar { height: 6px; }
.prod-scroll::-webkit-scrollbar-thumb { background: var(--rule); }
.prod-strip { display: flex; gap: 1rem; width: max-content; align-items: stretch; }
.slot-strip { width: auto; }
.slot-strip .slot-box { height: 240px; width: auto; aspect-ratio: var(--ar); }

/* ---------- apply ---------- */
.slot-apply { margin-bottom: clamp(2rem, 4vw, 2.75rem); }

/* ---------- FAQ kit lists ---------- */
.kit { margin-top: 0; }
.kit li {
  padding: .6rem 0 .6rem 1.4rem; border-bottom: 1px solid var(--rule);
  font-size: 0.9375rem; line-height: 1.45; color: var(--body); position: relative; text-wrap: pretty;
}
.kit li::before { content: ''; position: absolute; left: 0; top: 1.05rem; width: 6px; height: 1px; background: var(--mute); }
.kit-h { color: var(--mute); margin-bottom: .35rem; }
.kit + .kit-h { margin-top: 1.5rem; }

/* ---------- ANCHOR TARGETS clear the fixed header ---------- */
/* Structural, not a hand-kept list: the old enumeration had drifted and
   #showcase and #production were landing under the header. Every section that
   can be linked to clears the compact header by 24px. */
main[id], section[id] { scroll-margin-top: calc(var(--head-compact-h) + 24px); }


/* ==========================================================================
   THE TIMELINE — the signature
   12 week columns x 3 lane rows. Whole-school weeks are literally
   grid-row: 2 / 5 — the structure is the meaning.
   ========================================================================== */
.sec-tl { border-top: 1px solid var(--rule); }

.tl-scroll {
  overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  /* scroll band: starts on the same --edge line as the heading above it,
     bleeds to 0 on the right */
  padding-inline: var(--edge-l) 0;
  padding-bottom: .5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
.tl-scroll::-webkit-scrollbar { height: 6px; }
.tl-scroll::-webkit-scrollbar-track { background: var(--sunk); }
.tl-scroll::-webkit-scrollbar-thumb { background: var(--rule); }
.tl-scroll:focus-visible { outline-offset: -2px; }

.tl {
  display: grid;
  grid-template-columns: var(--lane-w) repeat(12, var(--week-w));
  grid-template-rows: auto repeat(3, var(--lane-h)) auto;
  gap: 2px;
  min-width: min-content;
  width: max-content;
}

/* ruler */
.tl-corner {
  grid-area: 1 / 1 / 2 / 2;
  position: sticky; left: 0; z-index: 3; background: var(--ground);
}
/* Sticky cells pin to the padding box, so blocks would otherwise scroll
   through the scroller's left padding. This pseudo extends the black fill
   leftward across it and is clipped by the scroll container. */
.tl-corner::before, .tl-lane::before {
  content: ''; position: absolute; top: 0; bottom: 0; right: 100%;
  width: 320px; background: var(--ground);
}
.tl-rule {
  grid-row: 1 / 2;
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--rule);
  position: relative;
}
.tl-rule span {
  font-family: var(--sans); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: .1em; color: var(--mute);
  font-feature-settings: 'tnum' 1;
}
.tl-rule::after {
  content: ''; position: absolute; left: 0; bottom: -1px;
  width: 1px; height: 7px; background: var(--rule);
}
.tl-w1{grid-column:2/3}.tl-w2{grid-column:3/4}.tl-w3{grid-column:4/5}
.tl-w4{grid-column:5/6}.tl-w5{grid-column:6/7}.tl-w6{grid-column:7/8}
.tl-w7{grid-column:8/9}.tl-w8{grid-column:9/10}.tl-w9{grid-column:10/11}
.tl-w10{grid-column:11/12}.tl-w11{grid-column:12/13}.tl-w12{grid-column:13/14}

/* sticky lane labels */
.tl-lane {
  grid-column: 1 / 2;
  position: sticky; left: 0; z-index: 3;
  background: var(--ground);
  display: flex; flex-direction: column; justify-content: center; gap: .25rem;
  padding-right: .9rem;
  border-right: 1px solid var(--rule);
}
.tl-lane-1 { grid-row: 2 / 3; }
.tl-lane-2 { grid-row: 3 / 4; }
.tl-lane-3 { grid-row: 4 / 5; }
.tl-lane-n { color: var(--paper); font-size: 0.6875rem; }
.tl-lane-d { color: var(--mute); font-size: 0.625rem; letter-spacing: .05em; }

/* blocks */
.blk {
  display: flex; flex-direction: column; gap: .4rem;
  padding: .75rem .8rem;
  overflow: hidden;
  min-width: 0;
}
.blk-w { color: inherit; opacity: .6; font-size: 0.625rem; font-feature-settings: 'tnum' 1; }
.blk-t { font-size: 0.6875rem; line-height: 1.3; }
.blk-s {
  font-size: 0.6875rem; line-height: 1.35; letter-spacing: 0;
  text-transform: none; font-weight: 400; opacity: .75; margin-top: auto;
}

/* fill ladder: paper = whole school, surface = your track, sunk = quiet */
.blk-all   { background: var(--paper); color: var(--ground); }
.blk-mid   { background: var(--surface); color: var(--paper); }
.blk-quiet { background: var(--sunk); color: var(--mute); border: 1px solid var(--rule); }
.blk-tbc {
  background: repeating-linear-gradient(135deg, var(--sunk) 0 6px, var(--ground) 6px 12px);
  color: var(--mute); border: 1px dashed var(--rule);
}

/* vertical text for single-week blocks */
.blk-v { writing-mode: vertical-rl; align-items: center; justify-content: center; gap: .5rem; padding: .8rem .5rem; }
.blk-v .blk-t { letter-spacing: .16em; }
.blk-all.blk-v .blk-t { font-weight: 600; }

/* placement */
.blk-a-foundation { grid-area: 2 / 2 / 5 / 5; }
.blk-a-s1 { grid-area: 2 / 5 / 3 / 7; }
.blk-a-s2 { grid-area: 3 / 5 / 4 / 7; }
.blk-a-s3 { grid-area: 4 / 5 / 5 / 7; }
.blk-a-p1 { grid-area: 2 / 7 / 3 / 9; }
.blk-a-p2 { grid-area: 3 / 7 / 4 / 9; }
.blk-a-p3 { grid-area: 4 / 7 / 5 / 9; }
.blk-a-e1 { grid-area: 2 / 9 / 3 / 10; }
.blk-a-e2 { grid-area: 3 / 9 / 4 / 10; }
.blk-a-e3 { grid-area: 4 / 9 / 5 / 10; }
.blk-a-prod { grid-area: 2 / 10 / 5 / 11; }
.blk-a-o1 { grid-area: 2 / 11 / 3 / 13; }
.blk-a-o2 { grid-area: 3 / 11 / 4 / 13; }
.blk-a-o3 { grid-area: 4 / 11 / 5 / 13; }
.blk-a-prem { grid-area: 2 / 13 / 5 / 14; }

.blk-a-foundation .blk-t { font-size: 0.8125rem; letter-spacing: .14em; font-weight: 600; }
.blk-a-foundation .blk-s { max-width: 22ch; opacity: .68; }

/* the shared marker under weeks 4—5 */
.tl-tie {
  grid-area: 5 / 5 / 6 / 7;
  padding-top: .5rem;
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
  margin-top: 2px;
}
.tl-tie span {
  display: block; padding: 0 .4rem;
  color: var(--mute); font-size: 0.625rem; line-height: 1.35;
  text-transform: uppercase; letter-spacing: .08em;
}

.tl-hint { color: var(--rule); margin-top: 1rem; font-size: 0.625rem; }
.tl-foot {
  display: grid; gap: 1.25rem;
  margin-top: 1.75rem; padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}
.cap-dates strong { color: var(--body); font-weight: 500; }

/* ---------- FAQ ---------- */
.sec-faq { border-top: 1px solid var(--rule); }
.faq { border-top: 1px solid var(--rule); }
.q { border-bottom: 1px solid var(--rule); }
.q summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: flex-start; gap: 1.25rem; padding: 1.35rem 0;
  font-size: var(--t1); font-weight: 700; line-height: 1.25;
  color: var(--paper); letter-spacing: -0.018em;
  transition: opacity .2s var(--ease);
}
.q summary::-webkit-details-marker { display: none; }
.q summary span { flex: 1; }
.q summary::after {
  content: ''; flex: none; width: 13px; height: 13px; margin-top: .45rem;
  background:
    linear-gradient(var(--mute), var(--mute)) center/13px 1px no-repeat,
    linear-gradient(var(--mute), var(--mute)) center/1px 13px no-repeat;
  transition: transform .28s var(--ease), background-size .28s var(--ease);
}
.q[open] summary::after { transform: rotate(180deg); background-size: 13px 1px, 0 13px; }
.q summary:hover { opacity: .72; }
.q-b { padding-bottom: 1.5rem; max-width: 62ch; }
.q-b p { color: var(--body); text-wrap: pretty; }
.q[open] .q-b { animation: fade .32s var(--ease) both; }
@keyframes fade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* ---------- APPLY ---------- */
.sec-apply { border-top: 1px solid var(--rule); }
.apply-head { margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.form { display: grid; gap: 1.4rem; }
.f { display: grid; gap: .55rem; }
.f-row { display: grid; gap: 1.4rem; }
.f label, .f legend, .f-fs legend { font-size: var(--t-1); font-weight: 700; color: var(--body); padding: 0; }
.opt { color: var(--mute); font-weight: 400; text-transform: none; letter-spacing: 0; }
.f-fs { border: 0; padding: 0; margin: 0; }

.f input[type="text"], .f input[type="tel"], .f input[type="email"], .f select, .f textarea {
  width: 100%; min-height: 52px; padding: .85rem 1rem;
  background: var(--sunk);
  border: 1px solid var(--mute); /* 6.92:1 — control boundaries must clear 3:1 */
  color: var(--paper);
  font-size: 1rem; /* 16px — stops iOS zoom on focus */
  line-height: 1.4; border-radius: 6px;
  -webkit-appearance: none; appearance: none;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.f textarea { min-height: 96px; resize: vertical; }
.f input:hover, .f select:hover, .f textarea:hover { border-color: var(--paper); }
.f input:focus, .f select:focus, .f textarea:focus { border-color: var(--paper); background: var(--surface); }
.f select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--mute) 50%),
    linear-gradient(135deg, var(--mute) 50%, transparent 50%);
  background-position: calc(100% - 19px) 23px, calc(100% - 13px) 23px;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; padding-right: 2.75rem;
}
.f select:invalid { color: var(--mute); }
.f option { background: var(--sunk); color: var(--paper); }

.radios { display: flex; gap: .6rem; }
.rad { flex: 1; }
.rad input { position: absolute; opacity: 0; width: 0; height: 0; }
.rad span {
  display: flex; align-items: center; justify-content: center;
  min-height: 52px; padding: 0 1rem; cursor: pointer; border-radius: 999px;
  background: var(--sunk); border: 1px solid var(--mute); color: var(--body);
  font-size: var(--t0);
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.rad:hover span { border-color: var(--paper); color: var(--paper); }
.rad input:checked + span { background: var(--paper); border-color: var(--paper); color: var(--ground); font-weight: 700; }
.rad input:focus-visible + span { outline: 2px solid var(--paper); outline-offset: 3px; box-shadow: 0 0 0 6px rgba(0,0,0,.75); }

.chk { display: flex; align-items: flex-start; gap: .85rem; cursor: pointer; font-size: 0.9375rem; line-height: 1.45; color: var(--body); font-weight: 400; }
.chk input { position: absolute; opacity: 0; width: 0; height: 0; }
.chk span { flex: 1; padding-top: .1rem; }
.chk span::before {
  content: ''; float: left; margin: 0 .85rem 0 -1.7rem; width: 22px; height: 22px; flex: none;
  background: var(--sunk); border: 1px solid var(--mute); border-radius: 4px;
  transition: background-color .18s var(--ease), border-color .18s var(--ease);
}
.chk input:checked + span::before {
  background: var(--paper) center/11px 9px no-repeat; border-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 9'%3E%3Cpath d='M1 4.5 4 7.5 10 1' stroke='%23000000' stroke-width='1.8' fill='none' stroke-linecap='square'/%3E%3C/svg%3E");
}
.chk input:focus-visible + span::before { outline: 2px solid var(--paper); outline-offset: 3px; }

.err { color: var(--paper); font-size: var(--t-1); font-weight: 700; }
.err::before { content: '— '; color: var(--mute); }
.f.has-err input, .f.has-err select, .f.has-err textarea { border-color: var(--paper); }
.f.has-err .rad span { border-color: var(--paper); }
.form-msg { padding: 1rem 1.25rem; border: 1px solid var(--paper); background: var(--sunk); color: var(--paper); font-size: var(--t0); line-height: 1.5; border-radius: 6px; }
.form-msg[data-state="err"] { border-color: var(--rule); color: var(--body); }

/* ---------- FOOTER ---------- */
.foot { border-top: 1px solid var(--rule); padding-block: clamp(3rem, 7vw, 5rem); }
.foot-name { font-size: var(--t2); font-weight: 900; color: var(--paper); line-height: 1.05; letter-spacing: -0.032em; }
.foot-sub { color: var(--mute); font-size: var(--t-1); margin-top: .6rem; }
.foot-founded { margin-block: clamp(2.5rem, 6vw, 3.5rem); padding-block: clamp(2rem, 5vw, 2.75rem); border-block: 1px solid var(--rule); }
.foot-logo { height: 44px; width: auto; margin-bottom: clamp(1.5rem, 4vw, 2rem); }

/* ==========================================================================
   MOTION — one orchestrated load, then near-nothing.
   ========================================================================== */
.js .anim { opacity: 0; transform: translateY(14px); }
.js.ready .anim { animation: rise .62s var(--ease) both; animation-delay: calc((var(--d, 1) - 1) * 75ms); }
[data-anim="1"] { --d: 1 } [data-anim="2"] { --d: 2 } [data-anim="3"] { --d: 3 }
[data-anim="4"] { --d: 4 } [data-anim="5"] { --d: 5 }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.js .reveal { opacity: 0; transform: translateY(12px); transition: opacity .5s var(--ease), transform .5s var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }

.js .tl-armed .blk { clip-path: inset(0 100% 0 0); }
.js .tl-armed .tl-tie { opacity: 0; }
.js .tl-run .blk { clip-path: inset(0 0 0 0); transition: clip-path .5s var(--ease); transition-delay: calc(var(--b, 0) * 55ms); }
.js .tl-run .tl-tie { opacity: 1; transition: opacity .4s var(--ease) .55s; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (min-width: 560px) {
  .f-row { grid-template-columns: 1fr 1fr; }
  .hero-actions { display: flex; gap: .75rem; }
  /* one row from here up; 0.8px per unit at 560 growing to 1px at 1024,
     where every mark sits at its own intrinsic size. From 560 there is room
     to left-pack the marks with generous gaps — the <560 space-between spread
     is a mobile-only treatment, so justify-content and the gap are restored
     here rather than inherited from the base rule. */
  .partner-list {
    display: flex; flex-wrap: wrap; justify-content: flex-start;
    gap: clamp(1.1rem, 3.5vw, 1.75rem) clamp(1.5rem, 3.6vw, 3rem);
    --logo-u: clamp(0.8px, 0.0431vw + 0.5586px, 1px);
  }
}

@media (min-width: 768px) {
  :root { --lane-w: 116px; --week-w: 92px; --lane-h: 128px; }
  .slot-pair { grid-template-columns: 1.7fr 1fr; }
  .slot-strip .slot-box { height: 300px; }
  .tl-foot { grid-template-columns: 1fr 1fr; gap: 2.5rem; }
  .foot-top { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 1rem; }
  .foot-top .foot-sub:last-child { grid-column: 2; grid-row: 1 / 3; text-align: right; margin-top: 0; }
}

/* ---------- >=1024: full-bleed hero, text over the media ---------- */
@media (min-width: 1024px) {
  .hero { min-height: 100svh; display: flex; }
  .hero-media { position: absolute; inset: 0; aspect-ratio: auto; height: 100%; }
  /* Desktop frames wider and centres the subject vertically — the tight mobile
     head-and-shoulders crop (60% 30%) is undone here. 65% keeps the subject
     centre-right so the left third stays clear for the headline. */
  .hero-img { object-position: 65% 50%; }
  /* ---------- THE SCRIM ----------
     Left-anchored, not a frame-wide dim. The type all sits lower-left while
     the subject sits upper-middle, so an ellipse anchored off the bottom-left
     corner builds density exactly where the type is and falls away before it
     reaches the face. Measured against the real image at 1440x950, white type,
     glyph boxes sampled pixel by pixel with the type hidden:

       treatment                    headline   strip    subject brightness
       no scrim                       1.62 X    2.57 X   0.0519  (100%)
       linear 100deg wedge            4.16 X   14.69     0.0222  ( 43%)
       denser linear wedge            6.80     17.39     0.0132  ( 25%)
       THIS (elliptical, e6)          8.12     18.71     0.0492  ( 95%)

     8.12:1 is 1.8x the 4.5 floor and costs the subject 5% of its brightness;
     the linear wedge could not clear the floor without halving it. Worst pixel
     is x=529 y=448 (37% across) — the lit shoulder under line 2.

     RETUNE THESE STOPS if the image is replaced. Nothing here is generic. */
  .hero-scrim {
    background: radial-gradient(110% 100% at -5% 82%,
      rgb(0 0 0 / 0.96)  0%,
      rgb(0 0 0 / 0.87) 31%,
      rgb(0 0 0 / 0.50) 53%,
      rgb(0 0 0 / 0.12) 71%,
      rgb(0 0 0 / 0)    85%);
  }
  .hero-inner {
    display: flex; flex-direction: column; justify-content: flex-end;
    width: 100%; min-height: 100svh;
    /* Top clears the RESTING header — the hero is the one place the header is
       never compact. Foot is --edge-bottom, not --edge: the strip sits 40px up. */
    padding-block: calc(var(--head-pad-top) + var(--head-mark-h) + 1.5rem)
                   calc(var(--edge-bottom) + env(safe-area-inset-bottom, 0px));
  }
  /* The subhead is set against the HEADLINE, not the viewport. A two-column
     grid with align-items:center lands it on the optical middle of the
     headline block (~44% down the frame) and pins its right edge to the same
     25px line as the Apply pill. No transform — .anim ends on transform:none,
     which would have wiped a translateY(-50%) centring. */
  .hero-lede {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: center; column-gap: clamp(2rem, 5vw, 5rem);
  }
  .hero-headline { grid-column: 1; font-size: clamp(3.75rem, 7.4vw, 7.5rem); max-width: 15ch; }
  /* Block stays hard right on the 25px line; the TEXT is left-aligned inside
     it, so the five lines share a left vertical and rag on the right. That is
     what makes it read as a column rather than a caption. */
  .hero-sub {
    grid-column: 2; justify-self: end; position: static;
    width: 30ch; max-width: 30ch; text-align: left; margin-top: 0;
  }
  /* The desktop See all tracks is the compact auto-width pill again, not the
     near-full-width mobile bar. */
  .hero-actions .btn-outline { width: auto; min-height: 52px; }
  .partners { margin-top: clamp(3rem, 9vw, 8.5rem); }
  .tracks { grid-template-columns: repeat(3, 1fr); }
  .tl-hint { display: none; }
  .slot-strip .slot-box { height: 340px; }
  /* the pull-line band reads cinematic once there is room for it */
  .sec-why { min-height: min(46vw, 560px); }

  /* showcase becomes an asymmetric 12-column grid, no scrolling — so it takes
     the frame on both sides again rather than bleeding right */
  .showcase-scroll { overflow: visible; }
  .showcase-scroll .showcase { padding-inline: var(--edge-l) var(--edge-r); }
  .showcase {
    display: grid; width: auto;
    grid-template-columns: repeat(12, 1fr);
    gap: clamp(1rem, 2vw, 1.75rem);
    align-items: start;
  }
  .showcase .slot { width: 100%; max-width: none; }
  .sc-01 { grid-column: span 5; }
  .sc-02 { grid-column: span 3; }
  .sc-03 { grid-column: span 4; }
  .sc-04 { grid-column: span 4; }
  .sc-05 { grid-column: span 3; }
  .sc-06 { grid-column: span 5; }
}

@media (min-width: 1400px) {
  :root { --week-w: 1fr; }
  .tl { width: 100%; min-width: 0; }
  /* no longer a scroll band, so it takes the frame on both sides */
  .tl-scroll { overflow-x: visible; padding-inline: var(--edge-l) var(--edge-r); }
}

/* ---------- REDUCED MOTION — a static page must still feel finished ---------- */
@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;
  }
  .js .anim, .js .reveal { opacity: 1 !important; transform: none !important; }
  .js .tl-armed .blk { clip-path: none !important; }
  .js .tl-armed .tl-tie { opacity: 1 !important; }
  .q[open] .q-b { animation: none; }

  /* The marquee must be switched OFF, not sped up. The blanket
     animation-duration: 0.001ms above would otherwise run it to completion
     instantly and leave every row parked at translate3d(-50%, 0, 0). */
  .marq-seq {
    animation: none !important;
    transform: none !important;
    width: auto; will-change: auto;
  }
  .marq-set { flex-wrap: wrap; row-gap: 6px; }
  .marq-set[data-clone] { display: none; }   /* the loop copy is pointless static */
  .marq-row { overflow: visible; padding-inline: var(--edge-l) var(--edge-r); }
  .marq-row + .marq-row,
  .marq-row + .marq-row + .marq-row { margin-top: 6px; }
}
