/* ===========================================================================
   TRAIN SMART — marketing site stylesheet.

   This is the app's design language adapted for a document rather than an
   interface. The tokens, the two faces, the radius scale and the elevation
   model are lifted directly from sport-training-app/src/index.css and
   tailwind.config.js so the site and the product read as one thing.

   What is ADAPTED for marketing, deliberately:
     - a wider measure and a bigger display scale (a phone screen caps at
       44px; a landing page opens at 96px);
     - a 12-column grid instead of a single phone column;
     - hover states, which a touch interface has no use for;
     - a light-on-dark editorial rhythm with real vertical air between bands.

   What is NOT adapted — the app's banned-defaults list is repeated here in
   full because a marketing site is exactly where each of these creeps back in:

     1. Multi-hue gradients. The only legal gradient is a single-hue scrim.
     2. Glassmorphism / backdrop-blur frosted panels.
     3. Gradient-filled or otherwise treated text.
     4. Emoji as iconography. Icons are drawn strokes.
     5. Soft ambient drop shadows, neumorphism, coloured glows.
     6. Uniform pill-rounding on every rectangle.
     7. Neon halos.
     8. Centre-aligned body layouts. Content sits on a hard left grid.
     9. Pastel accent surfaces.
    10. Generic stock photography as a substitute for design.

   Energy comes from structure and typographic force, not colour effects.
   =========================================================================== */

/* ---- fonts ---------------------------------------------------------------
   Self-hosted, latin-subset, variable. Served as files rather than the app's
   base64 data URIs: on the web these are cached independently of the CSS and
   shared across every page of the site, where inlining would re-download
   67KB of font inside every stylesheet hit.

   Saira is `swap` here, not `block` as in the app. On a document the first
   paint of readable text beats a perfectly-typeset one 100ms later; in the
   app it is `block` because the entire interface is set in it and a flash of
   system UI font reads as a different product.
   ------------------------------------------------------------------------ */
@font-face {
  font-family: 'Saira Cond';
  font-style: normal;
  font-weight: 500 900;
  font-stretch: 62.5%;
  font-display: swap;
  src: url('/assets/fonts/saira-cond.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/archivo.woff2') format('woff2');
}

:root {
  color-scheme: dark;

  --bg: #0a0a0a;
  --surface: #121212;
  --surface2: #1a1a1a;
  --surface3: #232323;
  --text: #ffffff;
  --muted: #8e8e88;
  --dim: #6e6e6e;
  --line: rgba(255, 255, 255, 0.11);
  --line2: rgba(255, 255, 255, 0.2);

  --accent: #d7ff3e;
  --accent-ink: #0a0f00;
  --bad: #ff5a45;
  --warn: #ffb020;

  --f-display: 'Saira Cond', 'Archivo', ui-sans-serif, system-ui, sans-serif;
  --f-body: 'Archivo', ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* Radius is a decision, not a default. Structural blocks are square. */
  --r-card: 12px;
  --r-sm: 6px;

  /* The page grid.
     Fluid, not a fixed 1200px. A fixed container left ~350px of dead margin
     down each side of a 1920px monitor and the site read as a narrow column
     floating in black.

     This is safe to widen because LAYOUT width and TEXT width are separate
     concerns here: .wrap sets how far cards, tables and grids spread, while
     running text is independently capped by --measure (68ch) and .lede. So a
     wider container fills the screen with content without ever producing a
     120-character line. */
  --page: min(92vw, 1720px);
  --measure: 68ch;
  --gutter: 24px;

  /* Vertical rhythm between bands. One value so every section agrees. */
  --band: clamp(64px, 9vw, 128px);
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@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;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

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

/* Every link inside prose is underlined. An unstyled inline link in a
   paragraph is invisible to anyone who navigates by anything other than
   colour, and colour alone fails WCAG 1.4.1. */
.prose a,
a.link {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(215, 255, 62, 0.45);
  transition: text-decoration-color 0.15s;
}
.prose a:hover,
a.link:hover {
  text-decoration-color: var(--accent);
}

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

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

/* =========================================================================
   TYPE

   Two faces, one job each. If it is a LABEL or a NUMBER it is display caps;
   if it is a SENTENCE it is body. Mixing the two inside one line is what
   makes a design look unresolved.
   ========================================================================= */

.d {
  font-family: var(--f-display);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 0.86;
  letter-spacing: 0.002em;
  margin: 0;
  /* Condensed caps have no descender clutter, so they can be set far tighter
     than body copy without collision — that tightness is the whole look. */
}

/* The display scale. clamp() throughout: these are the only elements that
   genuinely need to be different sizes on a phone and a 27" monitor, and a
   fluid ramp beats four breakpoints of hand-tuned overrides. */
.d-1 { font-size: clamp(46px, 9vw, 104px); }
.d-2 { font-size: clamp(36px, 6vw, 68px); }
.d-3 { font-size: clamp(28px, 4vw, 46px); }
.d-4 { font-size: clamp(21px, 2.4vw, 30px); font-weight: 800; line-height: 0.92; }
.d-5 { font-size: 17px; font-weight: 800; line-height: 1; letter-spacing: 0.01em; }

/* Stat numerals — tabular so a column of them lines up. */
.stat {
  font-family: var(--f-display);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  line-height: 0.85;
  font-size: clamp(34px, 4.4vw, 54px);
  letter-spacing: 0.002em;
}

/* Micro-label above a block. Body face — at 11px the condensed face loses too
   much aperture to stay legible. */
.eyebrow {
  font-family: var(--f-body);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 11px;
  line-height: 1.2;
  letter-spacing: 0.16em;
  color: var(--muted);
  margin: 0 0 18px;
  display: block;
}
.eyebrow--accent { color: var(--accent); }

.lede {
  font-size: clamp(17px, 1.5vw, 21px);
  line-height: 1.5;
  color: var(--muted);
  max-width: var(--measure);
  margin: 20px 0 0;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

.prose {
  max-width: var(--measure);
  color: var(--muted);
  font-size: 17px;
  line-height: 1.65;
}
.prose > * + * { margin-top: 1.15em; }
.prose strong { color: var(--text); font-weight: 700; }
.prose h2 {
  font-family: var(--f-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: clamp(26px, 3vw, 36px);
  line-height: 0.9;
  color: var(--text);
  margin: 2.2em 0 0;
  scroll-margin-top: 96px;
}
.prose h3 {
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 21px;
  line-height: 1;
  color: var(--text);
  margin: 1.9em 0 0;
  scroll-margin-top: 96px;
}
.prose ul,
.prose ol { margin: 0; padding-left: 1.2em; }
.prose li { margin-bottom: 0.55em; }
.prose li::marker { color: var(--accent); }
.prose blockquote {
  margin: 0;
  padding: 4px 0 4px 20px;
  border-left: 2px solid var(--accent);
  color: var(--text);
  font-size: 18px;
}
.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  background: var(--surface2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}

.muted { color: var(--muted); }
.dim { color: var(--dim); }
.accent { color: var(--accent); }
.tnum { font-variant-numeric: tabular-nums; }

/* =========================================================================
   LAYOUT
   ========================================================================= */

.wrap {
  width: 100%;
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.wrap--narrow { max-width: 860px; }

.band { padding: var(--band) 0; }
.band--tight { padding: calc(var(--band) * 0.6) 0; }
.band--ruled { border-top: 1px solid var(--line); }
.band--surface { background: var(--surface); }

/* A hard structural rule. This is what carries "elevation" here — not blur. */
.rule { border-top: 1px solid var(--line); }
.rule-accent { border-top: 2px solid var(--accent); }

.grid { display: grid; gap: 20px; }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Auto-fit grids for card lists whose length varies (sports, tests, guides). */
.g-auto { grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }
.g-auto-sm { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }

/* The workhorse editorial split: a sticky heading column and a content column.
   Used by every feature, sport, test and guide page, which is what makes them
   feel like one publication rather than twelve templates. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
.split__aside { position: sticky; top: 96px; }

@media (max-width: 900px) {
  .g-3, .g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .split__aside { position: static; }
}
@media (max-width: 620px) {
  .g-2, .g-3, .g-4 { grid-template-columns: minmax(0, 1fr); }
  .g-auto-sm { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.stack { display: flex; flex-direction: column; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.gap-8 { gap: 8px; } .gap-12 { gap: 12px; } .gap-16 { gap: 16px; }
.gap-24 { gap: 24px; } .gap-32 { gap: 32px; } .gap-48 { gap: 48px; }
.mt-8 { margin-top: 8px; } .mt-12 { margin-top: 12px; } .mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; } .mt-32 { margin-top: 32px; } .mt-48 { margin-top: 48px; }
.mt-64 { margin-top: 64px; }
.mb-0 { margin-bottom: 0; }

/* =========================================================================
   COMPONENTS — mirrors of the app's own, adapted for a page.
   ========================================================================= */

/* ---- buttons ------------------------------------------------------------
   Fully round on purpose, and one of the very few things that is: a primary
   action is a genuine pill, so it earns the radius. The label is display caps
   because a button is a LABEL, not a sentence. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 15px;
  padding: 15px 26px;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s, transform 0.12s;
  white-space: nowrap;
}
.btn:active { transform: scale(0.985); }
.btn--primary { background: var(--accent); color: var(--accent-ink); }
.btn--primary:hover { filter: brightness(0.94); }
.btn--ink { background: var(--text); color: var(--bg); }
.btn--ink:hover { background: rgba(255, 255, 255, 0.9); }
/* A hard 1px outline, not a soft tinted fill — the outline IS the style. */
.btn--outline { border-color: var(--line2); color: var(--text); }
.btn--outline:hover { border-color: rgba(255, 255, 255, 0.4); background: rgba(255, 255, 255, 0.04); }
.btn--ghost { color: var(--muted); }
.btn--ghost:hover { color: var(--text); background: rgba(255, 255, 255, 0.06); }
.btn--lg { font-size: 17px; padding: 18px 32px; }
.btn--sm { font-size: 13px; padding: 11px 18px; }
.btn--block { display: flex; width: 100%; }

/* The App Store badge button carries the Apple glyph so it reads as a
   download and not as a generic CTA. */
.btn svg { width: 1.15em; height: 1.15em; flex: none; }

/* ---- cards -------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 26px;
  display: flex;
  flex-direction: column;
  transition: border-color 0.18s, background-color 0.18s;
}
a.card:hover { border-color: var(--line2); background: var(--surface2); }
.card__title {
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 19px;
  line-height: 1;
  letter-spacing: 0.008em;
  margin: 0;
}
.card__body {
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.55;
  margin: 12px 0 0;
}
.card__more {
  margin-top: auto;
  padding-top: 18px;
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
a.card:hover .card__more span { transform: translateX(3px); }
.card__more span { transition: transform 0.18s; display: inline-block; }

/* A hard-edged block for content that reads as PART of the page rather than
   an object sitting on it — spec rows, stat bands. */
.block {
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* ---- tags / chips ------------------------------------------------------- */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.09);
  color: var(--text);
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 6px 12px;
  white-space: nowrap;
}
.tag--accent { background: transparent; color: var(--accent); border-color: rgba(215, 255, 62, 0.45); }
.tag--solid { background: var(--accent); color: var(--accent-ink); }

/* ---- stat band ---------------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  border-top: 1px solid var(--line);
}
.stats__item {
  padding: 30px 26px 30px 0;
  border-bottom: 1px solid var(--line);
}
.stats__label {
  display: block;
  margin-top: 12px;
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---- numbered steps ----------------------------------------------------- */
.steps { counter-reset: step; display: grid; gap: 0; }
.step {
  counter-increment: step;
  display: grid;
  grid-template-columns: 78px minmax(0, 1fr);
  gap: 24px;
  padding: 30px 0;
  border-top: 1px solid var(--line);
  align-items: start;
}
.step::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--f-display);
  font-weight: 900;
  font-size: 44px;
  line-height: 0.8;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 620px) {
  .step { grid-template-columns: 54px minmax(0, 1fr); gap: 16px; }
  .step::before { font-size: 32px; }
}

/* ---- spec / data table -------------------------------------------------- */
.tablewrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  -webkit-overflow-scrolling: touch;
}
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
  min-width: 460px;
}
table.data caption {
  text-align: left;
  padding: 16px 20px 0;
  color: var(--muted);
  font-size: 13px;
}
table.data th,
table.data td {
  text-align: left;
  padding: 13px 20px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
table.data thead th {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface2);
  white-space: nowrap;
}
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td:first-child { color: var(--text); font-weight: 600; }
table.data td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- definition rows (spec sheets) -------------------------------------- */
.spec { border-top: 1px solid var(--line); margin: 0; }
.spec__row {
  display: grid;
  grid-template-columns: minmax(120px, 200px) minmax(0, 1fr);
  gap: 24px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
.spec__row dt {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 3px;
}
.spec__row dd { margin: 0; color: var(--text); font-size: 15px; }
@media (max-width: 620px) {
  .spec__row { grid-template-columns: minmax(0, 1fr); gap: 6px; }
}

/* ---- FAQ ---------------------------------------------------------------- */
.faq { border-top: 1px solid var(--line); }
.faq details {
  border-bottom: 1px solid var(--line);
}
.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 22px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(16px, 1.7vw, 20px);
  line-height: 1.05;
  letter-spacing: 0.01em;
  transition: color 0.15s;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after {
  content: '';
  flex: none;
  width: 13px;
  height: 13px;
  margin-top: 4px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform 0.2s;
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq details > div {
  padding: 0 0 24px;
  max-width: var(--measure);
  color: var(--muted);
  font-size: 16px;
  line-height: 1.62;
}

/* =========================================================================
   HEADER / NAV
   ========================================================================= */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 12px 20px;
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  z-index: 100;
}
.skip:focus { left: 0; }

.hdr {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.hdr__inner {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 68px;
}
.hdr__logo {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--f-display);
  font-weight: 900;
  font-size: 21px;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  color: var(--accent);
  flex: none;
}
.hdr__logo svg { width: 26px; height: 26px; }

.nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav a {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: 14px;
  color: var(--muted);
  padding: 9px 12px;
  border-radius: var(--r-sm);
  transition: color 0.15s, background-color 0.15s;
}
.nav a:hover { color: var(--text); background: rgba(255, 255, 255, 0.05); }
.nav a[aria-current='page'] { color: var(--text); }

/* The mobile nav is a checkbox-driven panel, not JavaScript. A menu that
   needs a script to open is a menu that is broken while the script loads,
   and this one is the only interactive chrome on most pages. */
.navtoggle { display: none; }
.navbtn { display: none; }
/* Hidden at every width by default, not only inside the mobile query. Scoping
   the `display: none` to the media block left the panel rendering underneath
   the header on desktop, where nothing was hiding it. */
.navpanel { display: none; }

@media (max-width: 980px) {
  .nav,
  .hdr__cta { display: none; }
  .navbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    width: 42px;
    height: 42px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text);
    cursor: pointer;
  }
  .navbtn svg { width: 20px; height: 20px; }
  .navtoggle:checked ~ .navpanel { display: block; }
  .navpanel {
    display: none;
    border-top: 1px solid var(--line);
    background: var(--bg);
    max-height: calc(100vh - 68px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .navpanel .wrap { padding-top: 20px; padding-bottom: 28px; }
  .navpanel a {
    display: block;
    padding: 13px 0;
    border-bottom: 1px solid var(--line);
    font-family: var(--f-display);
    font-weight: 800;
    text-transform: uppercase;
    font-size: 19px;
    color: var(--text);
  }
  .navpanel .btn { margin-top: 22px; }
}

/* =========================================================================
   HERO
   ========================================================================= */

.hero { padding: clamp(56px, 8vw, 104px) 0 var(--band); }
.hero__title { max-width: 16ch; }
/* The one place a second colour appears in a heading: the product's own name
   set in volt, exactly as the app's own entry screen does it. */
.hero__title em { font-style: normal; color: var(--accent); display: block; }
.hero__ctas { margin-top: 36px; }
.hero__note {
  margin-top: 18px;
  font-size: 13px;
  color: var(--dim);
}

/* Page hero for interior pages — smaller, with a breadcrumb above it. */
.phero { padding: 40px 0 var(--band); }

/* ---------------------------------------------------------------------------
   VIDEO HERO — homepage only.

   The banned-defaults list forbids gradients as decoration and permits exactly
   one exception: "a single-hue scrim (canvas colour to transparent) used for
   legibility over an image". That is precisely what --scrim is doing here, and
   it is the only gradient on the site.

   The film carries no claim and no face. It is atmosphere, so it is muted,
   looping, and marked aria-hidden — a screen reader has nothing to gain from
   it, and it must never be announced as content.
   ------------------------------------------------------------------------ */
.vhero {
  position: relative;
  overflow: hidden;
  /* Falls back to the canvas colour if the video and poster both fail, so the
     white headline is never left on an undefined background.

     NOTE: the media layer is stacked with a POSITIVE z-index, not -1. A
     negative z-index child sits behind its parent's own background, so with a
     solid background here the video was painted over and the hero rendered
     plain black. `isolation: isolate` made it worse by trapping the child in
     this element's stacking context. Both are gone. */
  background: var(--bg);
  padding: clamp(72px, 11vw, 150px) 0 clamp(48px, 6vw, 84px);
  border-bottom: 1px solid var(--line);
}

.vhero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* The poster, again, as a background. The <video> paints its own poster
     attribute on top of this — but if the element is ever hidden, blocked, or
     the file 404s, the hero still has an image rather than a black rectangle. */
  background: var(--bg) url('/assets/video/hero-poster.jpg') center / cover no-repeat;
}

.vhero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* object-position moves the IMAGE inside the box, so a HIGHER percentage
     shows more of the image's right edge — which on this footage is the dark
     end of the bar. Pushing it right therefore slid the darkest part of the
     frame under the lightest part of the scrim and the hero went black again.
     Slightly left of centre instead: the lit subject drifts toward the right
     of the screen, where the scrim lets it through. */
  object-position: 38% center;
  display: block;
  /* NOT darkened. The footage is graded to crushed blacks already, and an
     earlier brightness(0.62) under the scrim below composited to a hero that
     rendered as a plain black rectangle. Everything the type needs for
     legibility is done by the scrim, which can be tuned per-region; a filter
     applies everywhere and takes the visible right-hand side down with it. */
  filter: contrast(1.03) saturate(0.85);
}

/* Two scrims, both single-hue, both doing a legibility job:
   - a horizontal one so the left-aligned headline always has ground under it;
   - a vertical one so the footage dissolves into the page instead of ending
     on a hard seam at the section boundary. */
.vhero__scrim {
  position: absolute;
  inset: 0;
  /* Two ramps, and they MULTIPLY — that is the thing that keeps catching this
     element out. An earlier pair that each looked reasonable in isolation
     composited to an opaque black rectangle over the whole frame.
     Verified by toggling the scrim off and comparing.

     Horizontal: opaque under the headline column, fully clear by ~70% so the
     right of the frame genuinely shows. Vertical: only enough at the very top
     and bottom to stop a hard seam where the section meets the page. */
  background:
    linear-gradient(to right,
      var(--bg) 0%,
      rgba(10, 10, 10, 0.92) 24%,
      rgba(10, 10, 10, 0.55) 42%,
      rgba(10, 10, 10, 0.16) 58%,
      rgba(10, 10, 10, 0) 70%),
    linear-gradient(to bottom,
      rgba(10, 10, 10, 0.5) 0%,
      rgba(10, 10, 10, 0) 16%,
      rgba(10, 10, 10, 0) 68%,
      rgba(10, 10, 10, 0.5) 90%,
      var(--bg) 100%);
}

@media (max-width: 760px) {
  /* On a phone the text occupies the full width, so the horizontal scrim is
     no longer enough on its own — the whole frame has to sit back. */
  /* On a phone the copy runs the full width, so there is no dark side to hide
     it in — the frame has to go dark UNDER it instead. The image reads in the
     top third, behind the eyebrow and the white display headline which are
     high-contrast enough to survive a mid-tone; from ~45% down it ramps to the
     canvas so the grey lede, the CTAs and the factbar all sit on flat black.
     Tuned in both directions: too heavy and the hero was a black rectangle,
     too light and the lede sat on lit knuckles. */
  .vhero__scrim {
    /* Stops are set from MEASURED geometry, not guessed. On a 375px viewport
       the hero is ~839px and the content lands at:
         eyebrow  9-10%   headline 12-26%   lede 29-44%   CTA 48-65%
       The headline is white, 900-weight display type and survives a light
       scrim, so the image is allowed to read behind it. The grey lede does
       not, so the ramp goes hard in the gap between the two — image texture
       up top, flat black from the body copy down. */
    background:
      linear-gradient(to bottom,
        rgba(10, 10, 10, 0.3) 0%,
        rgba(10, 10, 10, 0.34) 22%,
        rgba(10, 10, 10, 0.86) 30%,
        rgba(10, 10, 10, 0.96) 45%,
        var(--bg) 60%,
        var(--bg) 100%);
  }  /* Only on a phone is the type over the middle of the frame, so this is the
     one place a global darken is the right tool — but gently. Stacked with the
     scrim above, an earlier brightness(0.72) crushed the still to flat black. */
  .vhero__video { filter: brightness(0.82) contrast(1.03) saturate(0.85); object-position: center 38%; }
}

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

/* Over video, body copy has to be held inside the darkest part of the frame
   rather than allowed to run the full 68ch measure — the right end of a long
   line lands on the lit subject, where mid-grey on mid-grey stops being
   readable. Tighter measure, and a step up in colour for the same reason. */
.vhero .lede {
  max-width: 44ch;
  color: #B9BAB2;
}
.vhero .hero__note { color: var(--muted); }

/* A thin band of facts under the CTA. Replaces the full stat section the old
   homepage carried — same numbers, a fraction of the height. */
.factbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin-top: clamp(40px, 5vw, 64px);
  border-top: 1px solid var(--line2);
  padding-top: 20px;
}
.factbar > div {
  padding-right: clamp(28px, 5vw, 58px);
  margin-right: clamp(28px, 5vw, 58px);
  border-right: 1px solid var(--line);
}
.factbar > div:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.factbar b {
  display: block;
  font-family: var(--f-display);
  font-weight: 900;
  font-size: clamp(26px, 3vw, 36px);
  line-height: 0.9;
  color: var(--accent);
}
.factbar span {
  display: block;
  margin-top: 7px;
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
@media (max-width: 620px) {
  .factbar > div { padding-right: 22px; margin-right: 22px; margin-bottom: 18px; }
  .factbar b { font-size: 24px; }
}

/* ---- sport chips ---------------------------------------------------------
   Replaces the eight-card grid the old homepage used for sports. Fifteen
   programs in the height one card used to take, and a chip is one of the few
   objects that genuinely earns a full pill radius. */
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line2);
  border-radius: 999px;
  padding: 10px 18px;
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 14px;
  letter-spacing: 0.03em;
  color: var(--text);
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}
.chip:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* =========================================================================
   BREADCRUMBS
   ========================================================================= */
.crumbs {
  font-size: 12.5px;
  color: var(--dim);
  padding: 0;
  margin: 0 0 26px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  list-style: none;
}
.crumbs li { display: flex; align-items: center; gap: 8px; }
.crumbs li + li::before { content: '/'; color: var(--line2); }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--accent); }
.crumbs [aria-current='page'] { color: var(--text); }

/* =========================================================================
   PRODUCT FIGURES

   Drawn in HTML/CSS from the app's real interface rather than screenshotted.
   A screenshot of a phone UI at 320px wide is unreadable on a landing page
   and goes stale the day the app ships; these are built from the same tokens
   and stay sharp at any size.
   ========================================================================= */

.device {
  border: 1px solid var(--line2);
  border-radius: 22px;
  background: var(--bg);
  padding: 10px;
  max-width: 340px;
  width: 100%;
}
.device__screen {
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--bg);
  overflow: hidden;
}

.ui { padding: 20px 18px; }
.ui__eyebrow {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.ui__h {
  font-family: var(--f-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 30px;
  line-height: 0.88;
  margin: 8px 0 0;
}
.ui__card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
  margin-top: 12px;
}
.ui__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.ui__row:last-child { border-bottom: 0; }
.ui__name { color: var(--text); font-weight: 600; }
.ui__kg {
  font-family: var(--f-display);
  font-weight: 900;
  font-size: 17px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.ui__sub { color: var(--dim); font-size: 11.5px; }

/* A horizontal bar meter — used for readiness, load and benchmark figures.
   Value is passed as an inline --v (0-100) so the same class serves any
   figure without a class per percentage. */
.meter {
  height: 6px;
  background: var(--surface3);
  border-radius: 999px;
  overflow: hidden;
}
.meter > i {
  display: block;
  height: 100%;
  width: calc(var(--v, 0) * 1%);
  background: var(--accent);
  border-radius: 999px;
}

/* The week strip — seven days, each carrying what it holds. */
.week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}
.week__day {
  padding: 14px 8px;
  border-right: 1px solid var(--line);
  text-align: left;
  min-height: 118px;
}
.week__day:last-child { border-right: 0; }
.week__dow {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.week__what {
  font-family: var(--f-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 13px;
  line-height: 1.05;
  margin-top: 9px;
}
.week__day--game { background: var(--accent); }
.week__day--game .week__dow { color: rgba(10, 15, 0, 0.6); }
.week__day--game .week__what { color: var(--accent-ink); }
.week__day--rest .week__what { color: var(--dim); }
.week__tag {
  display: block;
  margin-top: 6px;
  font-size: 10.5px;
  color: var(--muted);
  line-height: 1.3;
}
@media (max-width: 760px) {
  .week { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .week__day { border-bottom: 1px solid var(--line); min-height: 0; }
}

/* =========================================================================
   CALCULATOR / TOOL WIDGETS
   ========================================================================= */
.tool {
  border: 1px solid var(--line2);
  border-radius: var(--r-card);
  background: var(--surface);
  padding: clamp(20px, 3vw, 32px);
}
.field { display: block; margin-bottom: 18px; }
.field > span {
  display: block;
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.field input,
.field select {
  width: 100%;
  background: var(--surface2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text);
  font-family: var(--f-body);
  font-size: 16px;
  padding: 13px 14px;
  appearance: none;
}
.field input:focus,
.field select:focus { border-color: var(--accent); outline: none; }
.field select {
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) 21px, calc(100% - 14px) 21px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.field input[type='number']::-webkit-outer-spin-button,
.field input[type='number']::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.field input[type='number'] { -moz-appearance: textfield; }

.result {
  border-top: 1px solid var(--line);
  margin-top: 26px;
  padding-top: 26px;
}
.result__big {
  font-family: var(--f-display);
  font-weight: 900;
  font-size: clamp(40px, 6vw, 64px);
  line-height: 0.85;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.result__note { color: var(--muted); font-size: 14px; margin-top: 14px; max-width: 46ch; }

/* =========================================================================
   CTA BAND
   ========================================================================= */
.cta {
  border-top: 2px solid var(--accent);
  background: var(--surface);
}
.cta__inner { padding: var(--band) 0; }

/* =========================================================================
   FOOTER
   ========================================================================= */
.ftr {
  border-top: 1px solid var(--line);
  padding: 64px 0 40px;
  font-size: 14px;
}
.ftr__cols {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr));
  gap: 40px 28px;
}
@media (max-width: 900px) { .ftr__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .ftr__cols { grid-template-columns: minmax(0, 1fr); } }
.ftr h2 {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 16px;
}
.ftr ul { list-style: none; margin: 0; padding: 0; }
.ftr li { margin-bottom: 10px; }
.ftr li a { color: var(--muted); font-size: 14px; }
.ftr li a:hover { color: var(--accent); }
.ftr__base {
  margin-top: 56px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 16px 28px;
  align-items: center;
  color: var(--dim);
  font-size: 12.5px;
}
.ftr__base a { color: var(--dim); }
.ftr__base a:hover { color: var(--muted); }

/* =========================================================================
   NOTICES
   ========================================================================= */
.notice {
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--surface);
  padding: 18px 22px;
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.6;
}
.notice strong { color: var(--text); }
.notice--warn { border-left-color: var(--warn); }

/* =========================================================================
   ENTRANCE MOTION

   One transform, one opacity, staggered by index. The app's own reveal is a
   scroll-linked measurement pass in JS; a document does not need that, and a
   pure-CSS animation cannot leave content invisible if a script fails.
   ========================================================================= */
@media (prefers-reduced-motion: no-preference) {
  .rise {
    animation: rise 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: calc(var(--i, 0) * 55ms);
  }
  @keyframes rise {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
  }
}

/* Print: nobody prints a landing page, but people do print a benchmark table
   or a test protocol — which is exactly the kind of page that earns links. */
@media print {
  .hdr, .ftr, .cta, .btn { display: none !important; }
  body { background: #fff; color: #000; }
  .card, .tablewrap { border-color: #ccc; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 10px; }
}

/* ---------------------------------------------------------------------------
   THE SHORT ANSWER

   One block, at the top of a page, that answers the page's primary question in
   40-60 words and nothing else.

   It exists for two readers at once. A person who searched "what is a good
   Bronco time" gets their answer without scrolling, which is simply the right
   way to treat them. And a search engine or language model looking for an
   extractable passage finds a self-contained one that carries its own
   qualification — so when it is quoted out of context, the caveat travels with
   it. That second property is why the text is written to survive being lifted.
   ------------------------------------------------------------------------ */
.answer {
  border-left: 2px solid var(--accent);
  background: var(--surface);
  padding: 22px 26px;
  margin: 32px 0 0;
  max-width: 74ch;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.answer > .eyebrow { margin-bottom: 10px; color: var(--accent); }
.answer p {
  margin: 0;
  font-size: 17.5px;
  line-height: 1.6;
  color: var(--text);
}
.answer p + p { margin-top: 0.7em; color: var(--muted); font-size: 16px; }
