/* GitGud Racing Academy -- homepage / landing page styles.

   Extracted VERBATIM from the four <style> blocks of
   templates/marketing/academy_landing.html, in their original order, so the
   browser can fetch this in parallel and keep it between visits (the page HTML
   carries a csrftoken and is not cacheable, so it used to re-download ~180 KB
   of CSS on every single visit).

   ORDER IS LOAD-BEARING: several rules in here win only by coming after an
   equally specific one. Do not sort, merge or otherwise tidy this file.

   The Django "static" tags that addressed images are now paths relative to
   THIS file -- WhiteNoise's CompressedManifestStaticFilesStorage rewrites and
   hashes them on collectstatic. The template links this sheet from its
   extra_head block, immediately after css/output.css, so the cascade order is
   exactly what it was when these rules were inline. */

/* === block 1 -- was the <style> in extra_head block (template lines 59-1709) === */
  .alp { position: relative; max-width: 74rem; margin: 4rem auto 0; padding: 0 1rem; overflow-x: clip; }

  .alp-eyebrow {
    display:inline-flex; align-items:center; gap:.55rem;
    font-family:var(--font-display); font-size:.68rem; font-weight:800;
    letter-spacing:.26em; text-transform:uppercase; color:var(--color-secondary);
    border:1px solid rgba(91,195,249,.25); background:rgba(91,195,249,.08);
    padding:.5rem .9rem; border-radius:999px;
  }
  .alp-eyebrow::before { content:""; width:6px; height:6px; border-radius:50%; background:var(--color-secondary); box-shadow:0 0 10px var(--color-secondary); }
  .alp-grad { background:linear-gradient(100deg,#fff 0%,#cfe9fb 35%,var(--color-secondary) 60%,var(--color-primary) 100%);
    -webkit-background-clip:text; background-clip:text; color:transparent; }

  /* ===== DRIVER RESULTS — label + real testimonials + sims ===== */
  /* ===== Page backdrop — solid dark with atmospheric glows. =====
     Was a track photo (academy_optimized.jpg) bleeding through the page
     edges; replaced by a clean linear-gradient base + the existing cyan +
     red radial glows. Reads more modern/SaaS, lets the hero card and the
     animated component glows pop without competing visual noise. */
  .lof::before{
    background:
      radial-gradient(56rem 30rem at 50% -7rem, rgba(91,195,249,.16), transparent 62%),
      radial-gradient(46rem 26rem at 50% 15%, rgba(227,38,54,.10), transparent 60%),
      linear-gradient(180deg, #070d18 0%, #050a14 55%, #03070f 100%);
  }
  /* Backdrop ::after layer, responsive:
       • Mobile (<=920px): hidden → clean solid (gradient + glows only).
       • Desktop (>=921px): the subtle blueprint grid overlay (faint, masked
         to the hero), paired with the desktop coach marquee.
     The base `display:none` also overrides the global `.lof::after` blue-glow
     layer in tailwind/input.css, so that dormant layer never shows through on
     mobile (on desktop the grid background covers it). Grids read busier on
     narrow screens, hence desktop-only; the cyan/red glows live on ::before. */
  .lof::after{ display:none; }
  @media (min-width:921px){
    .lof::after{
      content:""; display:block; position:fixed; inset:0; z-index:-2; pointer-events:none;
      background-image:
        linear-gradient(rgba(140,170,210,.05) 1px,transparent 1px),
        linear-gradient(90deg,rgba(140,170,210,.05) 1px,transparent 1px);
      background-size:58px 58px;
      -webkit-mask-image:radial-gradient(64rem 46rem at 50% -2rem,#000 48%,transparent 100%);
      mask-image:radial-gradient(64rem 46rem at 50% -2rem,#000 48%,transparent 100%);
    }}

  /* Small breath above the hero (the nav is hidden on this page — see below).
     `overflow-x:clip` contains the decorative .alp-glow blurs (wider than the
     viewport) so the page can't drift sideways on mobile — same clip the
     About/Features/Guides pages already apply to their <main>. */
  .lof-page main{ padding-top:.6rem; padding-bottom:0; overflow-x:clip; }
  /* On mobile the standard <main> + .alp gutters add ~32px on each side
     between viewport and card. Remove BOTH on .lof-page so cards
     extend edge-to-edge. Each card has its own internal padding so
     content never touches the screen edge. */
  @media (max-width:640px){
    .lof-page main{ padding-left:0; padding-right:0; }
    .lof-page .alp{ padding-left:0; padding-right:0; }}
  /* Hide the top nav on THIS landing only. The `>` is load-bearing:
     match ONLY the navbar (a direct child of <body>), NOT the legal
     footer further down the page, which is also a <nav> (.alp-legal with
     the Terms/Privacy links). The top nav is dark-on-dark here and just
     read as an empty band above the hero; on a conversion page its only
     targets (logo / Discord) are exits. Scoped to .lof-page so the shared
     navbar stays on auth pages — same call as the checkout page. */
  .lof-page > nav{ display:none; }
  /* The base .lof wrapper carries 1.5rem top padding; on this landing the
     hero should sit right under the (shrunk) nav and into the grid, so
     drop just the top padding here (scoped — other .lof pages unaffected). */
  .lof-page .lof{ padding-top:0; }

  /* ===== HOMEPAGE HEADER =====
     The shared public header (brand on the left, links on the right,
     frosted bar) now lives in input.css and applies to every public page
     (home, about, features, auth). The homepage is the one long page where
     it also STICKS on scroll. base.html pins the body to a single viewport
     (`h-full` = height:100%) — the sticky element's containing block — so
     the header would release after one screen; let the homepage body grow
     with its content instead so it stays pinned the whole way down. */
  body.lof-page{ height:auto; min-height:100vh; }
  .lof-page .landing-nav{ position:sticky; top:0; z-index:50; }
  /* Desktop: the trial hero card is tucked flush under this nav, so soften the
     nav (drop the hard bottom hairline + drop-shadow) for a clean seam, and drop
     the small top breath above the card so it sits right under the bar. Trial
     hero only (:has(.ggx)); mobile + the non-trial homepage keep the solid bar. */
  @media (min-width:980px){
    body.lof-page:has(.ggx) .landing-nav{ border-bottom:0; box-shadow:none; }
    body.lof-page:has(.ggx) main{ padding-top:0; }}

  /* ===== HOMEPAGE HERO CTA =====
     "Start learning" button under the hero copy (homepage only). */
  .lof-hero-cta-note{ font-size:.8rem; color:#9fb0c9; letter-spacing:.01em; }
  /* "incl. VAT" note next to the trial price — shown only for EU visitors
     (geo_vat.js toggles [hidden] from the browser timezone on load). */
  .lof-vat-note{ color:#8493a8; font-weight:600; white-space:nowrap; }
  /* Inside a join button's words (partials/_join_label.html, applications parked)
     the note is part of the label: the button's own white on red, not the grey
     that was chosen for the dark page (2026-09-26). */
  .join-price .lof-vat-note{ color:inherit; font-weight:inherit; }
  /* WCAG AA on the dark hero band: #9fb0c9 was borderline for this small
     trust text, so use the brighter body token (#c4cde0). */
  .lof-guarantee{ font-size:.78rem; color:#c4cde0; letter-spacing:.015em; }
  /* Hero value-stack — the few things you get, right under the price, so the
     offer panel answers "what do I get" before the CTA. */
  .lof-hero-incl{ list-style:none; margin:0; padding:0; width:100%;
    display:flex; flex-direction:column; gap:.32rem; }
  .lof-hero-incl li{ font-size:.8rem; color:#c4cde0; line-height:1.35;
    display:flex; align-items:flex-start; gap:.42rem; text-align:left; }
  .lof-hero-incl li::before{ content:"\2713"; color:#16a34a; font-weight:900; flex:none; }
  .lof-guarantee::before{ content:"\2713"; color:#16a34a; font-weight:900; margin-right:.4rem; }
  /* Unified hero offer panel — one bordered card so badge + price + reframe +
     CTA + guarantee read as a single offer (was a loose 5-item stack). */
  .lof-hero-offer{ display:flex; flex-direction:column; align-items:center; gap:.7rem;
    width:100%; max-width:23rem; margin:0 auto; padding:1.15rem 1.25rem 1.3rem;
    border-radius:1rem; background:rgba(15,23,40,.55); border:1px solid rgba(120,150,205,.22); }
  .lof-hero-offer-badge{ display:inline-flex; align-items:center; gap:.3rem;
    font-family:var(--font-display); font-size:.7rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
    color:#34d399; background:rgba(52,211,153,.1); border:1px solid rgba(52,211,153,.42);
    padding:.3rem .72rem; border-radius:999px; }
  .lof-hero-offer-price{ display:flex; align-items:baseline; gap:.5rem; }
  /* Price uses Inter (body) + tabular-nums — Orbitron reads badly on numbers. */
  .lof-hero-offer-price .amt{ font-weight:800; font-size:2.5rem; line-height:1; color:#fff;
    font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
  .lof-hero-offer-price .per{ font-size:1.05rem; font-weight:700; color:#aebbcf; }
  .lof-hero-offer-price .was{ font-size:1.15rem; color:#8493a8; text-decoration:line-through; text-decoration-color:rgba(255,99,110,.8); }
  .lof-hero-offer .lof-hero-ctas, .lof-hero-offer .alp-hero-cta{ width:100%; }
  .lof-hero-offer .lof-guarantee{ margin:0; }
  /* Mobile hero order (requested): kicker → headline → subtext → price card →
     founder photo → review. The checkmarks render INSIDE the price card on
     mobile (.lof-hero-incl--inbox), so the separate left-column copy is hidden.
     Both .alp-about-text and .lof-hero-band are display:contents on mobile so
     their children become hero-grid items and `order` interleaves them. Desktop
     (≥780px) lays the band out as three columns instead. */
  @media (max-width:780px){
    .alp-about-text{ display:contents; }
    .lof-hero-band{ display:contents; }
    .lof-hero-incl--col{ display:none; }   /* checkmarks live inside the price card on mobile */
    .alp-about-title{ order:1; }      /* headline first */
    .lof-sims-lead{ order:2; }        /* then the courses / pro-coaching subtext */
    .lof-hero-band-main{ order:3; }   /* price card (checkmarks + logos inside) */
    .alp-about-photo{ order:4; }      /* founder photo */
    .lof-hero-proof{ order:5; }}

  /* ===== Hero band — three columns on desktop: included list (left), the
     price/offer (center), the founder review (right) — so it fills the width
     instead of floating as a centered card. Mobile stacks them (see the order
     rules above; the band is display:contents there). ===== */
  .lof-hero-band{ width:100%; margin:0 auto; }
  .lof-hero-band-main{ display:flex; flex-direction:column; align-items:center;
    justify-content:center; width:100%; }
  /* Hero divider — fading hairline between the pitch and the offer band. Shown
     on desktop only (see the min-width rule); hidden on mobile where it stacks. */
  .lof-hero-sep{ display:none; }

  /* Founder portrait caption — names the LCP face + ties it to the 25M-view authority. */
  .alp-about-photo-cap{ display:flex; flex-direction:column; align-items:center; gap:.12rem;
    margin:.85rem auto 0; text-align:center; }
  .alp-about-photo-name{ font-family:var(--font-display); font-weight:800; font-size:1rem; color:#fff; letter-spacing:.01em; }
  .alp-about-photo-role{ font-size:.8rem; color:#9fb0c9; font-weight:600; }
  /* Founder social-proof chips (YouTube + Instagram reach) — ties both
     audiences to the founder's face as verifiable, clickable authority. */
  .alp-about-photo-socials{ display:flex; flex-wrap:nowrap; align-items:center; justify-content:center; gap:.45rem; margin-top:.5rem; }
  .alp-about-photo-soc{ display:inline-flex; align-items:center; gap:.35rem;
    padding:.28rem .6rem; border-radius:999px; font-size:.78rem; font-weight:700; line-height:1;
    color:#dfe6f2; text-decoration:none; background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.1);
    transition:background .15s ease, border-color .15s ease; }
  .alp-about-photo-soc svg{ width:.95rem; height:.95rem; flex:none; }
  .alp-about-photo-soc strong{ color:#fff; }
  .alp-about-photo-soc:hover{ background:rgba(255,255,255,.09); border-color:rgba(255,255,255,.2); }
  .alp-about-photo-soc--yt svg{ color:#ff0033; }
  .alp-about-photo-soc--ig svg{ color:#e1306c; }
  .alp-about-photo-soc--tt svg{ color:#f4f6fb; }

  /* Price-lock hook at the hero price (was buried in a collapsed FAQ) — the honest
     "act now" lever: your rate never rises while new members pay full. */
  .lof-hero-lock{ display:inline-flex; align-items:center; gap:.4rem; max-width:100%;
    padding:.35rem .8rem; border-radius:999px; font-size:.78rem; font-weight:700; line-height:1.3;
    color:#34d399; background:rgba(52,211,153,.1); border:1px solid rgba(52,211,153,.32); }
  .lof-hero-lock svg{ width:.85rem; height:.85rem; flex:none; }
  .lof-hero-lock-txt{ min-width:0; }
  .lof-hero-lock strong{ color:#fff; }

  /* Supported-sim logos, integrated at the bottom of the offer card. */
  .lof-offer-sims{ display:flex; align-items:center; justify-content:center; gap:1.1rem;
    width:100%; margin-top:.55rem; padding-top:.85rem; border-top:1px solid rgba(255,255,255,.09); }
  .lof-offer-sims img{ height:1.75rem; width:auto; max-width:5.25rem; object-fit:contain; opacity:.7; }
  /* Compact single testimonial directly under the hero — the warm visitor's
     first social proof without scrolling to the full Driver Results block. */
  .lof-hero-proof{ margin:1.6rem auto 0; max-width:34rem; padding:.95rem 1.15rem; text-align:center;
    border:1px solid rgba(245,176,65,.32); border-radius:.85rem; background:rgba(245,176,65,.055); }
  .lof-hero-proof-stars{ color:var(--color-warning); font-size:.82rem; letter-spacing:.1em; }
  .lof-hero-proof blockquote{ margin:.35rem 0 .4rem; padding:0; border:0; color:#fff; font-size:.95rem; line-height:1.55; font-style:italic; }
  .lof-hero-proof figcaption{ color:#9fb0c9; font-size:.77rem; }
  .lof-hero-proof-more{ display:inline-block; margin-top:.6rem; font-size:.78rem; font-weight:700;
    color:var(--color-warning); text-decoration:none; border-bottom:1px solid rgba(245,176,65,.4);
    transition:border-color .2s ease, opacity .2s ease; }
  .lof-hero-proof-more:hover{ border-color:var(--color-warning); opacity:.85; }
  .lof-hero-login{ font-size:.82rem; color:#93a6c3; text-decoration:none; border-bottom:1px solid transparent; transition:color .2s ease, border-color .2s ease; }
  .lof-hero-login:hover{ color:#cfe0ff; border-bottom-color:rgba(207,224,255,.5); }

  /* Dual hero CTA (homepage): paid "Unlock the Academy" + free "Community access" */
  .lof-hero-ctas{ display:flex; flex-wrap:wrap; gap:.9rem; align-items:center; justify-content:center; }
  .lof-hero-ctas .alp-hero-cta{ text-transform:none; font-size:1rem; letter-spacing:.01em; padding:1.05rem 2.2rem; }
  .alp-hero-cta-ghost{ position:relative; display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
    font-family:var(--font-display); font-weight:800; font-size:1rem; letter-spacing:.01em;
    color:#dfe6f2; text-decoration:none; background:rgba(255,255,255,.05); padding:1.05rem 2.2rem;
    clip-path:polygon(18px 0,calc(100% - 18px) 0,100% 50%,calc(100% - 18px) 100%,18px 100%,0 50%);
    box-shadow:inset 0 0 0 1.5px rgba(148,163,184,.4);
    transition:transform .18s ease, background .18s ease, box-shadow .18s ease; }
  .alp-hero-cta-ghost:hover{ transform:translateY(-1px); background:rgba(91,195,249,.12);
    box-shadow:inset 0 0 0 1.5px rgba(91,195,249,.65); }
  @media (max-width:560px){
    .lof-hero-ctas{ flex-direction:column; align-items:stretch; width:100%; max-width:24rem; margin:0 auto; }
    .lof-hero-ctas .alp-hero-cta, .lof-hero-ctas .alp-hero-cta-ghost{ width:100%; }}

  /* ===== STICKY MOBILE CHECKOUT BAR ===== */
  /* A permanent bottom CTA on phones so checkout is always one tap away
     while scrolling the long landing. Pure CSS (position:fixed) — no
     scroll JS. Hidden on desktop, where the offer card + hero CTA stay
     in view. Sits below the cookie-consent card (z-index 9999), so that
     one-time banner takes priority until the visitor accepts/declines. */
  .alp-sticky-cta{ display:none; transition:opacity .25s ease, transform .25s ease; }
  /* Fade the persistent CTA out while a colliding zone is in view (the final
     offer card it double-stacks with, or a section whose edge arrows it covered).
     JS toggles --clear via IntersectionObserver. */
  .alp-sticky-cta--clear{ opacity:0; pointer-events:none; transform:translateY(10px); }
  @media (max-width:640px){
    .alp-sticky-cta{
      position:fixed; left:0; right:0; bottom:0; z-index:60;
      display:flex; justify-content:center; align-items:center;
      padding:.6rem .9rem calc(.6rem + env(safe-area-inset-bottom));
      background:linear-gradient(180deg,rgba(10,14,22,.86),rgba(7,10,18,.97));
      backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
      border-top:1px solid rgba(255,255,255,.12);
      box-shadow:0 -10px 28px rgba(0,0,0,.5);
      text-decoration:none;
    }
    /* Centered CTA button with the discount stacked under the label. */
    .alp-sticky-cta-btn{
      width:100%; max-width:26rem;
      display:flex; flex-direction:column; align-items:center; gap:.12rem;
      /* Archivo like every other red join button on the page (owner 2026-09-27),
         not the Orbitron --font-display. */
      font-family:'Archivo',system-ui,sans-serif; color:#fff; text-align:center;
      background:linear-gradient(100deg,#e21429,#b00f20);
      padding:.65rem 1rem; border-radius:.75rem;
      box-shadow:0 6px 18px rgba(225,32,50,.45);
    }
    .alp-sticky-cta-btn-main{ font-weight:700; font-size:1rem; line-height:1.1; letter-spacing:.1em; text-transform:uppercase; }
    .alp-sticky-cta-btn-sub{
      font-weight:700; font-size:.72rem; letter-spacing:.14em;
      text-transform:uppercase; color:#fff; line-height:1;
      text-shadow:0 1px 2px rgba(0,0,0,.28);
    }
    /* Homepage variant: readable Inter price (same font family as the
       checkout price) + a "what you get" descriptor instead of the all-caps
       badge — the Orbitron all-caps "$19.99/MO" was hard to read. */
    .alp-sticky-cta--mobile .alp-sticky-cta-btn{ gap:.24rem; }
    .alp-sticky-cta--mobile .alp-sticky-cta-btn-sub{
      font-family:var(--font-sans); font-weight:600; font-size:.82rem;
      letter-spacing:.005em; text-transform:none; line-height:1.25;
      color:rgba(255,255,255,.9);
    }
    .alp-sticky-cta--mobile .alp-sticky-cta-price{
      font-weight:800; letter-spacing:-.015em; color:#fff;
      font-variant-numeric:tabular-nums;
    }
    /* Reserve space so the fixed bar never permanently hides the legal
       footer — the page scrolls its last content above the bar. !important:
       the later, equal-specificity `body.lof-page main{ padding:0 }` hero
       reset otherwise wins by source order (this rule was dead for weeks). */
    body.lof-page main{ padding-bottom:calc(5.5rem + env(safe-area-inset-bottom)) !important; }}
  /* ===== Founder offer card (clean, app-card idiom) =====
     Matches the .alp-about / .alp-platform-feature look — soft rounded
     corners, subtle cyan border, near-opaque dark base with a faint
     accent tint. No clip-path octagons, no double frame. */
  /* Final offer: the race-car image is a FULL-WIDTH band (edge to edge); the
     offer content stays centered on top. `main` has overflow-x:clip so the
     full-bleed band never causes horizontal scroll. */
  .alp-offer{ position:relative; z-index:1; max-width:64rem; margin:0 auto; text-align:center;
    padding:0; border:0; background:none; border-radius:0; box-shadow:none; }

  /* ===== HERO ===== */
  .alp-hero { max-width:62rem; margin:0 auto; padding: clamp(.4rem,1.4vw,.85rem) 1rem 1rem; text-align:center; }
  .alp-hero-cta { position:relative; display:inline-flex; align-items:center; justify-content:center; gap:.7rem;
    font-family:var(--font-display); font-weight:900; font-size:1.05rem; letter-spacing:.06em;
    text-transform:uppercase; color:#fff; text-decoration:none;
    background:linear-gradient(100deg,#e21429,#b00f20); padding:1.15rem 3rem;
    clip-path:polygon(18px 0,calc(100% - 18px) 0,100% 50%,calc(100% - 18px) 100%,18px 100%,0 50%);
    filter:drop-shadow(0 10px 26px rgba(225,32,50,.6));
    transition:transform .18s ease, filter .18s ease; }
  .alp-hero-cta:hover{ transform:translateY(-1px) scale(1.012);
    filter:drop-shadow(0 14px 34px rgba(225,32,50,.9)) brightness(1.06); }
  @media (prefers-reduced-motion:no-preference){
    .alp-hero-cta{ animation:alpCtaPulse 2.6s ease-in-out infinite; }
    @keyframes alpCtaPulse{ 0%,100%{ filter:drop-shadow(0 10px 26px rgba(225,32,50,.55)); }
      50%{ filter:drop-shadow(0 12px 34px rgba(225,32,50,.9)); } }}
  /* legal footer — bottom of the launch-offer page (base.html still
     renders the © line below this). */
  .alp-legal{ max-width:62rem; margin:clamp(2.4rem,6vw,3.6rem) auto 0;
    padding:1.4rem 1rem 1.6rem; border-top:1px solid rgba(255,255,255,.08); text-align:center; }
  .alp-legal-links{ display:flex; flex-wrap:wrap; align-items:center;
    justify-content:center; gap:.4rem .85rem; font-size:.82rem; font-weight:600; }
  .alp-legal-links a{ color:#9fb0c9; text-decoration:none; letter-spacing:.02em; }
  .alp-legal-links a:hover{ color:#fff; text-decoration:underline; text-underline-offset:3px; }
  .alp-legal-sep{ color:#5b6680; }

  .alp-section { padding: clamp(3.5rem,8vw,6rem) 0 0; position:relative; }
  /* Framed mocks: a fixed-design-width desktop comp scaled to fit the
     frame with transform:scale — NOT zoom. iOS WebKit (every iPhone
     browser — Safari AND Chrome — is required to use WebKit) does not
     shrink an element's layout box for `zoom`, so the 1280px comp
     overflowed and inner columns collapsed (per-word wrap) on iPhone.
     The extra_body JS sets the scale from the frame width and collapses
     the reserved (un-scaled) footprint via negative margins, so there
     is no empty space / overflow on ANY engine incl. iOS WebKit. */
  .alp-os { width:1280px; transform-origin:top left;
    display:grid; grid-template-columns:232px 1fr; min-height:600px; background:#070b15; }
  .alp-pane { width:1180px; transform-origin:top left; background:#070b15; }
  /* Phones: render the dashboard + courses mocks as the REAL
     responsive member UI at 1:1 (legible) instead of a ~30% shrunk
     1280px screenshot. !important beats the extra_body fit() inline
     transform. Sidebar nav is hidden — it's empty chrome at thumbnail
     scale; the page's CSS gutters keep the cards off the screen edge. */
  @media (max-width:760px){
    .alp-os{ width:auto !important; transform:none !important; margin:0 !important;
      grid-template-columns:1fr !important; min-height:0; }
    .alp-pane{ width:auto !important; transform:none !important; margin:0 !important; }}

  /* Scroll-reveal removed: elements render visible immediately (no
     opacity:0 → fade-in, no IntersectionObserver dependency). The
     fade-in read as "lag" on mobile — content sat blank until the
     observer fired, especially during fast scrolls. `.alp-reveal` is
     left on the markup as a harmless no-op hook. */
  @media (max-width:680px){
    .alp-section{ padding-top:3rem; }}

  /* ===== ABOUT-STYLE HERO (Option B — sits above the founder offer) ===== */
  .alp-about{ max-width:64rem; margin:0 auto;
    padding:clamp(1.5rem,3vw,2.4rem) clamp(1.25rem,3vw,2rem);
    border:1px solid rgba(91,195,249,.22);
    /* Cyan brand tint on top of a near-opaque dark base, so text stays
       readable over whatever backdrop the page has scrolled to. */
    background:
      linear-gradient(180deg,rgba(91,195,249,.08),rgba(91,195,249,.02)),
      linear-gradient(180deg,rgba(10,14,22,.88),rgba(7,10,18,.93));
    backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
    border-radius:1rem; }
  /* Full-width hero (trial variant): the page wrapper (.lof, max 64rem) + main
     (max 72rem) cap the hero. Lift those caps so the hero fills the viewport
     naturally — NO negative-margin full-bleed trick (that over-shifts in some
     browsers). Every section BELOW the hero keeps its own max-width + margin:
     auto, so they stay centered; only the full hero stretches. */
  body.lof-page main{ max-width:none; padding:0; }
  /* Persistent (sticky) site nav on the homepage — stays pinned on scroll. */
  body.lof-page .landing-nav{ position:sticky; top:0; z-index:50; }
  .lof-page .lof{ max-width:none; padding-left:0; padding-right:0; }
  /* Hero head: title + lead on the left, founder photo on the right
     (≥780px). Stacks single-column on mobile. */
  .alp-about-head{ display:grid; grid-template-columns:1fr;
    gap:1.5rem; align-items:center; }
  .alp-about-text{ }
  /* Photo order is set per-breakpoint by the hero-order media rules (mobile:
     order:2, directly under the headline; desktop: order:0). No base `order`
     here, or it would override the earlier @media rule (equal specificity,
     later wins). */
  .alp-about-photo{ margin:0; display:flex; flex-direction:column; align-items:center; }
  /* Frame wraps the portrait so we can layer a blurred, radially-masked
     dashboard screenshot behind it ("Marian standing in front of the
     platform" composition). */
  .alp-about-photo-frame{ position:relative; width:100%; max-width:16rem; }
  .alp-about-photo-frame::before{
    content:""; position:absolute; inset:-1rem;
    background:url("../../images/academy_features/ss_1.d27975bb54fd.webp") center 30% / cover no-repeat;
    border-radius:1.2rem;
    opacity:.5; filter:blur(2px) saturate(1.05);
    -webkit-mask:radial-gradient(closest-side at 50% 45%, #000 0%, rgba(0,0,0,.85) 55%, transparent 100%);
    mask:radial-gradient(closest-side at 50% 45%, #000 0%, rgba(0,0,0,.85) 55%, transparent 100%);
    z-index:0; pointer-events:none;
  }
  .alp-about-photo img{ position:relative; z-index:1;
    display:block; width:100%; height:auto;
    filter:drop-shadow(0 0 30px rgba(91,195,249,.25)) drop-shadow(0 14px 28px rgba(0,0,0,.6)); }
  @media (min-width:780px){
    .alp-about-head{ grid-template-columns:1.45fr 1fr; gap:2.4rem; }
    .alp-about-text{ text-align:left; }
    .alp-about-photo{ order:0; }
    /* Founder portrait sized as the hero's focal point — large enough to
       anchor the first section. Columns are centre-aligned so the taller photo
       extends evenly above/below the headline block. */
    .alp-about-photo-frame{ max-width:19rem; }
    /* On desktop the checkmarks are a separate LEFT card; the in-box copy
       (shown on mobile) is hidden here. */
    .lof-hero-incl--inbox{ display:none; }
    /* Fading hairline separating the pitch from the offer band. */
    .lof-hero-sep{ display:block; grid-column:1 / -1; height:1px; margin:.6rem 0 1.6rem;
      background:linear-gradient(90deg, transparent 0%, rgba(120,150,205,.28) 24%,
        rgba(91,195,249,.5) 50%, rgba(120,150,205,.28) 76%, transparent 100%); }
    /* Three columns: what's included (left), the price/offer (center), the
       founder review (right). The CENTER is wider + taller + brighter so it
       pops as the featured card; the two sides are smaller neutral-blue cards
       (centre-aligned, so they're shorter than the center). */
    .lof-hero-band{ grid-column:1 / -1; display:grid;
      grid-template-columns:1fr 1.3fr 1fr; column-gap:1.75rem; align-items:center; }
    /* Side cards (included + review) — matching blue cards, smaller height. */
    .lof-hero-band .lof-hero-incl--col,
    .lof-hero-band .lof-hero-proof{ justify-content:center;
      border:1px solid rgba(120,150,205,.2); background:rgba(15,23,40,.4);
      border-radius:.85rem; padding:1rem 1.25rem; }
    .lof-hero-band .lof-hero-proof{ margin:0; max-width:none; }
    .lof-hero-band-main{ min-width:0; }
    /* Center offer — bigger + brighter + a soft blue glow so it's the hero. */
    .lof-hero-band .lof-hero-offer{ max-width:none; width:100%; padding:1.7rem 1.6rem;
      border-color:rgba(91,195,249,.42);
      box-shadow:0 0 0 1px rgba(91,195,249,.12), 0 18px 46px rgba(0,0,0,.5); }}
  /* Category kicker above the H1 — names "sim racing" instantly (the 5-second
     qualification cue cold traffic needs). */
  .alp-about-kicker{ display:block; font-family:var(--font-display); font-weight:800;
    font-size:.78rem; letter-spacing:.2em; text-transform:uppercase;
    color:var(--color-secondary); margin:0 0 .7rem; text-align:center; }
  @media (min-width:780px){ .alp-about-kicker{ text-align:left; }}
  /* Matches .alp-hero-title (clamp/line-height/letter-spacing) for visual parity. */
  .alp-about-title{ font-family:var(--font-display); font-weight:900;
    font-size:clamp(2.3rem,5.6vw,4.3rem); line-height:1.03; letter-spacing:-.02em;
    margin:0 auto; max-width:46rem; text-align:center; color:#fff; overflow-wrap:anywhere; }
  @media (min-width:780px){
    .alp-about-title{ text-align:left; margin:0; max-width:none; }}
  .lof-sims-eyebrow-accent{
    background:linear-gradient(90deg, #5BC3F9 0%, #6c8cf7 100%);
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
  }
  /* Hero value lead (replaces the old "One platform / Every popular sim"
     eyebrow): a readable one-liner of what the membership includes, sitting
     above the supported-sim logos. */
  .lof-sims-lead{ max-width:33rem; margin:1.5rem 0 0; font-size:1.02rem; line-height:1.55;
    color:#c4cde0; font-weight:500; }
  .lof-sims-lead .lof-sims-eyebrow-accent{ font-weight:700; }
  @media (max-width:780px){ .lof-sims-lead{ text-align:center; }}

  /* 8s cycle, 4 tiles × 2s delay step = a single tile is "active" at any
     moment (1s rise → 1s fall → 6s dormant). Reads as a spotlight sweeping
     the row in a clean rhythm. */

  /* Partner / trust strip — an infinite left→right logo marquee under
     the hero stats. CSS-only: the track holds TWO identical logo sets and
     translates -50% for a seamless loop. Edge-fade mask, pause on hover,
     and a prefers-reduced-motion stop that wraps the logos statically. */
  /* Top margin = bottom margin + the next section's 3rem padding-top, so the
     gap above the eyebrow matches the gap below the bar (to "The complete
     package") at every breakpoint. */
  /* /launch-offer/ ONLY since 2026-09-15: the homepage renders
     partials/trusted_approach.html instead. The measure (calc(100% - 48px),
     max 1340px) is the one the strip was tuned at. */
  .alp-partners{ margin:calc(clamp(3.75rem,8vw,6rem) + 3rem) auto clamp(3.75rem,8vw,6rem);
    width:calc(100% - 48px); max-width:1340px; padding:0; }
  .alp-partners-eyebrow{ font-family:var(--font-display); font-size:.7rem; font-weight:800;
    letter-spacing:.2em; text-transform:uppercase; color:#9fb0c9; text-align:center; margin:0 0 .9rem; }
  /* ONE bar holds the whole strip — logos sit directly on it, separated by
     faint vertical dividers (not a box per logo). */
  .alp-partners-bar{ border:1px solid rgba(255,255,255,.08); border-radius:1rem;
    background:linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.01));
    overflow:hidden; padding:.5rem 0; }
  .alp-partners-viewport{ position:relative; overflow:hidden;
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
            mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent); }
  .alp-partners-track{ display:flex; width:max-content; animation:alpPartnersScroll 34s linear infinite; }
  /* Hover slows the scroll to a crawl (not a freeze) — handled in JS via
     the Web Animations API playbackRate so the speed change is seamless. */
  .alp-partner-set{ display:flex; align-items:center; }
  /* Shorter cells (owner 2026-08-25): 7rem of height for a logo that is at
     most 3.1rem tall was mostly empty space. The logos themselves are
     unchanged — only the room around them shrank. */
  .alp-partner{ flex:0 0 auto; display:flex; align-items:center; justify-content:center;
    width:13.5rem; height:4.4rem; padding:.4rem 1.5rem;
    border-left:1px solid rgba(255,255,255,.07); }
  .alp-partner img{ max-width:100%; max-height:3.1rem; object-fit:contain;
    opacity:.82; transition:opacity .2s ease; }
  .alp-partner:hover img{ opacity:1; }
  /* BOX ONE RACING ships as a dark logotype on a white JPG background — give
     just that one a white plate so it reads (like the Pit Road card in the
     reference), instead of a dark-on-dark block. */
  .alp-partner-plate img{ background:#fff; border-radius:.4rem; padding:.42rem .65rem;
    max-height:5.4rem; opacity:1; box-sizing:border-box; }
  /* Conspit ships as a white wordmark on its purple brand square — round the tile
     corners so it reads as an intentional badge (like the SRN tile), not a sticker. */
  .alp-partner-conspit img{ border-radius:.5rem; opacity:1; }
  @keyframes alpPartnersScroll{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }
  @media (prefers-reduced-motion:reduce){
    .alp-partners-track{ animation:none; }
    .alp-partner-set{ flex-wrap:wrap; justify-content:center; }
    .alp-partner-set + .alp-partner-set{ display:none; }
    .alp-partners-viewport{ -webkit-mask-image:none; mask-image:none; }}

  /* "Built for drivers on" — 4 game logos in a row inside the hero band
     (ad variant). Set by height (not width) so different aspect ratios still
     read as a consistent row. */
  .alp-about-games-row{ display:flex; align-items:center; justify-content:center;
    flex-wrap:wrap; gap:clamp(1rem,3vw,2.4rem); margin-top:.9rem; }
  .alp-about-games-row img{ height:clamp(26px, 3.4vw, 38px); width:auto;
    max-width:60vw; object-fit:contain; opacity:.78;
    filter:grayscale(1) brightness(1.15);
    transition:opacity .2s ease, filter .2s ease; }
  /* Per-logo size balancing: iRacing (1st) + ACC (3rd) are wide
     horizontal wordmarks — drop them 25% so they don't overpower the
     row. LMU (2nd) reads small at the base height — push it +20%. */
  .alp-about-games-row img:nth-child(1),
  .alp-about-games-row img:nth-child(3){ height:clamp(19.5px, 2.55vw, 28.5px); }
  .alp-about-games-row img:nth-child(2){ height:clamp(23px, 3vw, 33.5px); }
  .alp-about-games-row img:hover{ opacity:1; filter:grayscale(0) brightness(1); }
  /* Self-contained library grid — avoids the page's .alp-courses rules
     (which include a 6-card-specific nth-child(5) override). Cards get an
     explicit surface since the global .lesson-card is transparent and
     relied on a dark section behind it. */
  /* Course slider — horizontal scroll-snap carousel of the library cards
     with prev/next arrows (hidden on mobile — swipe instead). JS at the
     bottom of the file wires the arrows. Cards get an explicit surface
     since the global .lesson-card is transparent. */
  .lof-slider{ position:relative; }
  .lof-slider-track{ display:flex; gap:.85rem; overflow-x:auto; scroll-snap-type:x proximity;
    padding:.3rem .15rem; scrollbar-width:none; -ms-overflow-style:none; }
  .lof-slider-track::-webkit-scrollbar{ display:none; }
  .lof-slider-prev{ left:-.7rem; }
  .lof-slider-next{ right:-.7rem; }
  @media (max-width:680px){
    .lof-slider-prev{ left:.2rem; } .lof-slider-next{ right:.2rem; }}
  .lof-road-stage{ position:relative; display:flex; gap:1.15rem; padding-bottom:2.3rem; }
  .lof-road-stage:last-child{ padding-bottom:0; }
  .lof-road-stage:not(:last-child)::before{ content:""; position:absolute; left:18px; top:46px; bottom:-4px; width:2px;
    background:linear-gradient(180deg, var(--node,#5bc3f9), color-mix(in srgb,var(--node,#5bc3f9) 10%, transparent)); }

  /* Stages 2 + 3 collapse into rich "chapter" bars (.lof-road-toggle) that expand
     on click — Stage 1 stays open. The grid-template-rows 0fr->1fr trick animates
     the height; .open (toggled by JS on the <li>) drives chevron/label/pad too. */
  .lof-road-toggle{ position:relative; width:100%; display:flex; align-items:center; justify-content:space-between;
    gap:1rem; text-align:left; cursor:pointer; appearance:none; -webkit-appearance:none; color:inherit; font:inherit;
    background:linear-gradient(180deg,rgba(15,22,38,.72),rgba(9,14,26,.86));
    border:1px solid color-mix(in srgb,var(--node) 30%,rgba(255,255,255,.12)); border-radius:1rem;
    padding:1rem 1.15rem 1rem 1.35rem; transition:transform .18s ease, border-color .18s ease, background .18s ease; }
  .lof-road-toggle::before{ content:""; position:absolute; left:0; top:14px; bottom:14px; width:4px; border-radius:0 4px 4px 0;
    background:linear-gradient(180deg,var(--node),color-mix(in srgb,var(--node) 20%,transparent)); box-shadow:0 0 14px -2px var(--node); }
  .lof-road-toggle:hover{ transform:translateY(-2px); border-color:color-mix(in srgb,var(--node) 55%,transparent);
    background:linear-gradient(180deg,rgba(18,27,46,.82),rgba(11,16,30,.92)); }
  .lof-road-toggle:focus-visible{ outline:2px solid var(--node); outline-offset:2px; }
  .lof-road-tglbl{ font-family:var(--font-display); font-weight:800; font-size:.62rem; letter-spacing:.08em; text-transform:uppercase; color:var(--node); }
  /* collapse animation: JS animates .lof-road-collapse height 0 <-> scrollHeight
     (bulletproof easing, unlike fr-interpolation which resolves flaky here), then
     releases to height:auto; the pad fades in and is made non-focusable via delayed
     visibility so Tab can't land on hidden links when collapsed. */
  .lof-road-collapse{ height:0; overflow:hidden; transition:height .5s cubic-bezier(.4,.7,.2,1); }
  /* pulsing ring on closed chevrons advertises the tap */
  @media (prefers-reduced-motion: no-preference){
}

  /* responsive */
  @media (max-width:820px){
    .lof-road-tglbl{ display:none; }
    .lof-road-toggle{ padding:.85rem 1rem .85rem 1.2rem; }}
  @media (max-width:520px){
    .lof-road-stage{ gap:.85rem; }
    .lof-road-stage:not(:last-child)::before{ left:15px; }}

  /* ===== FAQ — straight Q/A pairs, no JS accordion. ===== */

  /* ===== Desktop sticky CTA — same fixed element at >640px, tucked
     bottom-right as a small floating button. ===== */
  @media (min-width:641px){
    /* Desktop floating CTA shows on BOTH the homepage and the ad variant — the
       hero CTA scrolls away on the long page, so a persistent priced button
       (bottom-right) keeps the action one click away. (The `--mobile` modifier
       still drives the richer mobile bottom-bar styling at ≤640px; it no longer
       suppresses the desktop button.) */
    .alp-sticky-cta{
      position:fixed; left:auto; right:1.5rem; bottom:1.5rem; z-index:60;
      display:inline-flex; align-items:center; padding:.75rem 1.25rem;
      border-radius:.65rem;
      background:linear-gradient(100deg,#e21429,#b00f20);
      box-shadow:0 12px 32px rgba(225,32,50,.45),
                 inset 0 0 0 1px rgba(255,255,255,.08);
      text-decoration:none;
    }
    .alp-sticky-cta-btn{
      display:inline-flex; flex-direction:column; align-items:flex-start; gap:.12rem;
      font-family:'Archivo',system-ui,sans-serif; color:#fff;
    }
    .alp-sticky-cta-btn-main{ font-weight:700; font-size:.95rem; line-height:1.1; letter-spacing:.1em; text-transform:uppercase; }
    .alp-sticky-cta-btn-sub{
      font-weight:700; font-size:.62rem; letter-spacing:.12em;
      text-transform:uppercase; color:#fff; opacity:.85; line-height:1;
    }}

  /* Stint Analyzer showcase styles live in partials/analyzer_mockup.html
     (shared with the features page). */

  /* ---- Free guide email capture ---- */

/* === block 2 -- was the mobile-hero-restructure <style> in content block (template lines 1721-2665) === */
  @media (max-width:780px){
    /* stat pills */
    .alp-mstats{ display:none; }}

  /* ====================================================================
     HERO "OPTION B" — exact port of homepageDesign/design_handoff_hero,
     scoped under .ggx so its tokens + reset never leak to the rest of the
     page. Desktop .ggx-d (.cx-hero, 3-col) + mobile .ggx-m (.mbo-hero,
     stack), toggled at 980px. ==================================================================== */
  .ggx{ --cyan:#5BC3F9; --cyan-soft:rgba(91,195,249,.08); --cyan-bd:rgba(91,195,249,.30); --cyan-glow:rgba(91,195,249,.16);
    --red:#e21429; --red-2:#b00f20; --red-soft:rgba(226,20,41,.12);
    --gold:#F5B041; --green:#34d399; --green-soft:rgba(52,211,153,.12); --check:#16a34a;
    --ink:#fff; --lead:#c8d2e6; --cardtext:#dfe6f2; --muted:#9fb0c9; --faint:#8ea0bd;
    --line:rgba(255,255,255,.08); --line-2:rgba(255,255,255,.12); --line-3:rgba(255,255,255,.18);
    width:100%; color:var(--ink); font-family:'Inter',system-ui,sans-serif; }
  .ggx *{ box-sizing:border-box; } .ggx img{ display:block; }
  /* "every week." is the ONE blue the page uses for its accents (owner
     2026-09-15: "use the same blue"), the same #5BC3F9 as "what to practise."
     in the band below. It used to be a white-to-cyan-to-red gradient clipped to
     the text. */
  .ggx .g{ color:#5BC3F9; }
  .ggx .heroBg{ position:relative; overflow:hidden;
    background:
      radial-gradient(820px 520px at 50% -4%, var(--cyan-glow), transparent 60%),
      radial-gradient(720px 480px at 50% 34%, rgba(227,38,54,.10), transparent 62%),
      linear-gradient(180deg, #070d18 0%, #050a14 55%, #03070f 100%); }
  /* THE GARAGE (owner's mock, 2026-09-15). The hero's backdrop is a
     photograph of the academy's garage: a GITGUD RACING flight case and
     tyres at the right, a rig behind them, the left two thirds dark for the
     copy. From media/newHomepage/backgr4.png (fourth cut: no grid drawn over
     it as in the first, no helmet on the case as in the second, no
     "DISCIPLINE DRIVES PROGRESS" on the wall as in the third), encoded at its native
     1672x941 (static/images/hero/rig-room.webp; dark and soft, so WebP eats
     it). The gradients in .heroBg stay underneath as the paint the page shows
     for the moment before the photo arrives, so there is no flash and no
     layout jump. `cover`, centred: a 16:9 viewport uses the whole frame, a
     squarer one loses a little of both sides rather than the wall. The old
     .grid-ov overlay is gone from both live heroes with it: no grid anywhere
     in this hero (owner). */
  /* NAVY SHADE over the photo (owner 2026-09-15: "a shade of darker blue like the nav
     bar ... the colour seems too bright and light"). The top layer is the nav's own
     rgb(9,13,22) at .45, flat, so the photo keeps its detail but sits in the same deep
     navy as the bar above it. It is a background layer, so the portrait, cards and
     type above it are untouched. --ggx-hero-shade is the one knob. */
  .ggx{ --ggx-hero-shade:rgba(9,13,22,.45); --ggx-hero-blur:7px; }
  /* THE PHOTO IS DEFOCUSED BEHIND HIM (owner 2026-09-17). It had no blur at all:
     the file is soft to begin with, and at `cover` on a 16:9 screen the flight
     case, the tyres and the rig behind them were all still legible enough to
     compete with the portrait cut out in front of them.

     It has to be a PSEUDO-ELEMENT, not a filter on .heroBg, because .heroBg is
     also the element every piece of hero content sits inside - blurring it would
     blur the headline, the card and Marian with it. So the photo and its navy
     shade move here, on a layer at z-index 0 (under .cx-founder at 1 and .cx-body
     at 4), and only that layer is filtered. Blurring the flat shade with it costs
     nothing; a flat colour is unchanged by a blur.

     `inset` is negative by twice the radius because blur() samples transparency
     beyond the element's own box and would otherwise fade the photo out at all
     four edges. .heroBg is overflow:hidden, so the overhang is cropped.

     --ggx-hero-blur is the one knob. The base gradient stays on .heroBg itself as
     the paint shown before the photo decodes. */
  .ggx-d.heroBg{ background-image:linear-gradient(180deg, #070d18 0%, #050a14 55%, #03070f 100%);
    background-size:auto; background-position:0 0; background-repeat:no-repeat; }
  .ggx-d.heroBg::before{ content:""; position:absolute;
    inset:calc(-2 * var(--ggx-hero-blur)); z-index:0; pointer-events:none;
    background-image:linear-gradient(var(--ggx-hero-shade), var(--ggx-hero-shade)),
      url("../../images/hero/rig-room.f8b3e91b3252.webp");
    background-size:auto, cover; background-position:0 0, 50% 50%; background-repeat:no-repeat;
    filter:blur(var(--ggx-hero-blur)); }
  /* On phones the photo is a band behind the headline, not a cover: the
     stacked hero is several screens tall and `cover` would blow a 941px frame
     up five times. 520px tall, anchored so the rigs on the right of the frame
     show beside the headline, fading into the base gradient before the founder
     band starts. The band's height is max(520px, 56.25vw) so the 16:9 frame is
     never narrower than the hero: this layout runs up to 979px wide, and at a
     fixed 520px the 960x540 file is only 924px across, which left a hard
     vertical photo edge beside the headline between 925 and 979px. The fade
     layer takes the same height so it still ends where the photo ends. */
  .ggx-m.heroBg{ background-image:
      linear-gradient(180deg, rgba(9,13,22,.55) 0%, rgba(9,13,22,.55) 45%, #050a14 100%),
      url("../../images/hero/rig-room-m.7d8c7191f2e6.webp"),
      linear-gradient(180deg, #070d18 0%, #050a14 55%, #03070f 100%);
    background-size:100% max(520px,56.25vw), auto max(520px,56.25vw), auto; background-position:0 0, 64% 0, 0 0; background-repeat:no-repeat; }

  /* nav (desktop) */
  .ggx .nav{ position:relative; z-index:6; height:76px; display:flex; align-items:center; justify-content:space-between; padding:0 36px; border-bottom:1px solid var(--line); }

  /* ---- DESKTOP: .cx-hero 3-col, one full screen under the nav ----
     A `flex` column: the founder photo layer (absolute), the 3-col content
     grid (flex:1, so it takes the height), and the footer row with the scroll
     cue. The grid's bottom-pinned review + offer card land just above that
     row. --ggx-navh is the desktop nav height used to size the fill.
     Desktop-only via the .ggx-d display toggle; mobile .mbo-hero is separate. */
  /* MEASURED, not guessed: .landing-nav is 70px. The old 77 was 7px of phantom
     height the hero was told to leave for a nav that does not need it. */
  /* --ggx-under: the hero stops this much short of the fold (owner, 2026-09-15,
     a red line drawn just under the cards: "the page ends at the red line so
     it will occupy less vertical space"). The band below the cards was fade
     and tagline only; now the next section peeks in there instead, which is
     also the scroll invitation the cue is making. Height-relative like every
     other vertical here; ~40px at 900. */
  .ggx{ --ggx-navh:70px; --ggx-under:clamp(30px,4.4vh,44px); }
  /* FULL-BLEED since the photograph (owner's mock, 2026-09-15). Until then this
     was a contained card, width:calc(100% - 48px), rounded, bordered, with a
     gap under it: the frame that made a gradient read as a designed surface.
     A photograph inside that frame reads as a picture on a page, so the frame
     went; the paint now runs edge to edge and flush to the next section. The
     content grid keeps the card's 1340px measure (see .cx-body), so nothing
     inside moved. */
  .ggx .cx-hero{ width:100%; min-height:calc(100vh - var(--ggx-navh) - var(--ggx-under)); margin:0; }
  /* 2-row grid: headline banner spans cols 1-2 across the top; checklist +
     offer sit in row 2 below it; the founder photo column spans BOTH rows
     (full height on the right). */
  /* Bottom padding is small because the footer row under this grid now owns
     the space beneath the offer card; the row-gap gave a few px back for the
     same reason. Both are height-relative so they shrink first on a short
     screen. Width is the old card's measure, centred inside the full-bleed
     hero. */
  .ggx .cx-body{ position:relative; z-index:4; flex:1 1 auto; width:100%; max-width:1340px; margin:0 auto; display:grid; grid-template-columns: 1fr var(--ggx-mid) 1fr; grid-template-rows:auto 1fr; column-gap:26px; row-gap:clamp(8px,1.4vh,22px); padding:clamp(14px,2.4vh,34px) var(--ggx-pad) clamp(2px,0.5vh,6px); align-items:stretch; }
  /* Headline is flush LEFT (owner 2026-07-24) -- was centre-aligned, which
     ragged the three lines against each other. Left-aligning gives the block a
     hard vertical edge that lines up with the "WHAT'S INCLUDED" column beneath
     it in grid-column 1. */
  .ggx .cx-head{ grid-column:1 / 3; grid-row:1; display:flex; flex-direction:column; justify-content:center; align-items:flex-start; text-align:left; min-width:0; }
  /* .cx-left held WHAT'S INCLUDED in row 2 of column 1 and came out on
     2026-09-17 (owner) - the application card occupies that cell now. The
     .cx-included rules it scoped are still live for the offer modal, which
     renders the same partial. */
  /* The middle column is a wrapper (.cx-offer-col) holding the offer card and,
     hung beneath it, the scroll cue; the card itself is the shared partial. */
  .ggx .cx-body .cx-offer-col{ grid-column:2; grid-row:2; align-self:end; position:relative; min-width:0; }
  .ggx .cx-offer-col .cx-offer{ width:100%; }
  /* THE OFFER CARD IS THE CENTRE OF THE SCREEN (owner's mock, 2026-09-15).
     Until now the headline band spanned columns 1-2 and the card sat under
     it, bottom-aligned; the lede ran out under the card's column. Now the
     headline block keeps to column 1, so the lede wraps at the column's
     width, and the card takes the middle column across both rows, centred
     vertically: the exact middle of the hero, with the scroll cue directly
     beneath it (owner: "under the box").
     The headline itself is NOT re-wrapped to the column: `nowrap` keeps the
     deliberate three lines, and the longest ("TRAIN SMARTER.", 482px at
     1440) pokes ~50px past the column, over the gap and the top of the
     card's column, as it does in the mock. That is safe because the card,
     centred, always starts below the headline's first line; measured at
     1280x720/800, 1366x768, 1440x900, 1536x864, 1920x1080 and 1280x1024.
     Below 1280px the column is too narrow for that overflow to stay clear of
     a card that is also higher up, so the spanning layout stays there, the
     card sits at the bottom and there is no room under it for the cue. */
  /* NUDGED RIGHT WITH THE SCREEN (owner, same day): the founder follows the
     viewport (78%) while the cards sit in the 1340px measure, so on a wide
     screen the gap between the card and him grew far past the gap between
     the left column's text and the card. The card is offset right by a tenth
     of the width the viewport has beyond the measure (2026-09-16: a sixth,
     capped at 100px, was what pushed it into the founder's half): nothing at 1340 (the mock's proportions), ~42px on a
     1760px screen, ~58px at 1920, capped at 60px. Relative offset, not a
     column change, so the proof card
     keeps its width and the left column its wrapping; the cue moves with the
     card. Checked that the offset card clears the proof card at
     1440x900, 1536x864, 1600x900, 1680x1050 and 1920x1080. */
  @media (min-width:1280px){
    /* The head spans into the gap and is stopped by the headline's own width
       instead of by the column, so the LEDE gets the same measure as the card
       under it (owner 2026-09-17). At grid-column:1 the lede wrapped at ~404px
       while the nowrap headline above it overhung to 568, which read as two
       different left columns stacked. */
    .ggx .cx-head{ grid-column:1 / 3; max-width:var(--ggx-h1w); }
    /* The 3.9vw term is new here (review, 2026-09-15): on a viewport that is
       tall for its width (1280x1024, 1400x1050) the height-bound 5.7vh let the
       headline grow to 58px while column 1 stayed ~386px, and lines 2 and 3
       ran under the centred card. 3.9vw keeps the second line's bottom clear
       of the card's top at those sizes; at 1440x900, 1536x864 and 1920x1080
       it is not the binding term, so nothing changes there. Three classes,
       not two: the base `.ggx .cx-h1` rule comes later in this sheet and would
       otherwise win on source order (it did, for an hour). */
    .ggx .cx-head .cx-h1{ white-space:nowrap; font-size:var(--ggx-h1fs); }
    /* THE CARD IS PART OF THE LEFT COLUMN NOW (owner 2026-09-17, over a mock).
       It used to span both rows in the MIDDLE column, vertically centred and
       nudged right by --ggx-card-shift, which is what made it read as a third
       column floating between the copy and the portrait. It now sits in row 2 of
       column 1, bottom-anchored, directly under the lede: one conversion zone
       down the left, the portrait alone on the right, and --ggx-mid demoted from
       "the card's column" to the breathing room between the two.

       It spans 1/3 rather than column 1 because column 1 is --ggx-col3 wide
       (~402px) and the headline is wider than that by design; the max-width
       below is what actually stops it, on the headline's last character.
       --ggx-card-shift still sizes the headline cap, so it stays. */
    .ggx .cx-body .cx-offer-col{ grid-column:1 / 3; grid-row:2; align-self:end; left:0; top:0; }
    .ggx .cx-body .cx-offer-col .cx-offer{ max-width:var(--ggx-h1w); }}
  /* Hero headline runs INTER 900, not Orbitron (owner 2026-07-24). Orbitron is a
     sci-fi display face -- wide, quirky, slow to read, and it reads "gaming"
     rather than "premium coaching" on the page that has to convert a stranger.
     Same reasoning PR #485 applied to checkout. Inter is already self-hosted AND
     preloaded (base.html), and its woff2 is the VARIABLE Inter (wght 100-900), so
     the 900 weight costs no extra request on the LCP element. Because Inter is
     ~16% narrower than Orbitron at the same px, the size goes UP 68->80 while the
     rendered block stays the same width -- bigger type, zero layout shift. */
  /* Tracking is POSITIVE (.04em), not the usual negative display tracking: on
     uppercase display type, open letterspacing is what reads "epic/cinematic"
     (owner 2026-07-24). Ceiling is set by wrapping, not taste -- at a 1280px
     laptop the hero column is ~735px and the longest line ("TRAIN SMARTER.")
     measures 685px at .04em, 726px at .08em, and WRAPS at .10em, which would
     break the deliberate 3-line block. Don't raise this past ~.05em without
     re-measuring at 1280. */
  /* min(vw, vh) so the headline is bounded by the SHORTER axis. It used to scale
     on width alone, so a wide-but-short screen — 1920x950 after browser chrome,
     which is most desktops — rendered it at the full 80px and spent 252px of a
     screen that did not have it. Three lines at 1.05 makes every point of font
     size cost 3.15px of the one screen this section is supposed to fit in. */
  /* A little lower on desktop (owner 2026-08-25). Shortening "what's
     included" from ten rows to four freed vertical space in the left column,
     and the headline was left riding high against the nav. Height-relative so
     it gives the space back on short screens rather than pushing the hero
     past one viewport — the property the hero was tuned for. */
  /* 2vh, down from 3.4vh (2026-09-15): the footer row with the scroll cue
     took ~40px of the one screen the hero is tuned to fit in, and this is the
     softest place to find it. At 1440x900 the hero still fits the fold with a
     dozen px to spare; re-measure before adding anything else to the column. */
  .ggx-d .cx-head{ padding-top:clamp(0px,2vh,44px); }
  /* Sized and spaced to sit ABOVE the headline without pushing it down: the
     hero is height-constrained on a laptop, so this borrows its bottom margin
     from the headline's line-height rather than adding to the stack. */
  .ggx .cx-eyebrow{ font-family:'Orbitron'; font-size:11px; font-weight:800; letter-spacing:.22em;
    text-transform:uppercase; color:var(--muted); margin:0 0 clamp(6px,0.9vh,12px); }
  .ggx .mbo-eyebrow{ font-family:'Orbitron'; font-size:10px; font-weight:800; letter-spacing:.2em;
    text-transform:uppercase; color:var(--muted); margin:0 0 8px; }
  .ggx .cx-h1{ font-family:'Inter'; font-weight:900; font-size:clamp(44px,min(5.7vw,5.7vh),80px); line-height:1.05; letter-spacing:.04em; margin:0; color:#fff; text-transform:uppercase; }
  /* Supporting lede under the H1. Deliberately quiet: sentence case, normal
     weight, muted, and capped at ~62ch so it reads as one comfortable line-
     length paragraph rather than a second headline. max-width is in ch (not px)
     so the measure stays readable as the clamped H1 grows with the viewport. */
  .ggx .cx-lede{ font-family:'Inter'; font-weight:400; font-size:clamp(15px,1.15vw,17px); line-height:1.55; letter-spacing:0; margin:clamp(8px,1.1vh,14px) 0 0; max-width:var(--ggx-h1w); color:#c4cde0; text-transform:none; }
  /* The claim gets its own line but NOT its own weight: bolding it would put a
     third piece of loud type above a card that has to be the thing you look at. */
  .ggx .cx-lede-lead{ display:block; }

  /* DESKTOP HERO ONLY — the checklist at the size the owner's reference has it
     (2026-09-17). The rules above are shared with the phone hero
     (.ggx .mbo-body .cx-included) and the offer card, where 19px would be far
     too loud, so the scale-up is scoped to .cx-left rather than applied to the
     partial. It is affordable here because the column is top-anchored now: the
     band this list used to be pushed down past is exactly the room it grew
     into, and the hero still clears the fold at 1366x768, 1440x900, 1600x900
     and 1920x1080 (measured). The tick and the "+ much more inside" indent
     move with the type so the text column stays flush. */
  .ggx .cx-lrev{ margin-top:auto; max-width:440px; display:flex; flex-direction:column; gap:9px; padding:clamp(10px,1.6vh,15px) 17px; border:1px solid var(--line-2); border-radius:14px;
    background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.02)); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
  .ggx .cx-lrev .q{ font-size:13.5px; color:var(--cardtext); font-style:italic; line-height:1.5; }
  .ggx .cx-lrev .who{ display:flex; align-items:center; gap:10px; font-size:12.5px; color:var(--muted); } .ggx .cx-lrev .who b{ color:#fff; font-weight:700; }
  .ggx .cx-lrev .who .av{ width:30px; height:30px; border-radius:50%; flex:0 0 30px; display:grid; place-items:center; background:linear-gradient(135deg,#1c3450,#0f1f33); border:1px solid var(--cyan-bd); color:var(--cyan); overflow:hidden; }
  .ggx .cx-lrev .who .av svg{ width:17px; height:17px; }
  .ggx .cx-lrev-more{ align-self:flex-start; font-size:12px; font-weight:700; letter-spacing:.02em;
    color:var(--cyan); text-decoration:none; border-bottom:1px solid var(--cyan-bd); transition:opacity .2s ease; }
  .ggx .cx-lrev-more:hover{ opacity:.8; }

  /* offer card (shared component) */
  .ggx .cx-offer{ align-self:center; width:100%; border:1px solid var(--line-2); border-radius:16px; overflow:hidden;
    background:linear-gradient(180deg, rgba(15,23,40,.82), rgba(7,12,22,.9)); backdrop-filter:blur(8px); box-shadow:0 26px 60px rgba(0,0,0,.5); }
  .ggx .cx-offer-top{ padding:18px 20px 16px; text-align:center; position:relative; border-bottom:1px solid var(--line);
    background:radial-gradient(320px 140px at 50% -30%, var(--green-soft), transparent 65%); }

  /* --- billing toggle (monthly / 4-month) — ported from the hero design handoff --- */
  .ggx .cx-offer .fa-lab{ font-family:'Orbitron'; font-size:10px; font-weight:800; letter-spacing:.2em; text-transform:uppercase; color:var(--muted); margin-bottom:12px; }
  .ggx .cx-offer .seg{ display:grid; grid-template-columns:1fr 1fr; gap:5px; padding:5px; border-radius:13px; border:1px solid var(--line-2); background:rgba(0,0,0,.30); box-shadow:inset 0 1px 2px rgba(0,0,0,.4); }
  .ggx .cx-offer .seg-btn{ position:relative; display:flex; align-items:center; justify-content:center; gap:7px; cursor:pointer; border:1px solid transparent; background:transparent; font-family:'Orbitron'; font-weight:800; font-size:11px; letter-spacing:.05em; text-transform:uppercase; color:var(--muted); padding:11px 6px; border-radius:9px; transition:background .18s,color .18s,border-color .18s,box-shadow .18s; -webkit-tap-highlight-color:transparent; }
  .ggx .cx-offer .seg-btn:hover{ color:var(--cardtext); }
  .ggx .cx-offer .seg-btn.on{ background:linear-gradient(180deg, rgba(91,195,249,.22), rgba(91,195,249,.07)); color:#fff; border-color:var(--cyan-bd); box-shadow:0 4px 14px rgba(91,195,249,.16), inset 0 1px 0 rgba(255,255,255,.12); }
  .ggx .cx-offer .seg-btn .save{ font-family:'Inter'; font-size:9px; font-weight:800; letter-spacing:.03em; color:#062015; background:var(--green); padding:2px 6px; border-radius:50px; line-height:1.2; }
  @keyframes ggxSegHint{ 0%,92%,100%{ box-shadow:0 4px 14px rgba(91,195,249,.16), inset 0 1px 0 rgba(255,255,255,.12); } 96%{ box-shadow:0 0 0 3px rgba(91,195,249,.28), 0 4px 14px rgba(91,195,249,.16); } }
  .ggx .cx-offer .seg-btn.on.hint{ animation:ggxSegHint 3.2s ease-in-out 3; }
  @media (prefers-reduced-motion:reduce){ .ggx .cx-offer .seg-btn.on.hint{ animation:none; }}
  .ggx .cx-offer .price{ display:flex; align-items:baseline; justify-content:center; gap:3px; margin-top:16px; }
  .ggx .cx-offer .price .cur{ font-family:'Inter'; font-weight:800; font-size:26px; color:#fff; align-self:flex-start; margin-top:7px; }
  .ggx .cx-offer .price .amt{ font-family:'Inter'; font-weight:800; font-variant-numeric:tabular-nums; font-size:56px; color:#fff; line-height:.82; letter-spacing:-.02em; }
  .ggx .cx-offer .price .per{ font-size:17px; color:var(--lead); font-weight:600; margin-left:3px; }
  /* Reserve two rows: the 4-month plan's billed line (strike + charge + save
     pill + VAT note) wraps to 2 lines while the monthly plan is 1 line — a
     fixed min-height keeps the card the SAME height across the toggle so
     nothing below it shifts when you switch plans. */
  .ggx .cx-offer .cx-billed{ font-size:11.5px; color:var(--muted); margin-top:11px; font-variant-numeric:tabular-nums; display:flex; align-items:center; justify-content:center; gap:6px 8px; flex-wrap:wrap; min-height:48px; }
  .ggx .cx-offer .cx-billed .s{ text-decoration:line-through; color:var(--faint); }
  .ggx .cx-offer .cx-billed .savepill{ color:var(--green); background:var(--green-soft); border:1px solid rgba(52,211,153,.4); padding:2px 8px; border-radius:50px; font-weight:700; }
  /* The monthly's struck regular price on the toggle card (2026-09-29). */
  .ggx .cx-offer .cx-billed .cx-was{ font-size:15px; font-weight:700; color:#c3cddd;
    text-decoration:line-through; text-decoration-color:#ef4444; text-decoration-thickness:2px; }
  .ggx .cx-sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
  /* Trial card ($0 today): the figure is one glyph, so it can afford to be the
     hero of the card — and the billed line is a single line, so the 48px
     two-line reservation of the sell card becomes dead space. */
  .ggx .cx-offer-trial .price .amt{ font-size:84px; line-height:.8; }
  .ggx .cx-offer-trial .price .cur{ font-size:34px; margin-top:10px; }
  .ggx .cx-offer-trial .price .per{ font-size:20px; }
  /* "$0 today" glows green (owner 2026-08-05). The layered text-shadow is
     the glow: a tight bright halo for the lit-tube edge, then two wide
     soft ones for the bloom. `currentColor` is deliberately NOT used —
     the halo stays a fixed neon while the glyph can sit slightly
     brighter than it. */
  .ggx .cx-offer-trial .price{ color:#25E062; }
  .ggx .cx-offer-trial .price .cur,
  .ggx .cx-offer-trial .price .amt{
    color:#3BFF7A;
    text-shadow:0 0 8px rgba(37,224,98,.95), 0 0 26px rgba(37,224,98,.55),
                0 0 54px rgba(37,224,98,.35);
  }
  .ggx .cx-offer-trial .price .per{ color:#7BF5A6; text-shadow:0 0 14px rgba(37,224,98,.4); }
  @media (prefers-reduced-motion: reduce){
    .ggx .cx-offer-trial .price .amt{ text-shadow:0 0 10px rgba(37,224,98,.7); }}
  .ggx .cx-offer-trial .cx-billed{ min-height:0; }
  .ggx .cx-offer-body{ padding:16px 18px 18px; }
  .ggx .cx-fullaccess{ display:flex; align-items:flex-start; gap:9px; padding:11px 13px; border-radius:10px; border:1px solid rgba(52,211,153,.35); background:var(--green-soft); margin-bottom:13px; }
  .ggx .cx-fullaccess svg{ width:15px; height:15px; color:var(--green); flex:0 0 15px; margin-top:1px; }
  .ggx .cx-fullaccess .t{ font-size:12px; color:var(--cardtext); line-height:1.4; } .ggx .cx-fullaccess .t b{ color:#fff; } .ggx .cx-fullaccess .t .y{ color:var(--green); font-variant-numeric:tabular-nums; }
  .ggx .cx-offer-btn{ display:flex; align-items:center; justify-content:center; gap:8px; width:100%; border:0; cursor:pointer; text-decoration:none; font-family:'Orbitron'; font-weight:800; font-size:13.5px; letter-spacing:.04em; text-transform:uppercase; color:#fff;
    background:linear-gradient(180deg,#e21429,#b00f20); padding:15px; border-radius:13px; box-shadow:0 12px 26px rgba(226,20,41,.4), inset 0 1px 0 rgba(255,255,255,.16); }
  .ggx .cx-offer-foot{ text-align:center; font-size:10.5px; color:var(--muted); margin-top:11px; }
  /* --- closed-academy / waitlist card ------------------------------------
     The locked strip. STEEL, not amber and not red: amber read as "wait", red
     is the CTA colour sitting inches below and would fight it, and green is
     "go, this is available" which is the one thing it is not. Cool slate reads
     "closed" and stays premium rather than alarming. It sits ABOVE
     cx-offer-top so it lands before the price, because the price means
     something different once you know you cannot buy today.
     Static on purpose: a pulsing indicator implies something live, and a lock
     is the opposite of live. */
  /* RED, glowing, slow pulse (owner 2026-07-30). He wanted the closed state to
     be unmissable and the steel treatment was too quiet.
     Tuned deliberately: a DEEP red, not the CTA's #e21429, and a 3.4s breath
     rather than a fast blink. The CTA sits inches below and is already bright
     red and glowing, so anything brighter or faster here would give the card
     two competing red pulses and cheapen it into a discount-timer look.
     To revert to the calmer steel version, swap the three reds below for
     rgba(148,163,184,.15) / rgba(148,163,184,.24) / #aebcd0 and drop the
     animation. */
  /* GREEN since 2026-08-07, when the copy became "Applications open". Red +
     a closed padlock said "you cannot have this"; the words now say the
     opposite, and the badge has to agree with them. The pulse is kept but
     slowed and softened — it reads as a live status light rather than a
     countdown. Reverting is a matter of swapping the three greens back to
     rgba(226,20,41,...) and restoring the closed lock in _hero_offer.html. */
  .ggx .cx-offer-wait .cx-status{ display:flex; align-items:center; justify-content:center; gap:9px;
    padding:12px 14px; border-bottom:1px solid rgba(52,211,153,.34);
    background:linear-gradient(180deg, rgba(52,211,153,.18), rgba(52,211,153,.05));
    font-size:12px; letter-spacing:.15em; text-transform:uppercase;
    font-family:'Orbitron'; font-weight:800; color:#8fe9c4;
    animation:ggx-full-glow 3.4s ease-in-out infinite; }
  .ggx .cx-offer-wait .cx-status b{ color:#fff; font-weight:800; }
  .ggx .cx-offer-wait .cx-status-lock{ width:14px; height:14px; flex:0 0 14px; color:#34d399; }
  @keyframes ggx-full-glow{
    0%,100%{ box-shadow:inset 0 0 18px rgba(52,211,153,.14), 0 0 0 rgba(52,211,153,0); }
    50%    { box-shadow:inset 0 0 30px rgba(52,211,153,.28), 0 0 16px -2px rgba(52,211,153,.34); } }
  @media (prefers-reduced-motion:reduce){ .ggx .cx-offer-wait .cx-status{ animation:none; }}
  /* The AUTUMN SALE strip (owner 2026-09-29, over his mock): solid orange, dark bold
     type, a price tag. Declared after the green strip so it wins at every width. */
  .ggx .cx-offer-wait .cx-status.cx-status--sale{ background:linear-gradient(180deg, #fbb13c, #f59315);
    border-bottom:1px solid rgba(0,0,0,.18); color:#1b1206; font-family:'Archivo', 'Inter', sans-serif;
    font-weight:900; font-size:18px; letter-spacing:.02em; padding:12px 14px; animation:none;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.35); }
  @media (max-width:420px){ .ggx .cx-offer-wait .cx-status.cx-status--sale{ font-size:15px; padding:10px 12px; } }
  /* At 320 the 15px line broke before "25%" and left the tag between two lines. */
  @media (max-width:340px){ .ggx .cx-offer-wait .cx-status.cx-status--sale{ font-size:13.5px; letter-spacing:.01em; padding:10px 10px; } }
  .ggx .cx-offer-wait .cx-status--sale .cx-status-tag{ width:20px; height:20px; flex:0 0 20px; color:#1b1206; }
  .ggx .cx-offer-wait .cx-status--sale .cx-status-dot{ margin:0 .55em; }
  /* The locked PRICE panel. The strip alone was not landing the message, so
     the price itself is presented as something behind glass: frosted frame,
     lock badge, and a diagonal sheen so it reads as a pane rather than a
     disabled control.
     ⚠️ The figure stays crisp. backdrop-filter blurs what is BEHIND the panel,
     not its children, so $22.68 renders exactly as sharp as before. Do not add
     opacity or a filter to .price here: a dimmed price reads as "unavailable"
     or "hidden", and pricing on this page is meant to be fully transparent. */
  /* No fa-lab above it any more, so the panel sits flush at the top of
     cx-offer-top and the card reclaims that vertical space. */
  .ggx .cx-offer-wait .cx-offer-top{ padding-top:14px; }
  /* --- one-viewport fit (owner 2026-07-30) --------------------------------
     The card grew a status strip, a glass price panel, a reason box and three
     steps, and ran ~110px past the fold at 1600x900. Rather than cut content,
     every block gave back a little: the login link went (redundant with the
     top nav), and the paddings, gaps and the price size were tightened. Keep
     these tight if you add anything else to this card, or re-measure. */
  .ggx .cx-offer-wait .cx-status{ padding:9px 14px; }
  .ggx .cx-offer-wait .cx-offer-body{ padding:16px 18px 15px; }
  .ggx .cx-offer-wait .cx-why{ padding:10px 12px; margin-bottom:13px; font-size:12px; line-height:1.45; }

  /* --- APPLY is the card now (owner 2026-08-07) ---------------------------
     The price panel came out, so the CTA inherits the weight it was
     spending: a larger, taller button that is unambiguously the thing to do
     on this card. .cx-offer-btn's base rule is 13.5px and shared with the
     sell + trial variants, so this is scoped to .cx-offer-wait only. */
  .ggx .cx-offer-wait .cx-offer-btn{ font-size:17.5px; padding:18px 18px; letter-spacing:.05em;
    border-radius:13px; }

  /* HOVER (owner 2026-09-17). The card answers in GREEN, not red: green is the
     colour of its own "Applications open" strip, and red is the button sitting in
     the middle of it - glowing the frame in the CTA's colour would make the whole
     card read as one enormous button and cost the button the thing that makes it
     the obvious target.

     The card lifts, the button does NOT. Both moving would stack two transforms
     the moment the pointer crosses from one to the other, and the button is
     already inside a card that has lifted on the way in - it brightens and
     deepens its own shadow instead, which is legible without another 2px of
     travel.

     @media (hover:hover): the card is a plain container, and on a touch screen it
     would take :hover from the tap that fires the CTA and hold it there. */
  @media (hover:hover){
    .ggx .cx-offer-wait:hover{ transform:translateY(-2px); border-color:rgba(52,211,153,.42);
      box-shadow:0 32px 72px rgba(0,0,0,.58), 0 0 46px -14px rgba(52,211,153,.4); }
    .ggx .cx-offer-wait:hover .cx-offer-btn{ filter:brightness(1.05); }
    .ggx .cx-offer-wait .cx-offer-btn:hover{ filter:brightness(1.1);
      box-shadow:0 16px 34px rgba(226,20,41,.52), inset 0 1px 0 rgba(255,255,255,.22); }}
  .ggx .cx-offer-wait{ transition:transform .25s ease, border-color .25s ease, box-shadow .25s ease; }
  .ggx .cx-offer-wait .cx-offer-btn{ transition:filter .2s ease, box-shadow .2s ease; }
  @media (prefers-reduced-motion:reduce){
    .ggx .cx-offer-wait{ transition:border-color .25s ease, box-shadow .25s ease; }
    .ggx .cx-offer-wait:hover{ transform:none; }}

  /* THE PRICE, ABOVE THE BUTTON (owner 2026-09-17). It spent six weeks below the
     CTA under a hairline, deliberately quiet at 15px, and had turned into a
     footnote: the red button and the numbered steps took the eye first, and the
     rule read as a seam between the offer and its price rather than a join. No
     divider now, roughly twice the size, and directly between the value statement
     and the button — open, what you get, what it costs, apply, how.

     THE BUTTON MUST STAY THE STRONGEST THING ON THE CARD. The figure is white type
     on the card's own ground; the CTA is a filled red block at full width and
     17px. If this block ever grows again, grow the button first.

     A HAIRLINE EACH SIDE, WITH MATCHING AIR (owner 2026-09-17, "so that the card
     has better breathability"). The price is its own band between the value
     statement and the button rather than something crowded against either, and the
     padding inside the rules is deliberately the same top and bottom - an uneven
     pair reads as a mistake at this size. This is NOT the 2026-08-07 divider that
     was removed: that one was a single rule BELOW the CTA, and it made the price
     look like a footnote the card had finished with. */
  .ggx .cx-offer-wait .cx-pricebox{ margin:0 2px 14px; padding:14px 0; text-align:center;
    border-top:1px solid var(--line); border-bottom:1px solid var(--line); font-variant-numeric:tabular-nums; }
  .ggx .cx-offer-wait .cx-price-main{ margin:0; font-family:'Inter'; font-size:31px; font-weight:800; line-height:1.1; letter-spacing:-.03em; color:#fff; }
  /* Beside the amount, not under it: baseline-aligned by sitting inline in the
     same line box, so the cadence reads as part of the figure. */
  .ggx .cx-offer-wait .cx-price-cad{ margin-left:6px; font-size:14px; font-weight:600; letter-spacing:0; color:var(--lead); }
  .ggx .cx-offer-wait .cx-price-sub{ margin:5px 0 0; font-size:12.5px; line-height:1.5; color:var(--muted); }
  /* The page-global VAT note is bold grey; here it is one clause of a quiet
     line, so it takes the line's own weight and colour. */
  .ggx .cx-offer-wait .cx-price-sub .lof-vat-note{ font-weight:inherit; color:inherit; }
  /* THE STRUCK REGULAR PRICE AND ITS SAVING, above the price (owner 2026-09-29:
     "make the crossed $39.99 more visible so people see the discount"). Not the
     faint small anchor these usually are: two-thirds the size of the price, a
     light grey that still reads as the OLD figure, and a red strike thick enough
     to see from across the room. Then the saving as a solid green badge. The
     price below stays the biggest, whitest thing in the box. */
  .ggx .cx-offer-wait .cx-price-was{ margin:0; font-family:'Inter'; font-size:22px; font-weight:700; line-height:1.1;
    letter-spacing:-.02em; color:#c3cddd; }
  /* A DIAGONAL strike (owner 2026-09-29): a flat line-through sat on the middle
     of the digits and made "$39.99" hard to read. The slash runs corner to corner
     over the figure, so the number stays legible and still reads as crossed out. */
  .ggx .cx-offer-wait .cx-price-was s{ position:relative; display:inline-block; text-decoration:none; padding:0 2px; }
  .ggx .cx-offer-wait .cx-price-was s::after{ content:""; position:absolute; left:-4px; right:-4px; top:50%;
    height:1.5px; margin-top:-.75px; border-radius:1px; background:#ef4444; transform:rotate(-10deg);
    pointer-events:none; }
  .ggx .cx-offer-wait .cx-price-save{ margin:7px 0 7px; line-height:1; }
  .ggx .cx-offer-wait .cx-price-save span{ display:inline-block; padding:5px 9px; border-radius:6px; background:#22c55e; color:#03210e;
    font-size:12.5px; font-weight:800; letter-spacing:.01em; line-height:1.1; white-space:nowrap; }

  /* The second door under the CTA (owner 2026-09-13): a quiet text link, never
     a second button, so applying stays the one strong action on the card. */
  .ggx .cx-offer-alt{ display:block; width:fit-content; margin:12px auto 0; padding:2px 0;
    font-family:'Inter',system-ui,sans-serif; font-size:13px; font-weight:600; letter-spacing:.01em;
    color:var(--cardtext); text-decoration:none; border-bottom:1px solid rgba(255,255,255,.22); }
  .ggx .cx-offer-alt:hover{ color:#fff; border-bottom-color:rgba(255,255,255,.6); }
  .ggx .cx-offer-alt:focus-visible{ outline:2px solid var(--cyan); outline-offset:3px; border-radius:2px; }

  @media (max-width:520px){
    .ggx .cx-offer-wait .cx-offer-btn{ font-size:14.5px; padding:16px 14px; }
    .ggx .cx-offer-wait .cx-pricebox{ padding:12px 0; margin-bottom:12px; }
    .ggx .cx-offer-wait .cx-price-main{ font-size:26px; }
    .ggx .cx-offer-wait .cx-price-cad{ font-size:13px; }
    .ggx .cx-offer-wait .cx-price-sub{ font-size:11.5px; }
    /* On a phone the strip's tracking is what overflows first, not the
       words — it is 0.15em of letter-spacing on an uppercase Orbitron
       string that now reads "APPLICATIONS OPEN" rather than the shorter
       "ACADEMY IS FULL". */
    .ggx .cx-offer-wait .cx-status{ font-size:11px; letter-spacing:.1em; gap:7px; padding:9px 10px; }}
  .ggx .cx-offer-wait .cx-offer-btn{ padding:13px; }
  .ggx .cx-offer-wait .cx-sims{ margin-top:12px; padding-top:12px; }
  /* The offer, in a sentence. Styled as a statement (left-aligned, readable)
     rather than as fine print, because it is the last thing read before the CTA.
     Its <b> is the claim and the line under it is the proof, so the bold line gets
     its own row and full white; without display:block the two run together and
     the claim stops being a claim. */
  .ggx .cx-offer-wait .cx-why{ font-size:12.5px; line-height:1.5; color:var(--cardtext);
    padding:11px 13px; border-radius:10px; border:1px solid var(--line-2);
    background:rgba(0,0,0,.24); margin-bottom:13px; }
  .ggx .cx-offer-wait .cx-why b{ display:block; margin-bottom:3px; color:#fff; font-weight:700; }
  /* No toggle any more, so the billed line is a single row: drop the
     two-row min-height that existed only to stop the card resizing between
     monthly and 4-month. */
  .ggx .cx-offer-wait .cx-billed{ min-height:0; }

  /* ===== THE WIDE APPLY CARD (owner 2026-09-17, over a reference mock) =======
     TYPE SCALE, second pass the same day: the card moved from the ~380px middle
     column to the ~568px left one and kept the sizes it had when it was narrow, so
     everything in it read a size too small for the frame around it. The list, the
     price, the button and the line under it all came up ~15%. The short-desktop
     tier below is unaffected - it sets its own values, which is the point of it.

     The card left the middle column for the left one and got ~180px wider, so
     the value statement and the price sit side by side instead of stacked, and
     the steps under the CTA became one line. Everything else about the card -
     the green header strip, the red CTA, the sim logos - is unchanged. */
  .ggx .cx-offer-wait .cx-wl-row{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,auto);
    align-items:center; gap:12px; margin-bottom:15px; }
  /* No panel round the list (owner's mock, 2026-09-25): the ticks sit straight on the
     card, divided from the price by the price box's own left border. */
  .ggx .cx-offer-wait .cx-wl-row .cx-why{ margin-bottom:0; padding:0; border:0; background:none; }
  .ggx .cx-offer-wait .cx-wl-list{ list-style:none; margin:0; padding:0; display:grid; gap:10px; }
  .ggx .cx-offer-wait .cx-wl-list li{ display:flex; align-items:center; gap:10px;
    font-size:15.5px; line-height:1.2; font-weight:600; color:#fff; }
  .ggx .cx-offer-wait .cx-wl-list svg{ width:19px; height:19px; flex:0 0 19px; }
  /* The divider between the two halves is this border, not a separate element,
     so it can never fall out of step with the row's height. */
  .ggx .cx-offer-wait .cx-wl-row .cx-pricebox{ margin:0; padding:4px 2px 4px 16px; text-align:left;
    border:0; border-left:1px solid var(--line); }
  .ggx .cx-offer-wait .cx-wl-row .cx-price-main{ font-size:37px; }
  .ggx .cx-offer-wait .cx-wl-row .cx-price-cad{ font-size:16.5px; }
  .ggx .cx-offer-wait .cx-wl-row .cx-price-sub{ margin-top:6px; font-size:13.5px; white-space:nowrap; }
  .ggx .cx-offer-wait .cx-wl-row .cx-price-was{ font-size:24px; }
  /* "Also included: ..." (2026-09-25): one centred muted line between the row and
     the button, the library around the four ticks. */
  .ggx .cx-offer-wait .cx-wl-also{ margin:0 0 14px; text-align:center; font-size:14px; line-height:1.4; color:var(--cardtext); text-wrap:balance; }
  /* One quiet line where the 1/2/3 steps were, with a hairline running out to
     each edge. flex:1 on the pseudo-elements centres the text in whatever width
     the card ends up, with no width to keep in step by hand. */
  .ggx .cx-offer-wait .cx-wl-note{ display:flex; align-items:center; gap:14px; margin:16px 0 0;
    font-size:13.5px; line-height:1.4; color:var(--muted); }
  /* Applications parked (2026-09-26): the note ("Cancel anytime · 30-day money-back
     guarantee") is longer than the application one and wraps on a phone; centred,
     it wraps under the button instead of hugging the left edge. Its own class so
     the application card keeps exactly the alignment it had. */
  .ggx .cx-offer-wait .cx-wl-note--parked{ text-align:center; }
  .ggx .cx-offer-wait .cx-wl-note::before,
  .ggx .cx-offer-wait .cx-wl-note::after{ content:""; flex:1 1 0; height:1px; background:var(--line); }
  /* The CTA is the one thing in the hero that should look pressable, and at this
     width it is a very wide block: the glow is what keeps it from reading flat. */
  .ggx .cx-offer-wait .cx-offer-btn{ box-shadow:0 10px 26px -12px rgba(226,20,41,.75); }
  /* Under the divider line, and quieter than it was: on the narrow card the
     logos were the only thing in the bottom strip, here they follow a line of
     type and are compatibility proof, not a feature. */
  /* FOUR EQUAL SLOTS WITH A RULE BETWEEN THEM (owner 2026-09-17, over a mock).
     The base .cx-sims is a centred flex with a hand-tuned height per logo (15 / 19 /
     28 / 30) because the four files have very different aspect ratios. On the wide
     card that left them small and huddled in the middle with dead space either side.

     A grid of four equal columns fixes the spacing by construction, and
     `object-fit:contain` on a full-width box replaces the per-logo heights: each
     logo is fitted inside its slot, so the wide iRacing lockup is limited by the
     column and the tall AMS2 badge by the height, which is what those hand-tuned
     numbers were approximating. The per-logo rules further down still exist for the
     other two card variants; this beats them on specificity (0,3,1 vs 0,3,0).

     The divider is a border on the image itself, not a separate element, so it can
     never fall out of step with the columns. Its height is the image box plus the
     vertical padding, which is why that padding is generous. */
  .ggx .cx-offer-wait .cx-sims{ border-top:0; margin-top:14px; padding-top:0; opacity:.92;
    display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:0;
    align-items:center; justify-items:center; min-height:58px;
    /* THE DIVIDERS ARE PAINTED ON THE STRIP, not bordered onto the images. A border
       on an image sits against the logo, and the four logos are centred at four
       different widths, so the rules came out at four different distances from the
       cell edge. Three 1px background layers pinned to 25/50/75% put them exactly on
       the column boundaries, whatever the logos do. */
    --simline:rgba(148,175,214,.2);
    background-image:linear-gradient(var(--simline),var(--simline)),
      linear-gradient(var(--simline),var(--simline)),
      linear-gradient(var(--simline),var(--simline));
    background-size:1px 60%;
    background-position:25% 50%,50% 50%,75% 50%;
    background-repeat:no-repeat; }
  /* Optical sizes, not one size - see the note in _hero_offer.html. A uniform
     height here was the bug the owner saw: these four run from a square badge to a
     4.26-wide lockup. max-width keeps any of them clear of a divider if a file is
     ever recut wider. */
  .ggx .cx-offer-wait .cx-sims img{ width:auto; max-width:86%; }
  .ggx .cx-offer-wait .cx-sims .l-ir{ height:23px; }
  .ggx .cx-offer-wait .cx-sims .l-acc{ height:29px; }
  .ggx .cx-offer-wait .cx-sims .l-lmu{ height:25px; }
  .ggx .cx-offer-wait .cx-sims .l-ams{ height:33px; }

  /* NARROW: THE ROW STACKS (owner 2026-09-17). Two columns need a card wide
     enough for both; on a phone the card is ~330px and the split gave the value
     statement a 55px measure, one word per line. Stacked, the divider becomes a
     rule between them rather than beside them. 620px, not the 520px the rest of
     this card uses: the squeeze starts well before the phone breakpoint. */
  @media (max-width:620px){
    .ggx .cx-offer-wait .cx-wl-row{ grid-template-columns:minmax(0,1fr); gap:0; }
    .ggx .cx-offer-wait .cx-wl-row .cx-pricebox{ border-left:0; border-top:1px solid var(--line);
      margin-top:11px; padding:11px 0 0; text-align:center; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-sub{ white-space:normal; }
    /* THE BLOCK CENTRES, THE TEXT DOES NOT (owner asked, 2026-09-17). Stacked,
       the list is the only left-aligned thing in a card whose status strip,
       price, button, note and logos are all centred, so it reads as pushed to
       one side. `width:max-content` + auto margins centre it as one object while
       every tick and every word still starts at the same x.

       Centring the TEXT would be the wrong fix: four items of different lengths
       (78px to 130px) would rag on both edges and the ticks would stop forming a
       column, which is the thing that makes a checklist scannable at a glance. */
    .ggx .cx-offer-wait .cx-wl-list{ width:max-content; max-width:100%; margin-inline:auto; }}

  /* BY THE CARD'S WIDTH, NOT THE WINDOW'S (2026-09-25). The four benefits got longer
     ("Personalised drills + follow-up"), and between ~1000px and ~1200px the hero puts
     this card in a 332px column: the viewport rule above never fires there, and the
     list and the price ran into each other. The body is a size container, so the row
     reacts to the room it actually has: compact from 480px of content down to 400,
     stacked below that (400, not 430: the short-desktop tier's 421-437px cards must
     stay side by side). Measured, not guessed: the list needs 257px and the price
     box 217px at full size, 232 and 183 compact.

     BEFORE the short-desktop tier on purpose: that tier's smaller type must win where
     both apply (same specificity, so source order decides). */
  .ggx .cx-offer-wait .cx-offer-body{ container:cxbody / inline-size; }
  @container cxbody (min-width:400px) and (max-width:479.98px){
    .ggx .cx-offer-wait .cx-wl-list li{ font-size:14px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-main{ font-size:32px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-cad{ font-size:14px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-was{ font-size:22px; }}
  @container cxbody (max-width:399.98px){
    .ggx .cx-offer-wait .cx-wl-row{ grid-template-columns:minmax(0,1fr); gap:0; }
    .ggx .cx-offer-wait .cx-wl-row .cx-pricebox{ border-left:0; border-top:1px solid var(--line);
      margin-top:11px; padding:11px 0 0; text-align:center; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-sub{ white-space:normal; }
    .ggx .cx-offer-wait .cx-wl-list{ width:max-content; max-width:100%; margin-inline:auto; }}

  /* SHORT DESKTOP (2026-09-17), AND IT MUST STAY BELOW THE .cx-wl-* RULES ABOVE:
     every selector here is the same specificity as the one it overrides, so
     source order is the whole mechanism. Placed before them (as it was for one
     build) the gap and the price size simply did not change.

     The card moved out of the middle column, where
     it spanned both grid rows, into row 2 under the copy - so on a 768px-tall
     laptop the headline, the lede and the whole card have to stack inside one
     hero. They do, but at 1366x768 it left 10px between the lede and the card
     and 4px under it. This tier takes ~45px out of the card itself rather than
     shrinking the type above it, which is what the hero is actually selling. */
  @media (min-width:1280px) and (max-height:820px){
    .ggx .cx-offer-wait .cx-status{ padding:7px 14px; font-size:11px; }
    .ggx .cx-offer-wait .cx-offer-body{ padding:11px 14px 12px; }
    .ggx .cx-offer-wait .cx-why{ padding:8px 10px; font-size:11.5px; line-height:1.4; }
    .ggx .cx-offer-wait .cx-wl-list{ gap:7px; }
    .ggx .cx-offer-wait .cx-wl-list li{ font-size:12.5px; gap:8px; }
    .ggx .cx-offer-wait .cx-wl-list svg{ width:15px; height:15px; flex:0 0 15px; }
    .ggx .cx-offer-wait .cx-wl-row{ gap:12px; margin-bottom:11px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-pricebox{ padding-left:13px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-main{ font-size:27px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-cad{ font-size:13px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-sub{ margin-top:4px; font-size:11px; }
    /* The struck price and its badge share ONE line here: stacked they added
       ~30px to the row and pushed the card's foot under a 768px fold. */
    .ggx .cx-offer-wait .cx-wl-row .cx-price-was{ font-size:20px; }
    .ggx .cx-offer-wait .cx-price-was,
    .ggx .cx-offer-wait .cx-price-save{ display:inline-block; vertical-align:middle; }
    .ggx .cx-offer-wait .cx-price-save{ margin:0 0 0 7px; }
    .ggx .cx-offer-wait .cx-price-save span{ font-size:11px; padding:4px 7px; }
    .ggx .cx-offer-wait .cx-wl-row .cx-price-main{ margin-top:4px; }
    .ggx .cx-offer-wait .cx-offer-btn{ font-size:14px; padding:12px 14px; }
    .ggx .cx-offer-wait .cx-wl-note{ margin-top:10px; font-size:11.5px; gap:11px; }
    .ggx .cx-offer-wait .cx-wl-also{ margin-bottom:10px; font-size:11.5px; }
    .ggx .cx-offer-wait .cx-sims{ margin-top:9px; }
    .ggx .cx-offer-wait .cx-sims{ min-height:48px; }
    .ggx .cx-offer-wait .cx-sims .l-ir{ height:19px; }
    .ggx .cx-offer-wait .cx-sims .l-acc{ height:24px; }
    .ggx .cx-offer-wait .cx-sims .l-lmu{ height:21px; }
    .ggx .cx-offer-wait .cx-sims .l-ams{ height:27px; }}

  .ggx .cx-sims{ display:flex; align-items:center; justify-content:center; gap:16px; margin-top:14px; padding-top:14px; border-top:1px solid var(--line); }
  .ggx .cx-sims img{ width:auto; opacity:.96; }
  /* Retuned 2026-09-17 for the new logo files. The ratio across the four is
     1 : 1.26 : 1.09 : 1.43, set on the apply card and reused at every size on the
     site, so the marks carry the same weight wherever they appear. LMU moved most:
     it was a compact badge and is now a wordmark. */
  .ggx .cx-sims .l-ir{ height:15px; } .ggx .cx-sims .l-acc{ height:19px; } .ggx .cx-sims .l-lmu{ height:16px; } .ggx .cx-sims .l-ams{ height:21px; }
  .ggx .cx-login{ display:block; text-align:center; text-decoration:none; font-size:12px; color:var(--muted); padding:12px 0 14px; }
  /* THE BIGGER, TALLER CARD at >=1280px (owner, 2026-09-15: "make this center
     box a little bigger", then "a little taller"). Goes with the 380px column
     in the layout block above. Type steps up roughly a point across the board
     so it reads as one larger card rather than a wide one with small text;
     the ~50px of extra height is spent as air between the blocks and a deeper
     bottom rather than one empty strip. This block sits AFTER every base
     offer-card rule on purpose: same selectors, so source order decides. */
  @media (min-width:1280px){
    .ggx .cx-offer-wait .cx-status{ font-size:13px; padding:12px 16px; }
    .ggx .cx-offer-wait .cx-offer-body{ padding:22px 20px 22px; }
    .ggx .cx-offer-wait .cx-why{ font-size:13.5px; padding:12px 14px; margin-bottom:15px; }
    .ggx .cx-offer-wait .cx-offer-btn{ font-size:17.5px; padding:17px; }
    .ggx .cx-offer-alt{ font-size:14px; margin-top:14px; }
    .ggx .cx-offer-wait .cx-pricebox{ margin-bottom:16px; padding:16px 0; }
    .ggx .cx-offer-wait .cx-price-main{ font-size:32px; }
    .ggx .cx-offer-wait .cx-price-cad{ font-size:14.5px; }
    .ggx .cx-offer-wait .cx-price-sub{ font-size:13px; margin-top:6px; }
    .ggx .cx-offer-wait .cx-sims{ margin-top:16px; padding-top:14px; }
    .ggx .cx-sims{ gap:18px; }
    .ggx .cx-sims .l-ir{ height:17px; } .ggx .cx-sims .l-acc{ height:21px; } .ggx .cx-sims .l-lmu{ height:19px; } .ggx .cx-sims .l-ams{ height:24px; }}

  /* col 3 — the proof card. The founder photo used to live in this column;
     it is a layer of the hero itself now (.cx-founder, below). */
  /* The proof card follows the screen edge the way the founder does (owner,
     2026-09-15: "move the marian barbieru box more towards the right"): a
     third of the width the viewport has beyond the 1340px measure, so it sits
     under his face at every width (~130px on a 1730px screen, 193px at 1920),
     capped at 200px where his position is capped too. The tagline row below
     takes the same offset to stay on the card's right edge. Nothing at 1340
     and below, where the card already reaches the measure's edge.

     PLUS 65px, BOUNDED BY THE EDGE (owner, 2026-09-16, twice: "further
     right", then "a bit more like this" over a card sitting near the screen
     edge). Once the portrait grew 10% the card wanted real air between itself
     and the offer card in the middle.

     The wanted shift is a third of the spare width plus a flat 65px. What
     ships is that OR the room actually available, whichever is smaller:
     --ggx-right-room is the distance from the column's right edge to 24px
     short of the viewport, so the card can never be clipped or dumped against
     the glass on a narrow desktop. At 1280 the room term is what wins (14px,
     because there is no spare width there at all); from ~1400 up the asked-for
     shift wins. 240px is the ceiling, so an ultra-wide keeps it with the
     cards rather than letting it drift off with the edge. */
  .ggx{ --ggx-mid:332px;
    /* Column 3's width, derived from the same numbers the grid uses: the
       measure minus its padding, minus the middle column, minus the two 26px
       gaps. The tagline centres itself on this, so it tracks the card at every
       width instead of being nudged by hand. */
    --ggx-col3:calc((min(100vw, 1340px) - 2 * var(--ggx-pad) - var(--ggx-mid) - 52px) / 2);
    --ggx-pad:clamp(20px,3vw,52px);
    /* +20px flat on 2026-09-16 (owner, over a drawing): the card sits a
       touch right of the column and a touch below centre, so it reads as
       its own object rather than as the middle of a three-column rule.
       The headline cap below reads this value, so the two stay in step. */
    --ggx-card-shift:calc(min(calc((100vw - min(100vw, 1340px)) / 10), 60px) + 20px);
    --ggx-right-room:calc((100vw - min(100vw, 1340px)) / 2 + var(--ggx-pad) - 24px);
    /* THE HEADLINE'S SIZE, AS A VARIABLE (2026-09-17). It was written twice as a
       literal: once here in the desktop rule and once in the 1280-2000 cap below,
       and the comment on that cap records an afternoon lost to editing the wrong
       one. Now the cap overrides this value and .cx-h1 reads it, so there is a
       single place to change it and the card below can read it too.
       --ggx-h1w is that size times the width of the longest line, measured:
       "TRAIN SMARTER." sets 9.4em at .04em tracking. The application card takes
       this as its max-width, which is what lands its right edge on the headline's
       full stop at every viewport. IF THE HEADLINE COPY CHANGES, RE-MEASURE 9.4 -
       a longer first line would simply overhang the card. */
    --ggx-h1fs:clamp(53px, min(4.8vw, 7vh), 101px);
    --ggx-h1w:calc(9.4 * var(--ggx-h1fs));
    --ggx-right-shift:min(calc((100vw - min(100vw, 1340px)) / 3 + 65px), var(--ggx-right-room), 240px); }
  /* The wide-screen card width, and it MUST sit after the base value above:
     both selectors are plain `.ggx`, so source order decides and the same
     override placed in the layout block earlier in this sheet loses silently
     (it did, for one build — the card stayed 332px at every width). */
  @media (min-width:1280px){ .ggx{ --ggx-mid:380px; }}
  .ggx .cx-right{ grid-column:3; grid-row:1 / 3; position:relative; left:var(--ggx-right-shift); display:flex; flex-direction:column; justify-content:flex-end; }
  /* THE FOUNDER, FULL HEIGHT (owner's mock, 2026-09-15). A new cutout, race
     suit and crossed arms, 1122x1402, shown at ITS OWN proportions: the height
     is the hero's and the width follows; nothing is stretched or object-fit
     cropped. It is a layer of the hero rather than a child of column 3 because
     at full height the photo is wider than the column (650px at 1440x900),
     and an absolutely positioned child of the grid paints over the
     non-positioned offer card beside it; as a sibling under .cx-body
     (z-index:4) it sits behind every card. The box is centred at the grid's
     1340px measure so the photo keeps its place against the proof card on
     wide screens instead of following the viewport edge, and the negative
     `right` lets his far shoulder run a little past the frame, as in the
     mock (the hero clips it). The soft left mask is the only treatment: it
     stops his near arm cutting a hard edge across the offer card where the
     two touch on a squarer viewport. The old cyan halo behind the head went
     with the gradient backdrop; the photograph has its own light.

     ZOOMED PAST THE FRAME (owner, same day: "the picture needs to be zoomed
     in a lot more"). The first cut fitted the whole portrait to the hero's
     height, which reads as a photo placed beside the cards. In the mock the
     figure is scaled to ~1.25x the hero, pinned to the top so the hair sits
     at the frame edge, and cropped by the frame at the bottom (the forearms
     go, the proof card covers the chest) and at the far shoulder. The face is
     placed at 79% of the 1340px measure, which is the proof card's centre at
     every width. --founder-zoom is the one knob; the aspect ratio is still
     the file's own. The file is 1122px wide and that is the source's ceiling:
     at 1.25 a 2x screen already draws the face from ~1.5x upscaled pixels, so
     do not turn the knob up without a larger export.

     `max-width:none` is load-bearing. Tailwind's preflight puts
     `img{max-width:100%}` on every image; with the width following the height,
     that clamp squeezed the portrait sideways (21% at 1024x1366) whenever the
     hero was taller than the box was wide, the one distortion the owner ruled
     out. Portrait-aspect desktops (an iPad Pro held upright) drop the zoom to
     1 so the wider frame does not run under the headline column. */
  /* HORIZONTAL PLACE (owner, same day: "marian needs to be more on the
     right"). The face was at 79% of the 1340px content measure, which on a
     1600-1700px screen is only ~73% of the viewport: too near the offer card,
     too far from the wall text. It is now 78% of the VIEWPORT, the mock's
     proportion (the mock's viewport was narrower than the content measure, so
     there the two were the same thing), capped at 560px right of centre so on
     an ultra-wide screen the figure stays with the cards instead of drifting
     to the far edge. The far shoulder runs past the frame from ~1500px up. */
  /* +10% (owner, 2026-09-16), so the portrait holds its own now that the
     card beside it is 10% narrower: 1.25 -> 1.375, and the portrait-aspect
     case 1 -> 1.1. The knob is the zoom, never the width, because scaling
     the box is what squeezed the figure sideways before. */
  .ggx .cx-founder{ --founder-zoom:1.375; position:absolute; top:0; bottom:0; left:0; right:0; z-index:1; pointer-events:none; }
  .ggx .cx-founder picture, .ggx .mbo-fband picture{ display:contents; }
  /* HAIR TO THE NAV (owner, 2026-09-16). marian-suit.webp carries 25 rows of
     transparent space above the crown, 1.783% of its 1402px height, so at
     top:0 the figure always hung that far below the hero's top edge. The rise
     is that share, scaled by the zoom (the rendered height is the zoom times
     the hero's), so the crown lands ON the edge at every viewport instead of
     at one hand-measured pixel count. Re-measure --founder-crown if the file
     is ever re-exported with a different margin. */
  .ggx .cx-founder{ --founder-crown:1.783%; }
  .ggx .cx-founder img{ position:absolute; top:calc(-1 * var(--founder-crown) * var(--founder-zoom)); left:min(78%, calc(50% + 560px)); height:calc(100% * var(--founder-zoom)); width:auto; max-width:none; transform:translateX(-49%);
    -webkit-mask-image:linear-gradient(90deg, transparent, #000 22%); mask-image:linear-gradient(90deg, transparent, #000 22%); }
  @media (min-width:980px) and (max-aspect-ratio:1/1){ .ggx .cx-founder{ --founder-zoom:1.1; }}
  .ggx .cx-rcontent{ position:relative; z-index:2; display:flex; flex-direction:column; gap:10px;
    background:linear-gradient(155deg, rgba(20,30,50,.62), rgba(7,12,22,.82)); border:1px solid var(--line-3); border-radius:16px;
    padding:14px; backdrop-filter:blur(18px) saturate(1.15); -webkit-backdrop-filter:blur(18px) saturate(1.15);
    box-shadow:0 26px 64px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.08); }
  .ggx .cx-fname{ font-family:'Orbitron'; font-weight:800; font-size:20px; color:#fff; letter-spacing:.01em; } .ggx .cx-frole{ font-size:13px; color:var(--cyan); font-weight:600; margin-top:3px; }
  .ggx .cx-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:9px; }
  .ggx .cx-stat{ border:1px solid var(--line-2); border-radius:12px; background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02)); padding:10px 7px; text-align:center; }
  .ggx .cx-stat-top{ display:flex; align-items:center; justify-content:center; gap:5px; }
  .ggx .cx-stat-top svg{ width:13px; height:13px; color:var(--cyan); flex:0 0 13px; }
  .ggx .cx-stat .v{ font-family:'Inter'; font-weight:800; font-variant-numeric:tabular-nums; font-size:16px; color:#fff; line-height:1; } .ggx .cx-stat .l{ font-size:9px; color:var(--muted); margin-top:4px; line-height:1.2; }

  /* ---- scroll cue + tagline (owner's mock, 2026-09-15) ----
     The cue: a mouse outline with a wheel that drops and fades, "SCROLL TO
     EXPLORE" between two hairlines under it. It hangs directly under the
     offer card (owner: "move scroll to explore under the box"), absolutely
     positioned off the card's wrapper so the card's own centring is not
     shifted by it. Hidden by default and shown only in the >=1280px layout
     where the card is centred and has room beneath it. The wheel is the only
     motion, and it stops under prefers-reduced-motion.
     The tagline lives in .cx-foot, a short flex row under the grid at the
     hero's bottom edge, sized to the 1340px measure so it lines up with the
     proof card's right edge. A row rather than an overlay so it can never sit
     on the proof card, which ends at the grid's bottom. */
  /* As short as the 9px tagline allows (owner's red line sits just under the
     cards): with the cards bottom-anchored, this row plus the grid's bottom
     padding is the whole distance from the cards to the hero's end. */
  .ggx .cx-foot{ position:relative; left:var(--ggx-right-shift); z-index:4; flex:0 0 auto; width:100%; max-width:1340px; margin:0 auto; height:clamp(16px,2.2vh,22px); padding:0 clamp(20px,3vw,52px); }
  /* 1280-1365 wide: column 1 is 386-413px and "TRAIN SMARTER." at the 44px
     floor is 428px with its .04em tracking, so its full stop touched the
     centred card's top corner at 1280x800. No tracking there buys the ~24px
     it needs (the line ends ~440, the card starts 450). */
  @media (min-width:1280px) and (max-width:1365px){
    .ggx .cx-head .cx-h1{ letter-spacing:0; }
    /* And the card's measure loses the same tracking. 14 characters x .04em is
       most of the difference between 9.4em and 8.84em; without this the card
       overhangs the headline's full stop by 30px at 1280, which is the one
       width where the two visibly disagree. */
    .ggx{ --ggx-h1w:calc(8.84 * var(--ggx-h1fs)); }}
  /* Above 1340 wide the content grid stops growing but the vw term does not,
     so on a tall screen the headline outgrew its column and "EVERY WEEK." ran
     under the card (live 1720x1224; 2px at 1600x1150; touching at 1920x1200).
     This caps the size to the room the column really has: column 1 (the same
     width as --ggx-col3, since both side columns are 1fr), the 26px gap and
     the card's own rightward offset, over 8em ("DRIVE FASTER" is ~7.65em with
     its tracking). Stops at 2000 wide, where the card sits far below the
     headline and the cap would only shrink it.

     2026-09-16: this rule is LATER in the sheet than the base desktop size, so
     it is the one that decides at 1280-2000 — a size change made up there and
     not here does nothing at all on a normal desktop (that is exactly what
     happened when the headline was put up 15%). It now carries the same +15%,
     and its column arithmetic reads the live custom properties instead of a
     hand-copied 432px and an offset formula that had since changed. */
  @media (min-width:1280px) and (max-width:2000px){
    .ggx{ --ggx-h1fs:clamp(51px, min(4.5vw, 6.55vh, calc((var(--ggx-col3) + 26px + var(--ggx-card-shift)) / 8)), 92px); }}
  /* The bottom of the hero fades toward the page, over the photo layer and
     under the cards. Two jobs: it softens the frame edge that cuts the crossed
     arms (a photograph ending in a hard line against a flat dark section reads
     as a banner), and it is what makes the tagline legible, which sits over the
     white suit on a squarer viewport where the photo runs wider than the mock. */
  .ggx-d.cx-hero::after{ content:""; position:absolute; left:0; right:0; bottom:0; z-index:2; pointer-events:none;
    height:clamp(90px,13vh,130px); background:linear-gradient(180deg, rgba(3,7,15,0), rgba(3,7,15,.88)); }
  /* CENTRED ON THE CARD (owner, 2026-09-16), not flush with its right edge:
     half of column 3 in from the measure's padding, then pulled back by half
     its own width. The row already carries --ggx-right-shift, so it stays with
     the card as the card moves. */
  .ggx .cx-tag{ position:absolute; right:calc(var(--ggx-pad) + var(--ggx-col3) / 2); top:50%; transform:translate(50%,-50%); font-family:'Orbitron'; font-size:9px; font-weight:700; letter-spacing:.24em; text-transform:uppercase; color:var(--faint); white-space:nowrap; }
  /* Below 871px of viewport the hero with this row no longer fits the fold
     (measured: the break-even is 867-871px at every width from 1440 up), so
     the row goes and gives its height back rather than sitting below the fold.
     A 1440x900 laptop with browser chrome (~800px) and a 1536x864 screen both
     land here; a full-screen 900 or 1080 shows it. */
  @media (max-height:870px){ .ggx .cx-foot{ display:none; }}

  /* ---- MOBILE: .mbo-hero stack ---- */
  .ggx .mbo-hero{ width:100%; }
  .ggx .mbo-body{ position:relative; z-index:4; padding:22px 20px 26px; display:flex; flex-direction:column; }
  /* 32px, not 34: the open .04em tracking (see .cx-h1) costs width, and at 34px
     the longest line measured 319px inside a 320px box on a 360px-wide Android
     -- 1px of headroom, i.e. one rasterization difference away from wrapping and
     breaking the 3-line block. 32px restores ~19px of margin. */
  .ggx .mbo-h1{ font-family:'Inter'; font-weight:900; font-size:32px; line-height:1.08; letter-spacing:.04em; color:#fff; margin:14px 0 0; text-transform:uppercase; }
  .ggx .mbo-lede{ font-family:'Inter'; font-weight:400; font-size:15px; line-height:1.55; letter-spacing:0; color:#c4cde0; margin:12px 0 0; text-transform:none; }
  .ggx .mbo-fband{ position:relative; margin-top:18px; height:296px; border-radius:16px; overflow:hidden; border:1px solid var(--line-2);
    background: radial-gradient(300px 230px at 50% 20%, var(--cyan-glow), transparent 66%), linear-gradient(180deg,#0c1628,#060c16); }
  /* 100%, not the old 108%: the new cutout starts at the top of his hair, so
     an overshoot only cut the hair off. The band's own bottom fade covers the
     crossed arms where the name badge sits. */
  .ggx .mbo-fband img{ position:absolute; left:50%; transform:translateX(-50%); bottom:0; height:100%; width:auto; }
  .ggx .mbo-fband::after{ content:""; position:absolute; inset:0; background:linear-gradient(180deg, transparent 46%, rgba(7,11,20,.55) 72%, rgba(7,11,20,.96) 100%); }
  .ggx .mbo-fband .id{ position:absolute; left:16px; bottom:14px; z-index:2; }
  .ggx .mbo-fband .badge{ display:inline-flex; align-items:center; gap:6px; background:rgba(8,12,22,.78); border:1px solid var(--line-2); backdrop-filter:blur(6px); padding:4px 10px; border-radius:50px; font-size:11px; font-weight:600; color:#fff; }
  .ggx .mbo-fband .badge .pip{ width:6px; height:6px; border-radius:50%; background:var(--cyan); box-shadow:0 0 6px var(--cyan); }
  .ggx .mbo-fband .nm{ font-family:'Orbitron'; font-weight:800; font-size:21px; color:#fff; margin-top:9px; letter-spacing:.01em; }
  .ggx .mbo-fband .rl{ font-size:13px; color:var(--cyan); font-weight:600; margin-top:3px; }
  .ggx .mbo-stats{ margin-top:12px; }
  .ggx .mbo-body .cx-offer{ margin-top:22px; align-self:stretch; width:100%; }
  .ggx .mbo-body .cx-lrev{ margin-top:22px; max-width:none; }

  /* ---- responsive toggle ---- */
  .ggx-d{ display:none; } .ggx-m{ display:block; }
  @media (min-width:980px){ .ggx-d{ display:block; } .ggx-m{ display:none; }
    /* The desktop hero is a full-height flex column ONLY at desktop. Scoped here
       (not on the base `.ggx .cx-hero`) because `.ggx .cx-hero{display:flex}`
       out-specifies the mobile hide `.ggx-d{display:none}` and would leak the
       3-col desktop hero onto phones (it did — regression fix). */
    .ggx-d.cx-hero{ display:flex; flex-direction:column; }}

/* === block 3 -- was the .mre-book <style> in content block (template lines 3101-3108) === */
      .mre-book{display:none}
      @media (max-width:720px){
        /* position:relative is load-bearing: .lof is isolation:isolate with a fixed
           full-viewport backdrop (::before), so its stacking context paints over any
           NON-positioned content after it. Every other band is positioned; without
           this the book slide rendered as an empty dark gap (2026-09-26). */
        .mre-book{position:relative;display:flex;flex-direction:column;align-items:center;gap:20px;padding:48px 6vw 44px;text-align:center}
        .mre-book h2{font-family:'Orbitron',sans-serif;font-weight:800;font-size:24px;letter-spacing:.05em;text-transform:uppercase;color:#fff}
        .mre-book img{width:min(62vw,260px);border-radius:10px;box-shadow:0 30px 70px rgba(0,0,0,.6),0 0 44px rgba(91,195,249,.12)}}

/* === block 4 -- was the .mre-close <style> in content block (template lines 3122-3150) === */
      .mre-close{display:none}
      /* Tighten the page end at every width (owner, 2026-07-17): the closer
         (Lights Out on desktop, the .mre-close card on phones) flows straight
         into legal links -> (c) line with no dead band. */
      .lof-page .lof{padding-bottom:0}
      .lof-page .alp{margin-top:0}
      .lof-page .alp .alp-legal{margin-top:1.3rem;padding-bottom:1.6rem}
      /* the base-layout (c) footer duplicated a near-invisible 69px band under
         the legal links — the landing ends at Terms/Privacy (owner) */
      body.lof-page footer{display:none}
      @media (max-width:720px){
        .mre-close{display:block}
        /* #driver-results (the reviews podium) is NO LONGER phone-hidden
           (owner 2026-07-24) — phones were getting zero social proof between the
           lap-review section and the closing offer. Its own <=980/<=640 rules
           stack it to a single column. Book + FAQ stay phone-hidden. */
        /* #faq was hidden here too. It cannot be: the page emits a
           ten-question FAQPage, and Google's structured-data policy
           requires marked-up content to be visible to the user -- on
           mobile-first indexing, this rendering IS the page. The book
           section carries no markup and stays hidden. */
        #sec-book{display:none}
        .mre-tabreview{display:none}
        /* No bottom bar between 641 and 720px, so the page end stays tight there. */
        body.lof-page main{padding-bottom:calc(1.1rem + env(safe-area-inset-bottom)) !important}}
      /* Phones (<=640px, where the fixed bottom bar is) keep the 5.5rem clearance
         at the page end. The bar does NOT hide there: it only fades over the zones
         the script at the end of academy_landing.html watches, and the FAQ now sits
         between the .mre-close card and the legal links, so without the clearance
         the bar covered Terms, Privacy and "Cookie settings", and a tap on them
         opened the checkout (2026-09-28). */
      @media (max-width:640px){
        body.lof-page main{padding-bottom:calc(5.5rem + env(safe-area-inset-bottom)) !important}}

/* ============================================================================
   partials/weekly_loop.html -- the weekly coaching loop.
   LAYOUT from the owner's mock of 2026-09-26: centred header, three text + card
   rows split by hairlines, one closing line and the join button.
   LOOK AND MOTION from the 2026-09-17 section it replaced, on the owner's word the
   same day: the mock's layout exactly, with only the old COLOURS and BACKGROUND
   ("keep only the colors and the background"; he rejected the mock's flat grey
   ground, then the dot, spine, turning glyphs and call-out that were tried on
   top): the night-track photograph over the navy ground and its grain, Inter 900
   headlines with an accent second line, the per-step accents (01 cyan, 02 violet,
   03 teal - two inline custom properties on the rows), lit glass panels with
   corner ticks, Marian's photo and the red join button.
   ============================================================================ */
.wkl{
/* --disp: Archivo (self-hosted for the Driver Performance Lab page, so licensed);
   headlines are Inter 900, the face every section headline on this page uses. */
--disp:'Archivo',system-ui,sans-serif;--body:'Inter',system-ui,sans-serif;
/* --faint was #7b8aa2 until 2026-09-26. The kicker, the "Reviewed within 48 hours"
   line and the line under the button are small text in this colour sitting straight on
   the photograph, and the fixed photo slides a bright band behind them as you scroll.
   Against that band #7b8aa2 measured 3.7-4.1:1 and failed AA's 4.5:1. The podium's
   #8a99b0 still left the kicker at 4.48:1 at 1024px. #8f9eb5 is the lightest step that
   clears every width, with the worst case at 4.76:1. Do not darken it again without
   re-measuring against the brightest background pixel. */
--ink:#fff;--lead:#d4ddec;--card:#dfe6f2;--muted:#a7b6cd;--faint:#8f9eb5;
--cyan:#5BC3F9;--cy:91,195,249;--red:#E21429;--red-2:#b00f20;--green:#34d399;--gr:52,211,153;
--line:rgba(148,175,214,.16);--line-2:rgba(148,175,214,.28);--line-3:rgba(148,175,214,.4);
--pad:clamp(16px,3vw,40px);
position:relative;isolation:isolate;width:100%;color:var(--ink);font-family:var(--body);-webkit-font-smoothing:antialiased;
/* THE GROUND, as it was: a navy colour field under the photograph (below). */
background:linear-gradient(180deg,#080b14 0,#0c0a1c 22%,#100c22 44%,#0a1a1e 72%,#06131f 88%,#070e1a 100%);
/* nothing else on this page sets a scroll margin, so an in-page jump to #loop
   would land under the sticky nav; --ggx-navh is scoped to .ggx, hence the fallback */
scroll-margin-top:calc(var(--ggx-navh,70px) + 12px)}
/* GRAIN: breaks the gradient's banding on 8-bit displays. Inline SVG, no request. */
.wkl::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:160px 160px}
/* NIGHT TRACK, FULL-BLEED (owner 2026-09-17): /about/'s Daytona photograph with
   /about/'s grade baked into the file (bg-loop-daytona.webp; re-derive it from
   static/images/about/iracing-daytona.webp if that page's look changes, never
   hand-edit it). `fixed` sizes `cover` against the viewport, so the file renders
   near 1:1 instead of a blurred 3-4x upscale over a tall section; iOS treats
   fixed as scroll, which is only the stretched fallback. The scrim is the dial:
   the copy sits straight on this ground, so darker = more legible. */
.wkl::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(ellipse 70% 30% at 50% 0,rgba(var(--cy),.06),transparent 70%),
    linear-gradient(180deg,rgba(8,11,20,.42) 0%,rgba(8,11,20,.5) 50%,rgba(8,11,20,.6) 100%),
    url("../../images/weekly-loop/bg-loop-daytona.01d236d5317d.webp") 50% 45% / cover no-repeat;
  background-attachment:scroll,scroll,fixed}
.wkl *{margin:0;padding:0;box-sizing:border-box}
.wkl img,.wkl svg{display:block;max-width:100%}
.wkl-in{position:relative;z-index:1;max-width:1180px;margin:0 auto;padding:clamp(56px,7vw,96px) var(--pad) clamp(56px,6vw,88px)}

/* ---- header ---- */
.wkl-head{text-align:center;margin-bottom:clamp(20px,2.6vw,36px)}
.wkl-hk{font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:.2em;color:var(--faint);text-transform:uppercase}
.wkl-head h2{margin-top:clamp(12px,1.3vw,18px);font-family:var(--body);font-weight:900;font-size:clamp(30px,4.5vw,74px);line-height:1;letter-spacing:.025em;text-wrap:balance}
.wkl-head h2 em{font-style:normal;color:var(--cyan);display:block}

/* ---- the three rows: text ~40%, card ~57% ---- */
.wkl-steps{position:relative}
.wkl-list{list-style:none}
.wkl-row{display:grid;grid-template-columns:minmax(0,40fr) minmax(0,57fr);gap:clamp(24px,3vw,44px);align-items:center;padding:clamp(28px,3.2vw,44px) 0}
.wkl-row+.wkl-row{border-top:1px solid var(--line)}
.wkl-k{font-family:var(--disp);font-weight:600;font-size:clamp(12.5px,1vw,14px);letter-spacing:.15em;color:var(--muted);text-transform:uppercase}
.wkl-k b{font-weight:800;letter-spacing:.06em;color:var(--cyan)}
/* The markup has real spaces around this aria-hidden dot, so a screen reader hears
   "01 Get feedback" and not "01Get feedback". Those spaces take up most of the old
   .6em gap, so the margin is only what is left over. */
.wkl-sep{margin:0 .25em;color:var(--faint)}
/* Capped at 39px, not 42. At 42px, "Get personal feedback." is wider than the ~436px
   text column that .wkl-in's 1180px cap leaves, so from about 1410px up step 01 broke
   onto a third line with "feedback." on its own. The mock sets it as one line. */
.wkl-copy h3{margin-top:clamp(12px,1.3vw,18px);font-family:var(--body);font-weight:900;font-size:clamp(26px,2.85vw,39px);line-height:1.06;letter-spacing:-.04em;text-wrap:balance}
.wkl-copy h3 em{font-style:normal;color:var(--cyan)}
.wkl-say{margin-top:clamp(12px,1.3vw,18px);font-size:clamp(15.5px,1.2vw,18.5px);line-height:1.62;color:var(--lead);max-width:36ch;text-wrap:pretty}
.wkl-meta{margin-top:clamp(12px,1.3vw,18px);font-size:clamp(13px,1vw,14.5px);line-height:1.5;color:var(--faint)}

/* ---- cards: the old lit glass panels, each in its step's accent ---- */
.wkl-card{position:relative;background:linear-gradient(180deg,rgba(13,24,43,.7),rgba(6,11,20,.82));border:1px solid rgba(var(--cy),.52);border-radius:14px;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  box-shadow:0 0 0 1px rgba(var(--cy),.12),0 34px 80px rgba(0,0,0,.56)}
/* corner ticks, top-left and bottom-right, as on the old "hot" panels */
.wkl-card::before,.wkl-card::after{content:"";position:absolute;z-index:4;width:15px;height:15px;border:1.5px solid var(--cyan);opacity:.85;pointer-events:none}
.wkl-card::before{top:-1px;left:-1px;border-right:0;border-bottom:0;border-radius:14px 0 0 0}
.wkl-card::after{bottom:-1px;right:-1px;border-left:0;border-top:0;border-radius:0 0 14px 0}
.wkl-ct{padding:15px 20px 12px;font-family:var(--body);font-weight:800;font-size:clamp(16px,1.35vw,20px);line-height:1.25;letter-spacing:-.025em;color:var(--ink)}
.wkl-pill{flex:none;display:inline-flex;align-items:center;font-family:var(--body);font-weight:500;font-size:13px;line-height:1;color:var(--lead);border:1px solid var(--line-2);border-radius:999px;padding:7px 14px;background:rgba(10,19,34,.55)}

/* the players: a local poster and a round play button until pressed, then the
   iframe static/js/lap_review_pair.js appends on top */
.wkl-po{position:relative;margin:0 8px;aspect-ratio:16/9;border-radius:10px;overflow:hidden;background:#0a1120}
.wkl-po--inset{margin:0 18px}
.wkl-po img{width:100%;height:100%;object-fit:cover}
/* the drill's source frame carries the sim's own UI in its corners; the same crop
   the old player used keeps the windscreen and loses the overlays */
.wkl-po--inset img{object-position:50% 22%;transform:scale(1.34);transform-origin:50% 46%}
.wkl-po>button{position:absolute;inset:0;display:grid;place-items:center;border:0;background:none;cursor:pointer}
.wkl-po>button[hidden]{display:none}
.wkl-po>button i{display:grid;place-items:center;width:clamp(58px,5.4vw,76px);height:clamp(58px,5.4vw,76px);border-radius:50%;background:rgba(var(--cy),.92);border:1.5px solid #fff;box-shadow:0 0 40px rgba(var(--cy),.5);transition:transform .22s ease}
.wkl-po>button i::after{content:"";width:0;height:0;margin-left:5px;border-left:19px solid #04070d;border-top:12px solid transparent;border-bottom:12px solid transparent}
.wkl-po>button:hover i{transform:scale(1.07)}
.wkl-po>button:focus-visible{outline:none}
.wkl-po>button:focus-visible i{outline:2px solid #fff;outline-offset:3px}
.wkl-po:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.wkl-po iframe{position:absolute;inset:0;z-index:3;width:100%;height:100%;border:0;border-radius:inherit}

/* step 01: the card's footer bar (the glyphs on the right are decoration) */
.wkl-vbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 20px 14px;font-size:14.5px;color:var(--lead)}
.wkl-vlabel,.wkl-vctl{display:flex;align-items:center;gap:10px}
.wkl-vctl{gap:20px;color:var(--faint)}
.wkl-vbar svg{width:20px;height:20px;flex:none}
.wkl-vlabel svg{color:var(--cyan)}

/* step 02: the drill under its poster */
.wkl-drill{padding:14px 20px 18px}
.wkl-dt{display:flex;align-items:center;justify-content:space-between;gap:12px}
.wkl-dt b{font-family:var(--body);font-weight:800;font-size:clamp(17px,1.4vw,20px);line-height:1.25;letter-spacing:-.02em}
.wkl-df{margin-top:5px;font-size:15px;line-height:1.45;color:var(--muted)}

/* step 03: the coach's feedback, a green "Improved" note and an accent "Next focus" note */
.wkl-fbhd{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px 12px 20px;border-bottom:1px solid var(--line)}
.wkl-fbhd .wkl-ct{padding:0}
.wkl-fbbd{display:flex;flex-direction:column;gap:12px;padding:14px 20px 20px}
.wkl-coach{display:flex;align-items:center;gap:13px;font-size:15.5px;color:var(--muted)}
.wkl-coach img{flex:none;width:48px;height:48px;border-radius:50%;object-fit:cover;object-position:50% 12%;background:#0e1a2e;border:1px solid var(--line-3)}
.wkl-coach b{color:var(--cyan);font-weight:600}
.wkl-coach em{font-style:normal;color:var(--muted)}
.wkl-note{display:grid;grid-template-columns:auto minmax(0,1fr);gap:14px;align-items:center;padding:14px 16px;border:1px solid rgba(var(--cy),.3);border-left:3px solid var(--cyan);background:linear-gradient(90deg,rgba(var(--cy),.1),rgba(var(--cy),.03));border-radius:0 11px 11px 0}
.wkl-note--ok{border-color:rgba(var(--gr),.3);border-left-color:var(--green);background:linear-gradient(90deg,rgba(var(--gr),.1),rgba(var(--gr),.03))}
.wkl-ic{display:grid;place-items:center;width:38px;height:38px;border-radius:50%}
.wkl-ic svg{width:19px;height:19px}
.wkl-note--ok .wkl-ic{background:rgba(var(--gr),.16);color:var(--green)}
.wkl-note--next .wkl-ic{background:rgba(var(--cy),.16);color:var(--cyan)}
.wkl-nt{font-size:16px;line-height:1.35;color:var(--ink)}
.wkl-nt b{font-weight:700}
.wkl-note--ok .wkl-nt b{color:var(--green)}
.wkl-note--next .wkl-nt b{color:var(--cyan)}
.wkl-nd{margin-top:4px;font-size:14.5px;line-height:1.5;color:var(--card);opacity:.82;text-wrap:pretty}

/* ---- close: the line and the old red join button ---- */
.wkl-close{display:flex;flex-direction:column;align-items:center;margin-top:clamp(28px,3.4vw,48px);padding-top:clamp(28px,3.4vw,44px);border-top:1px solid var(--line);text-align:center}
.wkl-rep{font-family:var(--body);font-weight:800;font-size:clamp(19px,1.9vw,28px);line-height:1.2;letter-spacing:-.025em;color:var(--lead);text-wrap:balance}
.wkl-rep em{font-style:normal;color:var(--cyan)}
.wkl-cta{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:54px;margin-top:clamp(18px,1.8vw,24px);padding:0 30px;border-radius:9px;background:linear-gradient(180deg,var(--red),var(--red-2));color:#fff;font-family:var(--disp);font-weight:700;font-size:15px;letter-spacing:.1em;text-transform:uppercase;text-decoration:none;box-shadow:0 12px 38px rgba(226,20,41,.36);transition:transform .18s,box-shadow .18s;white-space:nowrap}
.wkl-cta:hover{color:#fff;transform:translateY(-2px);box-shadow:0 16px 46px rgba(226,20,41,.48)}
.wkl-cta:focus-visible{outline:2px solid #fff;outline-offset:3px}
.wkl-ctasub{display:block;margin-top:12px;font-size:13px;color:var(--faint)}

/* ---- HOVER LIFT (2026-09-17): a panel rises 2px, its border comes up to its
   step's accent and a bloom of that accent opens under it; the corner ticks come
   up to full. @media (hover:hover) so a tap on a phone can't leave a panel stuck
   lifted. */
.wkl-card{transition:transform .25s ease,border-color .25s ease,box-shadow .25s ease}
.wkl-card::before,.wkl-card::after{transition:opacity .25s ease}
@media (hover:hover){
  .wkl-card:hover{transform:translateY(-2px);border-color:rgba(var(--cy),.8);
    box-shadow:0 0 0 1px rgba(var(--cy),.26),0 30px 74px rgba(0,0,0,.6),0 0 60px -10px rgba(var(--cy),.4)}
  .wkl-card:hover::before,.wkl-card:hover::after{opacity:1}}

/* ---- phones: each row stacks, text over its card ---- */
@media (max-width:760px){
.wkl-row{grid-template-columns:minmax(0,1fr);gap:20px;align-items:start}
.wkl-head h2{font-size:clamp(30px,9vw,40px)}
.wkl-copy h3{font-size:clamp(24px,7vw,30px)}
.wkl-say{max-width:none;font-size:16px}
.wkl-ct{padding:13px 16px 10px}
.wkl-vbar{padding:11px 16px 13px;font-size:14px}
.wkl-po{margin:0 6px}
.wkl-po--inset{margin:0 12px}
.wkl-drill{padding:12px 16px 16px}
.wkl-fbhd{padding:10px 12px 10px 16px}
.wkl-fbbd{padding:14px 12px 14px}
.wkl-coach img{width:42px;height:42px}
.wkl-note{gap:12px;padding:12px 13px}
.wkl-ic{width:34px;height:34px}
.wkl-ic svg{width:17px;height:17px}
.wkl-nt{font-size:15.5px}
/* The closing line wraps at this width. Left to wrap on its own, it put the cyan
   "Keep" at the end of the white line. As a block, the accent phrase gets a line of
   its own, the same accent-second-line pattern the headlines use. */
.wkl-rep em{display:block}
/* the join button carries the price while applications are parked
   (partials/_join_label.html) and no longer fits one line on a phone */
.wkl-cta:has(.join-lbl){white-space:normal;height:auto;min-height:54px;padding:12px 22px;line-height:1.35}}

@media (prefers-reduced-motion:reduce){
.wkl-card{transition:border-color .25s ease,box-shadow .25s ease}
.wkl-card:hover,.wkl-cta:hover,.wkl-po>button:hover i{transform:none}
.wkl-cta,.wkl-po>button i{transition:none}}

/* ============================================================================
   partials/trusted_approach.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
  .tbx{position:relative;overflow:hidden;isolation:isolate;background:#060a12}
  /* Everything visible sits in .tbx-reveal, which is what the entrance clips.
     The section itself is never clipped: Chrome's IntersectionObserver measures
     a target through its own clip-path, so a section clipped to nothing is never
     "intersecting" and the reveal that would unclip it never fires (that shipped
     for a few minutes as a blank band). */
  .tbx-reveal{position:relative;padding:clamp(34px,4.4vw,56px) 0 clamp(40px,5vw,64px)}
  /* The photograph is its own layer so the entrance can scale it. A light blur
     (owner 2026-09-26, "a little bit") so the headline reads over it; the layer
     overhangs the section by 12px on every side, which .tbx's overflow:hidden
     clips, so the blur's soft edge never shows as a dark rim at the sides. */
  .tbx-bg{position:absolute;inset:-12px;z-index:0;pointer-events:none;filter:blur(3px);
    background:url("../../images/hero/trusted-track.8cbd214fd3d8.webp") center / cover no-repeat;transform-origin:50% 60%}
  /* Fades into the page at top and bottom, a soft dark pool behind the centred
     copy (2026-09-25), and the light left-to-right veil. */
  .tbx-reveal::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(180deg,#060a12 0,rgba(6,10,18,0) 14%,rgba(6,10,18,0) 84%,#060a12 100%),
               radial-gradient(58% 52% at 50% 62%,rgba(6,10,18,.55),rgba(6,10,18,0) 72%),
               linear-gradient(90deg,rgba(6,10,18,.5),rgba(6,10,18,.12) 45%,rgba(6,10,18,.3))}
  .tbx-in{position:relative;z-index:2;width:100%;max-width:1340px;margin:0 auto;padding:0 clamp(20px,3vw,52px)}

  /* nowrap + shrinkable hairlines: on a 390px phone the tracked caps take ~230px
     and the lines give way, instead of the label breaking onto two lines. */
  .tbx-eyebrow{display:flex;align-items:center;justify-content:center;gap:18px;margin:0 0 clamp(18px,2.2vw,26px);white-space:nowrap;
    font-family:'Orbitron',sans-serif;font-weight:700;font-size:11px;letter-spacing:.32em;text-transform:uppercase;color:#d6dfee}
  .tbx-eyebrow::before,.tbx-eyebrow::after{content:"";flex:1 1 clamp(40px,6vw,90px);max-width:90px;min-width:0;height:1px;
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.42))}
  .tbx-eyebrow::after{background:linear-gradient(90deg,rgba(255,255,255,.42),transparent)}

  /* The chamfered panel. clip-path clips a border away with the corners, so the
     border is a second box: the outer element is the 1px line colour, the inner
     element the fill, both cut to the same polygon (percentages, so the same
     expression fits both boxes). */
  .tbx-bar{--cut:16px;position:relative;padding:1px;background:rgba(255,255,255,.13);
    clip-path:polygon(var(--cut) 0,calc(100% - var(--cut)) 0,100% var(--cut),100% calc(100% - var(--cut)),
      calc(100% - var(--cut)) 100%,var(--cut) 100%,0 calc(100% - var(--cut)),0 var(--cut))}
  .tbx-bar-in{--cut:16px;position:relative;padding:12px 0;
    background:linear-gradient(180deg,rgba(11,17,30,.88),rgba(6,10,19,.93));
    clip-path:polygon(var(--cut) 0,calc(100% - var(--cut)) 0,100% var(--cut),100% calc(100% - var(--cut)),
      calc(100% - var(--cut)) 100%,var(--cut) 100%,0 calc(100% - var(--cut)),0 var(--cut))}
  /* The marquee: two identical sets, the track slides one set's width (-50%)
     and snaps back invisibly. Edge fade so logos appear and leave softly. */
  .tbx-viewport{position:relative;overflow:hidden;
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
            mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
  .tbx-track{display:flex;width:max-content;animation:tbxScroll 34s linear infinite}
  .tbx-set{display:flex;align-items:center}
  .tbx-logo{position:relative;flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:13.5rem;min-height:72px;padding:6px 24px}
  /* dividers: a short vertical hairline at every cell's left edge, not full height, as in the mock */
  .tbx-logo::before{content:"";position:absolute;left:0;top:22%;height:56%;width:1px;background:rgba(255,255,255,.13)}
  .tbx-logo img{display:block;max-width:100%;max-height:40px;width:auto;height:auto;object-fit:contain;opacity:.92}
  /* BOX ONE RACING ships as a dark logotype on a white JPG: a white plate, as before. */
  .tbx-logo-plate img{background:#fff;border-radius:6px;padding:6px 10px;max-height:54px;box-sizing:border-box;opacity:1}
  /* Conspit's purple square and SRN's red square read as badges: round them. */
  .tbx-logo-tile img{border-radius:8px;opacity:1}
  @keyframes tbxScroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
  @media (prefers-reduced-motion:reduce){
    .tbx-track{animation:none;width:100%}
    .tbx-set{flex-wrap:wrap;justify-content:center}
    .tbx-set + .tbx-set{display:none}
    .tbx-viewport{-webkit-mask-image:none;mask-image:none}}

  /* ---- THE PITCH (owner's mock, 2026-09-25): replaced the $80-vs-membership
     comparison that stood here from 2026-09-17. One centred column under the logo
     panel: eyebrow, headline, a two-colour line, one sentence, and a pointer down
     to the Driver Results band. No price, and no step loop (the mock drew
     01/02/03; the owner struck it out on seeing it built). */
  .tbx-pitch{display:flex;flex-direction:column;align-items:center;text-align:center;
    margin-top:clamp(30px,3.6vw,52px)}
  /* INTER 900 at +.025em, the face every section headline on this page uses
     (owner 2026-09-17). Two block lines as in the mock: "What if coaching didn't
     end" / "after one hour?", with the cyan inside the second. Balanced, so a
     phone splits the first line evenly instead of stranding one word. */
  .tbx-h{font-family:'Inter',system-ui,sans-serif;font-weight:900;font-size:clamp(32px,4.5vw,76px);line-height:1.04;
    letter-spacing:.025em;color:#fff;margin:clamp(28px,3.2vw,46px) 0 0}
  .tbx-h > span{display:block;text-wrap:balance}
  .tbx-h em{font-style:normal;color:#5BC3F9}
  .tbx-lede{margin:clamp(16px,2vw,30px) 0 0;max-width:34em;font-family:'Inter',system-ui,sans-serif;
    font-size:clamp(15px,1.3vw,22px);line-height:1.6;color:#aab8cd;text-wrap:balance}

  /* Down to the podium band (#driver-results), which is the next section. */
  .tbx-more{display:inline-flex;flex-direction:column;align-items:center;gap:10px;margin-top:clamp(26px,3.2vw,48px);
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:clamp(16px,1.35vw,23px);color:#fff;text-decoration:none}
  .tbx-more svg{width:clamp(22px,1.8vw,28px);height:auto;color:#5BC3F9}
  .tbx-more:hover{color:#5BC3F9}
  @media (prefers-reduced-motion:no-preference){
    .tbx-more svg{animation:tbxNudge 2.4s ease-in-out infinite}
    @keyframes tbxNudge{0%,100%{transform:translateY(0)}50%{transform:translateY(6px)}}}

  /* ===== entrance: ONE reveal of the whole band, photograph included, and
     nothing fades (owner 2026-09-15, after a staggered fade-in was rejected:
     "an animation for the whole thing including background, not something with
     fade"). The band is clipped to nothing and a slanted edge wipes it open left
     to right in 1.1s, a bright scan line riding just inside that edge; the
     content eases in as one block against the wipe and the photo settles from a
     slight zoom; the logos start rolling as it opens. Pre-states only with JS
     and only for people who have not asked for reduced motion. The slant is
     100px over the band's height; the scan line's skew is tuned to the band's
     usual ~530px, close enough at other heights. ===== */
  @media (prefers-reduced-motion:no-preference){
    .tbx.tbx-js .tbx-reveal{clip-path:polygon(0 0,0 0,-100px 100%,0 100%)}
    .tbx.tbx-js .tbx-bg{transform:scale(1.05)}
    .tbx.tbx-js .tbx-in{transform:translateX(40px)}
    .tbx.tbx-js .tbx-track{animation-play-state:paused}
    /* The scan line rides the slanted edge: the edge's mid-height point is
       clip-x + 50px, the line sits 8px inside it, and both travel with the
       same easing so the offset holds for the whole wipe (`left`, not a
       translate: a translate percentage would be of the 5px line itself).

       NO SKEW, AND THAT IS A FIX, NOT A SIMPLIFICATION (owner 2026-09-17, "i see
       this line here while narrow the browser why"). It used to be skewX(-10deg),
       tuned when this band was ~530px tall and held only two columns of copy. A
       skew pivots about the element's middle, so the line's two ENDS swing out by
       halfHeight x tan(angle) in opposite directions - and the band's resting
       position, left:calc(100% + 42px), only clears a line that has not swung.

       Putting the plan cards in here took the band to ~790px on a desktop and
       ~1800px once the columns stack on a narrow window. At 1800px the swing is
       ~197px, so the BOTTOM end of the line came to rest ~155px back inside the
       band: a lit diagonal stripe sitting permanently across the Academy card,
       which is exactly what the owner photographed. It was doing the same thing at
       530px, just 16px in, where nobody saw it.

       Upright, the whole line rests outside the band and .tbx's overflow:hidden
       takes care of it. What it gives up is riding a slanted edge - and the edge is
       100px of run over the band's height, which at 790px is 7 degrees and at
       1800px is 3. It was never far off vertical; the skew was. */
    .tbx.tbx-js .tbx-reveal::after{content:"";position:absolute;top:-12%;bottom:-12%;left:-58px;width:5px;z-index:3;pointer-events:none;
      background:linear-gradient(180deg,rgba(91,195,249,.15),#fff 42%,#5BC3F9 62%,rgba(91,195,249,.15));
      box-shadow:0 0 30px 8px rgba(91,195,249,.5)}

    .tbx.tbx-live .tbx-reveal{clip-path:polygon(0 0,calc(100% + 100px) 0,100% 100%,0 100%);transition:clip-path 1.1s cubic-bezier(.7,0,.3,1)}
    .tbx.tbx-live .tbx-reveal::after{left:calc(100% + 42px);transition:left 1.1s cubic-bezier(.7,0,.3,1)}
    .tbx.tbx-live .tbx-in{transform:none;transition:transform 1.1s cubic-bezier(.7,0,.3,1)}
    .tbx.tbx-live .tbx-bg{transform:scale(1);transition:transform 1.8s cubic-bezier(.2,.6,.2,1)}
    .tbx.tbx-live .tbx-track{animation-play-state:running}}

  @media (max-width:700px){
    .tbx-bg{background-image:url("../../images/hero/trusted-track-m.ce7bfe6b741e.webp")}}
  @media (max-width:560px){
    .tbx-logo{width:11rem;min-height:64px;padding:6px 16px}
    .tbx-eyebrow{letter-spacing:.24em;gap:12px}
}

/* ============================================================================
   partials/reviews_podium.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
  .pdr{
    --disp:'Orbitron',sans-serif; --body:'Inter',sans-serif;
    --bg:#04070d; --ink:#fff; --lead:#d4ddec; --muted:#a7b6cd; --faint:#8a99b0;
    --cyan:#5BC3F9; --violet:#b98cff; --red:#e21429; --red-2:#b00f20; --green:#34d399; --gold:#F5B041;
    --line:rgba(148,175,214,.2); --glass:rgba(8,13,24,.78);
    --grad:linear-gradient(96deg,var(--cyan) 4%,var(--violet) 48%,var(--red) 96%);
  }
  .pdr, .pdr *{margin:0;padding:0;box-sizing:border-box}
  .pdr{color:var(--ink);font-family:var(--body)}
  :where(.pdr) a{color:var(--cyan);text-decoration:none}
  :where(.pdr) a:hover{color:#fff}

  .pdr{position:relative;min-height:100svh;display:flex;overflow:hidden;background:var(--bg)}
  .pdr .pdr-bg,.pdr .pdr-bg img{position:absolute;inset:0;width:100%;height:100%}
  /* BLUE, NOT ORANGE (owner 2026-09-15: "a blue tint ... to better fit the
     homepage style"). The photograph is a sunset in orange and gold; every other
     band on the page is night blue, so its hue is rotated on the way in (orange
     ~30deg lands on ~220deg blue, the golds on cyan) and the saturation eased.
     One knob, --pdr-hue; the confetti beat and the cards are unaffected. */
  .pdr{--pdr-hue:190deg}
  .pdr .pdr-bg img{object-fit:cover;object-position:50% 26%;filter:hue-rotate(var(--pdr-hue)) saturate(.82) brightness(.96)}
  .pdr .pdr-scrim{position:absolute;inset:0;background:
    linear-gradient(180deg,rgba(4,7,13,.5),transparent 22%),
    linear-gradient(0deg,rgba(4,7,13,.72),transparent 26%)}

  /* ===== results ceremony (JS adds .pdr-js on init, .pdr-live when the
     section scrolls into view): camera release + timing-feed card entrance
     P3 -> P2 -> P1, gold crown flash + shimmer + count-up on the winner,
     one confetti beat, strip last. Without JS everything shows finished. */
  /* SLOWER than the original, not twice as slow (owner 2026-09-15: "a slower
     fade animation", then "a bit too slow"): fades of 1s, from .6s, with the
     stagger stretched to match. The heading fades in first, the cards follow one
     by one, and the crown and confetti wait for P1 to land. Camera release
     2.4s, from 1.7s. */
  .pdr.pdr-js .pdr-bg img{transform:scale(1.14) translateY(2.2%);transform-origin:50% 30%}
  .pdr.pdr-live .pdr-bg img{transform:scale(1) translateY(0);transition:transform 2.4s cubic-bezier(.2,.6,.2,1)}
  .pdr.pdr-js .pdr-kicker,.pdr.pdr-js .pdr-card,.pdr.pdr-js .pdr-tl,.pdr.pdr-js .pdr-foot,.pdr.pdr-js .pdr-strip{opacity:0;transform:translateY(26px)}
  .pdr.pdr-live .pdr-kicker,.pdr.pdr-live .pdr-card,.pdr.pdr-live .pdr-tl,.pdr.pdr-live .pdr-foot,.pdr.pdr-live .pdr-strip{opacity:1;transform:none;
    transition:opacity 1s cubic-bezier(.2,.7,.2,1),transform 1s cubic-bezier(.2,.7,.2,1)}
  .pdr.pdr-live .pdr-kicker{transition-delay:.1s}                 /* the heading opens */
  .pdr.pdr-live .pdr-card:nth-of-type(3){transition-delay:.35s}   /* P3 first */
  .pdr.pdr-live .pdr-card:nth-of-type(2){transition-delay:.8s}    /* then P2 */
  .pdr.pdr-live .pdr-card:nth-of-type(1){transition-delay:1.25s}  /* P1 crowned last */
  .pdr.pdr-live .pdr-foot{transition-delay:1.75s}
  .pdr.pdr-live .pdr-strip{transition-delay:1.9s}
  /* P1 crown: gold ring flash on the avatar + one shimmer sweep */
  .pdr.pdr-live .pdr-card:nth-of-type(1) .pdr-ava{animation:pdrCrown 1.2s 2.2s ease both}
  @keyframes pdrCrown{
    0%{box-shadow:0 0 14px color-mix(in oklab,var(--ac,#5BC3F9) 30%,transparent)}
    35%{box-shadow:0 0 0 3px var(--gold),0 0 30px rgba(245,176,65,.85)}
    100%{box-shadow:0 0 14px color-mix(in oklab,var(--ac,#5BC3F9) 30%,transparent)}
  }
  .pdr.pdr-live .pdr-card:nth-of-type(1)::after{content:"";position:absolute;top:0;bottom:0;left:-70%;width:44%;
    transform:skewX(-20deg);pointer-events:none;
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.16),transparent);animation:pdrShine 1.2s 2.2s ease both}
  .pdr .pdr-card{position:relative}
  @keyframes pdrShine{0%{left:-70%}100%{left:130%}}
  /* confetti beat behind the tower */
  .pdr-confetti{position:absolute;inset:0;overflow:hidden;pointer-events:none;opacity:0}
  .pdr.pdr-live .pdr-confetti{opacity:1}
  .pdr-confetti i{position:absolute;top:-4%;width:7px;height:11px;border-radius:2px;opacity:0}
  .pdr.pdr-live .pdr-confetti i{animation:pdrDrop 2s cubic-bezier(.3,.4,.6,1) both;animation-delay:calc(2.3s + var(--cd,0)*.14s)}
  @keyframes pdrDrop{
    0%{opacity:0;transform:translateY(0) rotate(0)}
    12%{opacity:.95}
    100%{opacity:0;transform:translateY(64vh) rotate(260deg)}
  }
  @media (prefers-reduced-motion: reduce){
    .pdr.pdr-js .pdr-bg img,.pdr.pdr-js .pdr-kicker,.pdr.pdr-js .pdr-card,.pdr.pdr-js .pdr-tl,.pdr.pdr-js .pdr-foot,.pdr.pdr-js .pdr-strip{opacity:1;transform:none;transition:none}
    .pdr.pdr-live .pdr-card:nth-of-type(1) .pdr-ava,.pdr.pdr-live .pdr-card:nth-of-type(1)::after,.pdr.pdr-live .pdr-confetti i{animation:none}
    .pdr-confetti{display:none}}

  .pdr-wrap{position:relative;z-index:2;display:flex;flex-direction:column;width:100%;max-width:1500px;margin:0 auto;padding:6.5vh 4.5vw 4vh}

  /* THE HEADING is the eyebrow "DRIVER RESULTS" with a hairline, sitting at the
     top of the tower, over P1 (owner 2026-09-15; it was top-left of the slide for
     an hour, and had a big two-line headline under it for an afternoon, both
     cut). The kicker is the h2, so the section keeps a visible heading (it had
     an sr-only one from 2026-07-22 to today). */
  .pdr-kicker{display:flex;align-items:center;gap:18px;margin:0 0 4px;padding:0 4px;font-family:var(--body);font-weight:700;font-size:12px;letter-spacing:.3em;
    text-transform:uppercase;color:#e6edf8;text-shadow:0 2px 8px rgba(0,0,0,.8)}
  .pdr-kicker::after{content:"";flex:0 0 clamp(60px,9vw,140px);height:1px;background:rgba(255,255,255,.35)}

  /* The tower is the grid's only child now, so it names its column; the first
     column is the open photo. */
  .pdr-body{flex:1;display:grid;grid-template-columns:minmax(0,1fr) minmax(340px,560px);gap:32px;align-items:center;margin-top:2vh}
  .pdr-tower{grid-column:2}

  .pdr-tower{display:flex;flex-direction:column;gap:12px}
  .pdr-tl{font-family:var(--body);font-weight:700;font-size:11.5px;letter-spacing:.1em;color:#cbd7e8;text-transform:uppercase;
    display:flex;align-items:center;gap:14px;padding:0 4px;text-shadow:0 2px 8px rgba(0,0,0,.8)}
  .pdr-tl::after{content:"";flex:1;height:1px;background:rgba(148,175,214,.3)}
  .pdr-tl b{font-weight:700}

  .pdr-card{border:1px solid var(--line);border-radius:16px;background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    box-shadow:0 24px 60px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);overflow:hidden;transition:transform .25s ease,border-color .25s ease,box-shadow .25s ease}
  /* OPEN IS LIGHT BLUE, NOT GOLD (owner 2026-09-17). Gold is what the position
     markers and the star rating are, and an expanded row edged in the same colour
     read as a third use of it rather than a state. One blue, the site's own accent,
     across all three rows: this is the "this one is open" signal, and a signal that
     changes colour depending on which row you opened is not a signal.

     It is deliberately NOT var(--ac): that is the per-row accent the hover uses, and
     hover and open have to stay tellable apart. */
  .pdr-card.pdr-open{border-color:rgba(91,195,249,.6);box-shadow:0 24px 60px rgba(0,0,0,.6), 0 0 30px rgba(91,195,249,.18), inset 0 1px 0 rgba(255,255,255,.06)}
  /* HOVER (owner 2026-09-17). Each row lights in ITS OWN accent - the one already on
     the avatar and the delta chip - rather than a single shared colour, so hovering
     P2 does not make it look like P1. The whole card responds because the whole card
     is the hit area: .pdr-rhead fills it and toggles the review open.

     @media (hover:hover) keeps it off touch, where :hover sticks after a tap and
     would leave a row lifted and glowing under the review it just opened. */
  @media (hover:hover){
    .pdr-card:hover{transform:translateY(-2px);border-color:rgba(var(--ac-rgb),.55);
      box-shadow:0 26px 64px rgba(0,0,0,.58), 0 0 40px -8px rgba(var(--ac-rgb),.3), inset 0 1px 0 rgba(255,255,255,.08)}
    /* An open row is already bordered; hover only deepens it, and never dims it. */
    .pdr-card.pdr-open:hover{border-color:rgba(var(--ac-rgb),.8)}}
  @media (prefers-reduced-motion:reduce){
    .pdr-card{transition:border-color .25s ease,box-shadow .25s ease}
    .pdr-card:hover{transform:none}}
  .pdr-rhead{appearance:none;border:0;background:transparent;width:100%;cursor:pointer;text-align:left;color:var(--muted);font-family:var(--body);
    display:flex;align-items:center;gap:14px;padding:16px 18px}
  .pdr-rhead .pdr-pos{font-family:var(--disp);font-weight:900;font-size:17px;color:var(--gold);width:36px;flex:0 0 auto}
  .pdr-ava{width:42px;height:42px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;
    font-family:var(--disp);font-weight:800;font-size:16px;line-height:1;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5);
    background:color-mix(in oklab,var(--ac,#5BC3F9) 32%,#0a1424);border:2px solid var(--ac,#5BC3F9);
    box-shadow:0 0 14px color-mix(in oklab,var(--ac,#5BC3F9) 30%,transparent)}
  .pdr-rhead .pdr-nm{min-width:0}
  .pdr-rhead .pdr-nm b{display:block;font-size:15px;font-weight:700;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .pdr-rhead .pdr-nm span{display:block;font-size:12px;color:var(--muted);margin-top:3px}
  .pdr-rhead .pdr-delta{margin-left:auto;flex:0 0 auto;font-weight:700;font-size:12px;color:var(--green);
    border:1px solid rgba(52,211,153,.4);border-radius:9px;padding:7px 12px;background:rgba(52,211,153,.07);white-space:nowrap}
  .pdr-rhead .pdr-chev{flex:0 0 auto;width:18px;height:18px;stroke:var(--faint);fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
    transition:transform .3s ease}
  /* The chevron is part of the open state, so it moves with the edge - a gold arrow
     inside a blue-edged card reads as something left behind. */
  .pdr-card.pdr-open .pdr-chev{transform:rotate(180deg);stroke:var(--cyan)}
  .pdr-rbody{display:grid;grid-template-rows:0fr;transition:grid-template-rows .38s cubic-bezier(.2,.7,.2,1)}
  .pdr-card.pdr-open .pdr-rbody{grid-template-rows:1fr}
  .pdr-rbody > div{overflow:hidden}
  .pdr-rin{padding:2px 18px 18px 68px}
  .pdr-stars{color:var(--gold);font-size:13px;letter-spacing:2px}
  .pdr-rin blockquote{font-size:14.5px;line-height:1.65;color:#eef3fa;font-weight:500;margin-top:9px}
  .pdr-badge{display:inline-flex;align-items:center;gap:8px;margin-top:12px;border:1px solid rgba(52,211,153,.4);border-radius:999px;
    padding:7px 13px;background:rgba(52,211,153,.08);font-weight:700;font-size:11.5px;color:var(--green)}
  .pdr-badge svg{width:13px;height:13px;stroke:var(--green);fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
  /* A FOURTH ROW, AND THE SPECIAL ONE (owner 2026-09-17: "similar with the boxes above
     but looking more special than those"). It takes .pdr-card's geometry exactly - full
     width of the tower, 16px radius, the same glass, the same blur, the same drop
     shadow and inner highlight - so it reads as one more row rather than a caption
     floating under three of them. It had been a small pill, which is what made it look
     like fine print.

     What makes it the special one is the only thing that differs: a lit cyan edge, a
     cyan sheen over the glass and a bloom underneath, where the rows above sit on a
     neutral hairline.

     It is NOT solid at rest. The page's one solid button is red and means apply, and a
     second filled button a few inches above it in another colour competes for the same
     decision. It fills on hover instead: clearly a control, clearly the secondary one. */
  .pdr-foot{margin-top:12px}
  .pdr-foot a{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;
    padding:18px 22px;border-radius:16px;
    font-weight:700;font-size:15px;letter-spacing:.01em;text-shadow:none;color:#dff1ff;
    background:linear-gradient(180deg,rgba(91,195,249,.17),rgba(91,195,249,.05)),var(--glass);
    border:1px solid rgba(91,195,249,.55);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    box-shadow:0 24px 60px rgba(0,0,0,.5),0 0 34px -8px rgba(91,195,249,.34),inset 0 1px 0 rgba(255,255,255,.08);
    transition:background .2s ease,color .2s ease,border-color .2s ease,transform .2s ease,box-shadow .2s ease}
  .pdr-foot a:hover{background:var(--cyan);color:#04070d;border-color:var(--cyan);transform:translateY(-2px);
    box-shadow:0 28px 68px rgba(0,0,0,.55),0 0 48px -8px rgba(91,195,249,.6),inset 0 1px 0 rgba(255,255,255,.25)}
  .pdr-foot a:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}

  .pdr-strip{margin-top:auto;border-radius:16px;border:1px solid rgba(148,175,214,.26);background:rgba(6,10,19,.82);
    backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    display:flex;align-items:center;gap:18px 28px;padding:16px 22px;flex-wrap:wrap}
  .pdr-strip .pdr-rate{display:flex;align-items:center;gap:10px;font-weight:600;font-size:12.5px;color:var(--muted)}
  .pdr-strip .pdr-price{margin-left:auto;font-weight:600;font-size:12.5px;color:var(--muted)}
  .pdr-strip .pdr-price b{color:#fff}
  .pdr-btn{font-family:var(--disp);font-weight:800;font-size:12px;letter-spacing:.13em;color:#fff;
    background:linear-gradient(180deg,var(--red),var(--red-2));padding:14px 26px;border-radius:11px;white-space:nowrap;
    box-shadow:0 12px 26px rgba(226,20,41,.38), inset 0 1px 0 rgba(255,255,255,.22);transition:transform .2s ease,filter .2s ease}
  .pdr-btn:hover{color:#fff;transform:translateY(-2px);filter:brightness(1.08)}
  .pdr-strip .pdr-tagf{font-weight:600;font-size:11px;color:var(--faint)}
  .pdr-strip .pdr-tagf b{color:var(--green)}

  @media (prefers-reduced-motion: reduce){
    .pdr-rbody,.pdr-chev,.pdr-card{transition:none}
    .pdr-foot a:hover{transform:none}}
  @media (max-width: 980px){
    /* Mobile/tablet = ONE clean full-viewport photo SLIDE (the celebration,
       winner's finger raised), then the reviews as their own block below on the
       dark --bg (owner 2026-07-24: "put the image normally as a single slide
       with nothing, and below it introduce the reviews"). Nothing overlaps the
       photo — the bg + scrim are capped at 100svh, and the card wrap is pushed
       a full viewport down so the slide reads on its own. */
    .pdr{min-height:100svh}
    .pdr .pdr-bg{bottom:auto;height:100svh}          /* photo occupies the first viewport only */
    .pdr .pdr-bg img{object-position:50% 35%}         /* frame the winner (finger up) fully */
    .pdr .pdr-scrim{bottom:auto;height:100svh;background:linear-gradient(180deg,
      rgba(4,7,13,0) 0%, rgba(4,7,13,0) 78%, rgba(4,7,13,.6) 92%, var(--bg) 100%)}
    .pdr .pdr-wrap{padding:calc(100svh + 22px) 5vw 5vh}  /* cards begin BELOW the slide */
    .pdr-body{grid-template-columns:1fr}
    .pdr-tower{grid-column:1}
    .pdr-strip{margin-top:30px}
    .pdr-strip .pdr-price{margin-left:0}}
  @media (max-width: 640px){
    /* (wrap padding is set in the <=980 slide rule above.) */
    /* The delta pill is the collapsed card's only hook ("Move done next lap"),
       so on phones it wraps onto its own row under the name instead of being
       hidden — hiding it left P2/P3 as bare names with nothing to open them
       for. Indent 56px lines it up under the name, clearing pos+avatar. */
    .pdr-rhead{flex-wrap:wrap;row-gap:9px}
    .pdr-rhead .pdr-nm{flex:1 1 auto;min-width:0}
    .pdr-rhead .pdr-chev{order:4}
    .pdr-rhead .pdr-delta{order:5;flex:0 0 auto;margin-left:56px;margin-right:auto;
      font-size:11.5px;padding:6px 11px}
    .pdr-rin{padding-left:18px}
    .pdr-strip{flex-direction:column;align-items:stretch;text-align:center}
    .pdr-strip .pdr-rate{justify-content:center}
    .pdr-btn{text-align:center}
    /* The page's fixed .alp-sticky-cta--mobile bar physically OVERLAPS this
       inline CTA on phones (measured at 360x800: bar top 730 vs button
       765-811 — the button is covered), so hide it and let the sticky bar own
       the phone CTA. Same pattern partials/drills_showcase.html uses. The
       rating / price / guarantee lines stay — they're the social proof. */
    .pdr-strip .pdr-btn{display:none}}

/* ============================================================================
   partials/ask_a_coach.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
  .akc{
    --disp:'Orbitron',sans-serif; --body:'Inter',sans-serif; --mono:'JetBrains Mono',monospace;
    --bg:#04070d; --ink:#fff; --lead:#d4ddec; --muted:#a7b6cd; --faint:#7b8aa2;
    --cyan:#5BC3F9; --blue:#5b9dff; --violet:#b98cff; --red:#e21429; --red-2:#b00f20; --green:#34d399; --gold:#F5B041;
    --line:rgba(148,175,214,.16); --glass:rgba(8,14,26,.72);
  }
  .akc, .akc *{margin:0;padding:0;box-sizing:border-box}
  .akc{color:var(--ink);font-family:var(--body)}
  :where(.akc) a{color:var(--cyan);text-decoration:none}
  :where(.akc) a:hover{color:#fff}
  .akc img{display:block;max-width:100%}

  .akc{position:relative;padding:14vh 6vw;overflow:hidden;background:var(--bg)}
  .akc-bg-track{position:absolute;inset:0;z-index:0}
  .akc-bg-track img{width:100%;height:100%;object-fit:cover;object-position:50% 60%}
  .akc-bg-track::after{content:"";position:absolute;inset:0;background:
    linear-gradient(180deg,rgba(4,7,13,.72) 0%,rgba(4,7,13,.38) 40%,rgba(4,7,13,.78) 100%),
    radial-gradient(1000px 560px at 78% 16%,rgba(91,157,255,.07),transparent 60%)}
  .akc-cols,.akc-grid-ov{position:relative;z-index:1}
  .akc-grid-ov{position:absolute;inset:0;pointer-events:none;opacity:.4;
    background:linear-gradient(rgba(148,175,214,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(148,175,214,.05) 1px,transparent 1px);
    background-size:58px 58px;-webkit-mask-image:radial-gradient(circle at 60% 30%,black,transparent 74%);mask-image:radial-gradient(circle at 60% 30%,black,transparent 74%)}
  .akc-cols{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);gap:5vw;max-width:1240px;margin:0 auto;align-items:center}

  .akc-rv{opacity:0;transform:translateY(24px)}
  .akc-rv.akc-in{opacity:1;transform:none;transition:opacity .8s cubic-bezier(.2,.7,.2,1),transform .8s cubic-bezier(.2,.7,.2,1)}
  .akc-rv.akc-in.akc-d1{transition-delay:.08s}.akc-rv.akc-in.akc-d2{transition-delay:.16s}.akc-rv.akc-in.akc-d3{transition-delay:.24s}.akc-rv.akc-in.akc-d4{transition-delay:.32s}
  @media (prefers-reduced-motion: reduce){ .akc-rv{opacity:1;transform:none}}

  /* ---- left ---- */
  .akc-pill{display:inline-flex;align-items:center;gap:8px;font-family:var(--disp);font-weight:700;font-size:10px;letter-spacing:.28em;color:var(--cyan);
    border:1px solid rgba(91,195,249,.42);border-radius:999px;padding:9px 16px;background:rgba(91,195,249,.06)}
  .akc-pill i{width:6px;height:6px;border-radius:50%;background:var(--cyan);animation:akcPulse 1.9s ease infinite;font-style:normal}
  @keyframes akcPulse{0%,100%{opacity:1}50%{opacity:.25}}
  /* Headline face matched to the weekly loop's "Your weekly coaching loop"
     (partials/weekly_loop.html .wkl-head h2) on the owner's ask, 2026-09-17:
     Inter 900 with positive .025em tracking, not Orbitron. The weekly loop is the
     new reference headline on this page and these sections follow it. Case is left
     as each section has it. Size clamp and line-height are each section's own and
     unchanged. */
  .akc h2{font-family:var(--body);font-weight:900;font-size:clamp(30px,3.8vw,54px);line-height:1.07;letter-spacing:.025em;color:var(--ink);margin-top:18px}
  /* Matched to the "Stop guessing / what to practise." headline in
     partials/trusted_approach.html (.tbx-h / .tbx-h span) on the owner's ask,
     2026-09-17: white with ONE #5BC3F9 accent. It used to run --grad, the
     cyan -> violet -> red sweep, which put a pink third line on the page that
     appears nowhere else in the section. Solid colour, not a gradient, so it
     matches the other headline exactly rather than approximately. */
  .akc h2 .akc-g{color:#5BC3F9}
  .akc-sub{color:var(--muted);font-size:15px;line-height:1.65;max-width:480px;margin-top:16px}
  .akc-topics{display:flex;gap:8px;flex-wrap:wrap;margin-top:22px}
  .akc-topic{font-family:var(--body);font-weight:600;font-size:12px;letter-spacing:.03em;color:var(--lead);border:1px solid var(--line);border-radius:999px;
    padding:9px 15px;background:rgba(6,11,21,.6);transition:all .3s ease}
  .akc-topic.akc-hot{border-color:var(--tc);color:#fff;background:color-mix(in oklab,var(--tc) 12%,rgba(6,11,21,.6));box-shadow:0 0 18px color-mix(in oklab,var(--tc) 18%,transparent)}
  .akc-allow{display:flex;align-items:center;gap:14px;margin-top:26px;border:1px solid var(--line);border-radius:14px;padding:15px 18px;background:var(--glass);max-width:420px}
  .akc-allow .akc-dots{display:flex;gap:6px}
  .akc-allow .akc-dots i{width:26px;height:8px;border-radius:4px;background:rgba(148,175,214,.18)}
  .akc-allow .akc-dots i.akc-on{background:linear-gradient(90deg,var(--cyan),var(--blue));box-shadow:0 0 10px rgba(91,195,249,.45)}
  .akc-allow .akc-tx{font-family:var(--body);font-weight:600;font-size:12px;color:var(--muted)}
  .akc-allow .akc-tx b{color:#fff}
  .akc-facts{display:flex;gap:22px;margin-top:18px;flex-wrap:wrap;font-family:var(--body);font-weight:600;font-size:12px;color:var(--faint)}
  .akc-facts span{display:flex;align-items:center;gap:8px}
  .akc-facts i{font-style:normal;color:var(--green)}
  .akc-cta{display:flex;align-items:center;gap:16px;margin-top:26px;flex-wrap:wrap}
  /* Same face as the weekly loop's join button above it (owner 2026-09-27, "an
     inconsistency with the font"): Archivo 700 at .1em, not this section's
     Orbitron --disp, which the pill and labels here keep. */
  .akc-btn{font-family:'Archivo',system-ui,sans-serif;font-weight:700;font-size:15px;letter-spacing:.1em;color:#fff;
    background:linear-gradient(180deg,var(--red),var(--red-2));padding:15px 28px;border-radius:12px;
    box-shadow:0 14px 32px rgba(226,20,41,.4), inset 0 1px 0 rgba(255,255,255,.22);transition:transform .2s ease,filter .2s ease}
  .akc-btn:hover{color:#fff;transform:translateY(-2px);filter:brightness(1.08)}
  .akc-price{font-family:var(--body);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--faint)}
  .akc-price b{color:#fff}

  /* ---- right: thread ---- */
  .akc-thread{position:relative;justify-self:end;width:min(520px,100%)}
  .akc-thread .akc-halo{position:absolute;inset:-12%;z-index:0;border-radius:50%;background:radial-gradient(circle,rgba(91,195,249,.1),transparent 62%);filter:blur(12px)}
  .akc-panel{position:relative;z-index:1;border-radius:20px;border:1px solid rgba(148,175,214,.28);background:var(--glass);
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 44px 100px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.07);overflow:hidden}
  .akc-ph{display:flex;align-items:center;gap:12px;padding:14px 18px;border-bottom:1px solid var(--line)}
  .akc-ph .akc-t{font-family:var(--disp);font-weight:700;font-size:11px;letter-spacing:.18em}
  .akc-ph .akc-roster{margin-left:auto;display:flex;align-items:center}
  .akc-ph .akc-roster .akc-av{width:30px;height:30px;border-radius:50%;border:2px solid #0a1222;margin-left:-8px;overflow:hidden;background:radial-gradient(circle at 50% 30%,rgba(91,157,255,.3),#0a1424);
    display:flex;align-items:center;justify-content:center;font-family:var(--disp);font-weight:800;font-size:10px;transition:all .35s ease;position:relative}
  .akc-ph .akc-roster .akc-av img{width:100%;height:100%;object-fit:cover;object-position:50% 10%}
  .akc-ph .akc-roster .akc-av.akc-live{border-color:var(--green);box-shadow:0 0 12px rgba(52,211,153,.5);transform:translateY(-2px)}
  .akc-ph .akc-st{font-family:var(--body);font-weight:600;font-size:11px;letter-spacing:.04em;color:var(--green);margin-left:12px;white-space:nowrap}
  .akc-ph .akc-st i{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--green);margin-right:6px;animation:akcPulse 1.6s ease infinite;font-style:normal}

  .akc-feed{padding:18px;display:flex;flex-direction:column;gap:12px;min-height:330px}
  .akc-msg{max-width:86%;border-radius:14px;padding:12px 15px;font-size:13px;line-height:1.55;position:relative;
    opacity:0;transform:translateY(14px) scale(.98);transition:opacity .45s ease,transform .45s cubic-bezier(.2,.7,.2,1)}
  .akc-msg.akc-show{opacity:1;transform:none}
  .akc-msg.akc-q{align-self:flex-end;background:linear-gradient(180deg,rgba(91,157,255,.2),rgba(91,157,255,.1));border:1px solid rgba(91,157,255,.35);color:#fff;border-bottom-right-radius:4px}
  .akc-msg.akc-q .akc-who{font-family:var(--body);font-weight:700;font-size:10px;color:var(--blue);letter-spacing:.06em;margin-bottom:5px;text-transform:uppercase}
  .akc-msg.akc-a{align-self:flex-start;background:rgba(5,9,18,.72);border:1px solid var(--line);border-left:3px solid var(--green);color:var(--lead);border-bottom-left-radius:4px;display:flex;gap:11px}
  .akc-msg.akc-a .akc-cav{width:34px;height:34px;border-radius:50%;flex:0 0 auto;overflow:hidden;border:1.5px solid var(--green);background:#0a1424;
    display:flex;align-items:center;justify-content:center;font-family:var(--disp);font-weight:800;font-size:11px}
  .akc-msg.akc-a .akc-cav img{width:100%;height:100%;object-fit:cover;object-position:50% 10%}
  .akc-msg.akc-a .akc-who{font-family:var(--body);font-weight:700;font-size:10.5px;color:var(--green);margin-bottom:5px}
  .akc-msg.akc-a .akc-who span{color:var(--faint);font-weight:600}
  .akc-typing{align-self:flex-start;display:flex;gap:5px;padding:13px 16px;border-radius:14px;border-bottom-left-radius:4px;background:rgba(5,9,18,.72);border:1px solid var(--line);
    opacity:0;transition:opacity .3s ease}
  .akc-typing.akc-show{opacity:1}
  .akc-typing i{width:6px;height:6px;border-radius:50%;background:var(--muted);animation:akcTp 1s ease infinite;font-style:normal}
  .akc-typing i:nth-child(2){animation-delay:.15s}.akc-typing i:nth-child(3){animation-delay:.3s}
  @keyframes akcTp{0%,100%{opacity:.25;transform:none}50%{opacity:1;transform:translateY(-3px)}}
  .akc-stamp{align-self:flex-start;font-family:var(--body);font-weight:600;font-size:11.5px;letter-spacing:.03em;color:var(--faint);padding-left:4px;
    opacity:0;transition:opacity .4s ease}
  .akc-stamp.akc-show{opacity:1}
  .akc-stamp b{color:var(--green)}

  .akc-composer{display:flex;gap:10px;align-items:center;padding:14px 16px;border-top:1px solid var(--line)}
  .akc-composer .akc-in{flex:1;border:1px solid var(--line);border-radius:11px;padding:12px 15px;font-size:12.5px;color:var(--faint);background:rgba(4,8,16,.7);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .akc-composer .akc-in .akc-caret{display:inline-block;width:6px;height:13px;background:var(--cyan);vertical-align:middle;margin-left:2px;animation:akcPulse 1.1s steps(2) infinite}
  .akc-composer .akc-send{width:42px;height:42px;flex:0 0 auto;border-radius:11px;background:linear-gradient(180deg,#7cd0ff,#3e9be6);display:flex;align-items:center;justify-content:center;
    box-shadow:0 10px 22px rgba(91,195,249,.35)}
  .akc-composer .akc-send svg{width:17px;height:17px;stroke:#04121f;fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
  .akc-left-note{font-family:var(--body);font-weight:600;font-size:11px;color:var(--faint);text-align:center;padding:0 16px 14px}
  .akc-left-note b{color:var(--cyan)}

  @media (prefers-reduced-motion: reduce){
    .akc-pill i,.akc-ph .akc-st i,.akc-typing i,.akc-composer .akc-in .akc-caret{animation:none}
    .akc-msg,.akc-typing,.akc-stamp{transition:none}}
  @media (max-width: 1024px){
    /* minmax(0,1fr), not bare 1fr: the composer's nowrap placeholder otherwise
       inflates the column past the viewport (panel clipped ~9px at 390px). */
    .akc-cols{grid-template-columns:minmax(0,1fr);gap:52px}
    .akc-thread{justify-self:stretch;width:100%;min-width:0}}
  @media (max-width: 640px){
    .akc{padding:12vh 5vw}
    .akc-feed{min-height:300px;padding:14px}
    .akc-msg{max-width:94%}
    .akc-btn{flex:1;text-align:center}
    .akc-topics .akc-topic:nth-child(4){display:none}}

  /* Owner 2026-07-17 (mobile): the ASK YOUR FIRST QUESTION button is replaced
     by the reviews-tower conversion strip at the section end (the reviews
     section itself is phone-hidden and its strip lives on here). */
  .akc-strip{display:none}
  @media (max-width: 720px){
    .akc{padding:48px 6vw 44px}  /* owner: no dead space above the pill (was 12-14vh) */
    .akc-cta{display:none}
    .akc-facts span:nth-child(3){display:none}  /* owner: no 'Professional coaching advice' on phones */
    .akc-strip{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:26px;text-align:center;
      border:1px solid rgba(148,175,214,.24);border-radius:16px;background:rgba(6,11,21,.7);padding:16px 18px}
    .akc-strip .akc-stars{color:var(--gold);font-size:13px;letter-spacing:2px;margin-right:8px}
    .akc-strip .akc-rate,.akc-strip .akc-sprice{font-family:var(--body);font-weight:600;font-size:12.5px;color:var(--muted)}
    .akc-strip .akc-sprice b{color:#fff}
    .akc-strip .akc-btn2{width:100%;text-align:center;font-family:'Archivo',system-ui,sans-serif;font-weight:700;font-size:15px;letter-spacing:.1em;color:#fff;
      background:linear-gradient(180deg,var(--red),var(--red-2));padding:15px 26px;border-radius:11px;
      box-shadow:0 12px 26px rgba(226,20,41,.38), inset 0 1px 0 rgba(255,255,255,.22)}
    .akc-strip .akc-tagf2{font-family:var(--body);font-weight:600;font-size:12px;color:var(--faint)}
    .akc-strip .akc-tagf2 b{color:var(--green)}}

/* ============================================================================
   partials/racing_book_cinematic.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
  .rbk{
    --disp:'Orbitron',sans-serif; --body:'Inter',sans-serif; --mono:'JetBrains Mono',monospace;
    --bg:#04070d; --ink:#fff; --lead:#d4ddec; --muted:#a7b6cd; --faint:#7b8aa2;
    --cyan:#5BC3F9; --blue:#5b9dff; --red:#e21429; --red-2:#b00f20; --green:#34d399; --gold:#F5B041;
    --line:rgba(148,175,214,.16); --glass:rgba(8,14,26,.7);
  }
  .rbk, .rbk *{margin:0;padding:0;box-sizing:border-box}
  .rbk{color:var(--ink);font-family:var(--body)}
  :where(.rbk) a{color:var(--cyan);text-decoration:none}
  :where(.rbk) a:hover{color:#fff}
  .rbk img{display:block;max-width:100%}

  .rbk{height:600vh;position:relative}
  .rbk .rbk-stick{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;display:flex;flex-direction:column;gap:2vh;padding:calc(1.5vh + 64px) 5vw 4vh;background:var(--bg)}
  .rbk-bg-track{position:absolute;inset:0;z-index:0}
  .rbk-bg-track img{width:100%;height:100%;object-fit:cover;object-position:50% 68%}
  /* BOTTOM EDGE ONLY (owner 2026-09-17): the courses band below reuses this same
     photograph on its own crop, so the join showed as a hard horizontal cut. Fading
     this image out over the last 12% lets both bands meet on flat ground. The top is
     left alone - above it is Ask A Coach, a different photograph, and masking there
     would only wash out this one's sky. */
  .rbk-bg-track img{-webkit-mask-image:linear-gradient(180deg,#000 0,#000 88%,transparent 100%);
    mask-image:linear-gradient(180deg,#000 0,#000 88%,transparent 100%)}
  /* THREE LAYERS, and the order is the point (first listed sits on top).
     The photograph is a sunset track: its mid-band is warm orange-grey and read
     as a different palette from the rest of the page, which is navy throughout.
     The blue wash goes UNDER the dark gradient rather than over it, so it tints
     most exactly where the dark layer is thinnest (34% at the 62% stop) - i.e.
     the bright warm middle - and barely touches the already-black top and bottom.
     A flat overlay at one opacity would have muddied the dark ends to lift the
     middle. Owner asked for "slightly blue", 2026-09-17. */
  .rbk-bg-track::after{content:"";position:absolute;inset:0;background:
    linear-gradient(180deg,rgba(4,7,13,.88) 0%,rgba(4,7,13,.55) 34%,rgba(4,7,13,.34) 62%,rgba(4,7,13,.86) 100%),
    linear-gradient(180deg,rgba(64,132,224,.16) 0%,rgba(64,132,224,.30) 58%,rgba(64,132,224,.18) 100%),
    radial-gradient(1000px 560px at 74% 20%,rgba(91,157,255,.07),transparent 60%)}
  .rbk-head,.rbk-mid{z-index:2}
  .rbk-grid-ov{z-index:1}
  .rbk-grid-ov{position:absolute;inset:0;pointer-events:none;opacity:.4;
    background:linear-gradient(rgba(148,175,214,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(148,175,214,.05) 1px,transparent 1px);
    background-size:58px 58px;-webkit-mask-image:radial-gradient(circle at 50% 34%,black,transparent 76%);mask-image:radial-gradient(circle at 50% 34%,black,transparent 76%)}

  .rbk-head{position:relative;display:flex;align-items:flex-end;justify-content:space-between;gap:20px;max-width:1280px;width:100%;margin:0 auto;flex-wrap:wrap}
  /* Headline face matched to the weekly loop's "Your weekly coaching loop"
     (partials/weekly_loop.html .wkl-head h2) on the owner's ask, 2026-09-17:
     Inter 900 with positive .025em tracking, not Orbitron. The weekly loop is the
     new reference headline on this page and these sections follow it. Case is left
     as each section has it. Size clamp and line-height are each section's own and
     unchanged. */
  .rbk-head h2{font-family:var(--body);font-weight:900;font-size:clamp(28px,3.6vw,52px);line-height:1.08;letter-spacing:.025em;text-transform:none}
  /* Matched to "Stop guessing / what to practise." in partials/trusted_approach.html
     (.tbx-h / .tbx-h span) on the owner's ask, 2026-09-17, same as the Ask-A-Coach
     headline. It ran --grad, the cyan -> violet -> red sweep, which is why
     "Included In The Membership" faded to pink and then red. The h2 already
     inherits white from .rbk{color:var(--ink)}, so only the accent needed setting. */
  .rbk-head h2 .rbk-g{color:#5BC3F9}
  .rbk-head .rbk-sub{color:var(--muted);font-size:13.5px;margin-top:8px}
  .rbk-head .rbk-chips{display:flex;gap:8px;flex-wrap:wrap}
  .rbk-head .rbk-chips span{font-family:var(--body);font-weight:600;font-size:11.5px;letter-spacing:.04em;color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:8px 13px;background:rgba(6,11,21,.6)}
  .rbk-head .rbk-chips span b{color:var(--cyan);font-weight:700}

  .rbk-mid{position:relative;flex:1;min-height:0;display:grid;grid-template-columns:minmax(200px,250px) minmax(0,1fr);gap:3vw;max-width:1280px;width:100%;margin:0 auto;align-items:center}

  /* ---- chapter rail ---- */
  .rbk-toc{display:flex;flex-direction:column;gap:4px}
  .rbk-toc .rbk-t{font-family:var(--body);font-weight:600;font-size:11px;letter-spacing:.06em;color:var(--faint);margin-bottom:10px;text-transform:uppercase}
  .rbk-ch{appearance:none;background:none;border:0;text-align:left;cursor:pointer;display:flex;align-items:baseline;gap:10px;padding:9px 12px;border-radius:10px;
    border:1px solid transparent;color:var(--faint);transition:all .3s ease;font-family:var(--body)}
  .rbk-ch .rbk-pg{font-family:var(--body);font-weight:600;font-size:10.5px;letter-spacing:.04em;width:34px;flex:0 0 auto;color:var(--faint)}
  .rbk-ch .rbk-nm{font-size:13.5px;font-weight:600;letter-spacing:.01em}
  .rbk-ch.rbk-done{color:var(--muted)}
  .rbk-ch.rbk-on{color:#fff;border-color:rgba(91,195,249,.35);background:rgba(91,195,249,.07)}
  .rbk-ch.rbk-on .rbk-pg{color:var(--cyan)}
  .rbk-ch:hover{color:#fff}

  /* ---- 3D book ---- */
  .rbk-stage{position:relative;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;perspective:1700px}
  .rbk-book{position:relative;height:min(58vh,520px);aspect-ratio:1.554;transform-style:preserve-3d;
    transform:rotateX(calc(var(--tx,0)*1deg)) rotateY(calc(var(--ty,0)*1deg));
    cursor:grab;user-select:none;-webkit-user-select:none}
  .rbk-book img{-webkit-user-drag:none}
  .rbk-book .rbk-shadow{position:absolute;left:2%;right:2%;bottom:-8%;height:11%;border-radius:50%;background:radial-gradient(ellipse,rgba(0,0,0,.78),transparent 70%);filter:blur(7px)}
  .rbk-half{position:absolute;top:0;bottom:0;width:50%}
  .rbk-half.rbk-l{left:0}.rbk-half.rbk-r{left:50%}
  /* page edge stacks (book thickness) */
  .rbk-edge{position:absolute;top:1.2%;bottom:1.2%;width:9px;background:repeating-linear-gradient(90deg,#cfd6e2 0 1px,#96a0b2 1px 2px);opacity:0}
  .rbk-edge.rbk-r{left:100%;border-radius:0 3px 3px 0;transform-origin:left;opacity:var(--eo,0)}
  .rbk-edge.rbk-l{right:100%;border-radius:3px 0 0 3px;transform-origin:right;opacity:var(--el,0)}
  .rbk-base{position:absolute;inset:0;border-radius:0 10px 10px 0;overflow:hidden;background:#0a0d13;box-shadow:0 30px 70px rgba(0,0,0,.55)}
  .rbk-base img{width:100%;height:100%;object-fit:cover}
  .rbk-base::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(0,0,0,.42),transparent 14%)}
  .rbk-backboard{position:absolute;inset:0;border-radius:10px 0 0 10px;overflow:hidden;background:#0a0d13;box-shadow:0 30px 70px rgba(0,0,0,.55);opacity:var(--bb,0)}
  .rbk-backboard::after{content:"";position:absolute;inset:0;background:linear-gradient(-90deg,rgba(0,0,0,.42),transparent 14%)}
  .rbk-sheet{position:absolute;left:50%;top:0;bottom:0;width:50%;transform-origin:left center;transform-style:preserve-3d;
    transform:rotateY(calc(var(--f,0) * -180deg))}
  .rbk-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;overflow:hidden;background:#0a0d13}
  .rbk-face.rbk-fr{border-radius:0 10px 10px 0}
  .rbk-face.rbk-bk2{transform:rotateY(180deg);border-radius:10px 0 0 10px;display:flex;align-items:center;justify-content:center}
  .rbk-face img{width:100%;height:100%;object-fit:cover}
  .rbk-face.rbk-fr::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(0,0,0,.42),transparent 14%),
    linear-gradient(-80deg,rgba(255,255,255,calc(var(--gl,0)*.14)),transparent 46%)}
  .rbk-face.rbk-bk2::after{content:"";position:absolute;inset:0;background:linear-gradient(-90deg,rgba(0,0,0,.45),transparent 16%)}
  .rbk-face.rbk-bk2 .rbk-bkin{text-align:center;padding:20px}
  .rbk-face.rbk-bk2 .rbk-bkin .rbk-lg{font-family:var(--disp);font-weight:900;font-size:15px;letter-spacing:.2em;color:rgba(148,175,214,.4)}
  .rbk-face.rbk-bk2 .rbk-bkin .rbk-cap{font-family:var(--mono);font-size:9px;letter-spacing:.22em;color:rgba(148,175,214,.55);margin-top:9px}
  .rbk-face.rbk-bk2{background:
    radial-gradient(60% 60% at 50% 40%,rgba(91,157,255,.06),transparent 70%),
    linear-gradient(180deg,#0d1420,#080d16)}
  .rbk-spine{position:absolute;left:calc(50% - 2px);top:1%;bottom:1%;width:4px;background:linear-gradient(180deg,#1a2230,#0b101a);border-radius:2px;opacity:var(--bb,0)}
  .rbk-morep{position:absolute;left:50%;bottom:6%;transform:translate(-50%,10px);z-index:60;font-family:var(--mono);font-size:10px;letter-spacing:.18em;color:#fff;
    background:rgba(4,7,13,.78);border:1px solid rgba(91,195,249,.4);border-radius:999px;padding:10px 16px;backdrop-filter:blur(8px);opacity:0;transition:opacity .5s ease,transform .5s ease}
  .rbk-morep b{color:var(--cyan);font-weight:700}
  .rbk-morep.rbk-in{opacity:1;transform:translate(-50%,0)}

  /* ---- mobile swipe strip (hidden on desktop; the static <=720px mode) ---- */
  .rbk-mstrip{display:none}

  /* The bottom bar (drag scrubber, page counter, price, CTA and the "small
     sample" link) and the gold "small sample" notice were removed on 2026-09-17
     (owner). Their styles went with them; static/js/racing_book_cinematic.js lost
     the matching reads in the same change, because pagect/scrubln were written on
     every animation frame and #rbk-scrub was read at module scope. */

  @media (prefers-reduced-motion: reduce){ .rbk-morep{transition:none}}

  @media (max-width: 1024px){
    .rbk-mid{grid-template-columns:1fr}
    .rbk-toc{display:none}
    .rbk-head .rbk-chips{display:none}}
  @media (max-height: 700px){
    .rbk .rbk-stick{gap:1.4vh;padding:calc(1vh + 64px) 5vw 3vh}
    .rbk-head .rbk-sub{display:none}
    .rbk-book{height:min(52vh,460px)}}

  /* ===== <=720px: normal NON-pinned experience (owner's #438 decision — the
     pinned 3D scrub is laggy on phones). Static head + native swipe page
     strip + CTA; the 3D stage, chapter rail and scrubber are desktop-only.
     LAST block on purpose: source order beats the pinned rules above. ===== */
  @media (max-width: 720px){
    .rbk{height:auto}
    .rbk .rbk-stick{position:relative;height:auto;overflow:visible;padding:44px 4vw 40px;gap:18px}
    .rbk-head h2{font-size:clamp(21px,6.4vw,30px)}
    .rbk-mid{display:none}
    .rbk-mstrip{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
      padding:6px 2px 14px;scrollbar-width:none}
    .rbk-mstrip::-webkit-scrollbar{display:none}
    .rbk-mstrip img{flex:0 0 70vw;max-width:320px;aspect-ratio:773/1000;object-fit:cover;scroll-snap-align:center;
      border-radius:10px;border:1px solid var(--line);box-shadow:0 18px 40px rgba(0,0,0,.5)}}

/* ============================================================================
   partials/tools_included.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
/* ============ .tlx — "Our Professional Courses". One section, ordinary scrolling. ============ */
.tlx{
  /* --disp is here for .tlx-cta ONLY, which is the Ask A Coach button copied value
     for value and that button is Orbitron (.akc --disp). Nothing else in this band
     is a display face: the headline is Inter 900 on the owner's 2026-09-17 ask. A
     rule that reaches for var(--disp) without this line does not fall back to the
     body font, it drops the whole font-family declaration. */
  --disp:'Orbitron',sans-serif;
  --body:'Inter',system-ui,sans-serif; --mono:'JetBrains Mono',ui-monospace,monospace;
  --bg:#04070d; --ink:#fff; --muted:#a7b6cd; --faint:#7b8aa2;
  --cyan:#5BC3F9;
  --line:rgba(148,175,214,.16);
  position:relative;isolation:isolate;width:100%;background:var(--bg);color:var(--ink);
  font-family:var(--body);-webkit-font-smoothing:antialiased;overflow:hidden}
.tlx *{margin:0;padding:0;box-sizing:border-box}
.tlx img{display:block;max-width:100%}

/* Full-bleed backdrop on a real 100%-wide element, NOT a 100vw pseudo-element:
   100vw includes the scrollbar and overflows the page by its width. */
.tlx-bg{position:absolute;inset:0;z-index:0}
.tlx-bg img{width:100%;height:100%;object-fit:cover;object-position:50% 62%}
/* ---- SEAM BLEND (owner 2026-09-17) ----
   The racing book, this band and the tools band all use the SAME photograph, but each
   crops and positions it independently, so where two of them meet the image jumped -
   a visible horizontal seam straight across the page.
   The overlay above already darkens the edges to ~88%, and that last 12% is exactly
   what showed the cut. Rather than push it to 100% (which would flatten the whole
   photo), the image itself is masked away at the top and bottom: it fades to nothing
   over the outer ~14%, leaving each band's own flat ground at the boundary. Two
   adjacent bands therefore meet on identical flat colour and the join disappears.
   A blur would have to be baked into the asset or cost a filter on a full-bleed layer
   every frame; a mask is free and composites on the GPU.
   -webkit- first for older WebKit, which still needs the prefix for mask-image. */
.tlx-bg img{
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 14%,#000 86%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 14%,#000 86%,transparent 100%)}

/* THREE LAYERS, and the order is the point (first listed sits on top) — copied
   value-for-value from .rbk-bg-track::after so this band and the Racing Book
   above it carry the identical blue cast the owner approved on 2026-09-17. The
   photograph is a sunset track whose warm mid-band would otherwise read as a
   different palette from the navy page; the blue wash goes UNDER the dark
   gradient so it tints hardest exactly where the dark layer is thinnest. If the
   book's values change, change these with them. */
.tlx-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(180deg,rgba(4,7,13,.88) 0%,rgba(4,7,13,.55) 34%,rgba(4,7,13,.34) 62%,rgba(4,7,13,.86) 100%),
  linear-gradient(180deg,rgba(64,132,224,.16) 0%,rgba(64,132,224,.30) 58%,rgba(64,132,224,.18) 100%),
  radial-gradient(1000px 560px at 74% 20%,rgba(91,157,255,.07),transparent 60%)}

/* Gutter on the OUTER element, centred 1280 box inside - the same arrangement as
   .rbk-stick (5vw) + .rbk-head (max-width:1280;margin:0 auto) in the racing book.
   The gutter used to sit inside the 1280 box, which indented this headline 48px
   right of the book's at 1440 and made the two bands look misaligned. */
.tlx{padding-left:5vw;padding-right:5vw}
.tlx-in{position:relative;z-index:2;width:100%;max-width:1280px;margin:0 auto;
  padding:clamp(40px,6vh,80px) 0 clamp(40px,6vh,80px)}

/* ---- head: same face as .rbk-head h2 (Inter 900, .025em, accent line #5BC3F9). ---- */
.tlx-head{margin-bottom:clamp(22px,3vh,38px)}
.tlx-head h2{font-family:var(--body);font-weight:900;font-size:clamp(30px,4vw,62px);
  line-height:1.06;letter-spacing:.025em;text-transform:none;text-wrap:balance}
.tlx-head h2 .tlx-g{color:var(--cyan)}
.tlx-sub{color:#b4c1d4;font-size:clamp(15px,1.3vw,21px);line-height:1.45;margin-top:clamp(8px,1vw,14px);max-width:60ch}

/* ---- the four thumbnails + the counted remainder. ONE tree, reflowed by column
   count only. The "+ N other courses inside" line is `--body` DELIBERATELY: it is a
   sentence, not a button, and this band wears the same Inter face as the Racing Book
   headline it sits under (the book dropped Orbitron for Inter on 2026-09-17). It was
   written as var(--disp) while the token block defined no display font, which does
   not fall back to the body font - it drops the declaration. ---- */
.tlx-more{margin-top:clamp(16px,2vh,24px);font-family:var(--body);font-weight:700;font-size:12.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--cyan)}
.tlx-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.5vw,20px)}
/* THE WHOLE CARD IS A SOLID PANEL (owner 2026-09-17). The title and lesson count used
   to sit straight on the track photograph with nothing behind them, and against a
   bright kerb or a white car they were close to unreadable. A text-shadow would have
   been a patch that still fails over the brightest part of the image; an opaque card
   fixes it everywhere and matches how the driver-story and drill cards on this page
   already work (#0A0E15 is the same --dst-card value).
   The card is a flex column so the covers stay aligned even when a title wraps to two
   lines - "Complete Driving Technique - Foundations" does at this width. */
/* The card is a DIV, not a link (owner 2026-09-17: clicking a tool should enlarge
   its screenshot, not walk the reader out of the page to the apply form). The click
   target is .tlx-zoom, a button stretched over the whole card - which is why the
   card is position:relative. It is a <button> and not an <a href="#"> because it
   navigates nowhere, and the card cannot itself be the button: <button> takes
   phrasing content only, and there is an <h3> in here. */
.tlx-card{position:relative;display:flex;flex-direction:column;color:inherit;
  background:#0A0E15;border:1px solid var(--line);border-radius:12px;overflow:hidden;
  box-shadow:0 14px 30px rgba(0,0,0,.45);
  transition:border-color .25s ease,transform .25s ease,box-shadow .25s ease}
.tlx-card:hover{border-color:rgba(91,195,249,.45);transform:translateY(-2px);
  box-shadow:0 18px 38px rgba(0,0,0,.55)}
/* Empty, labelled, and over everything: the whole card stays the hit area it was as
   a link, and the focus ring is drawn inside so it is not clipped by the card's
   overflow:hidden. zoom-in says what the click does before it happens. */
.tlx-zoom{position:absolute;inset:0;z-index:2;border:0;padding:0;background:none;cursor:zoom-in;
  -webkit-appearance:none;appearance:none}
.tlx-zoom:focus-visible{outline:2px solid var(--cyan);outline-offset:-3px;border-radius:12px}

/* ---- the enlarged screenshot ----
   A real <dialog>, so Escape, the top layer, focus trapping and inertness behind it
   all come from the platform rather than from this file. */
.tlx-lb{border:0;padding:0;background:none;max-width:none;max-height:none;width:100%;height:100%;
  color:var(--ink);overflow:hidden}
.tlx-lb::backdrop{background:rgba(3,6,12,.86);backdrop-filter:blur(6px)}
.tlx-lb-in{width:100%;height:100%;display:grid;place-items:center;padding:clamp(16px,4vw,52px)}
.tlx-lb figure{max-width:100%;display:flex;flex-direction:column;gap:12px;align-items:center}
.tlx-lb img{display:block;max-width:min(1600px,92vw);max-height:80vh;width:auto;height:auto;
  border-radius:12px;border:1px solid rgba(91,195,249,.34);box-shadow:0 40px 110px rgba(0,0,0,.7)}
.tlx-lb figcaption{font-family:var(--disp,inherit);font-weight:700;font-size:13px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cyan)}
.tlx-lb-x{position:absolute;top:clamp(10px,2vw,20px);right:clamp(10px,2vw,20px);width:42px;height:42px;
  display:grid;place-items:center;border-radius:50%;cursor:pointer;font-size:22px;line-height:1;
  color:var(--ink);background:rgba(10,14,21,.8);border:1px solid var(--line-2);
  transition:border-color .2s ease,background .2s ease}
.tlx-lb-x:hover{background:rgba(16,24,38,.92);border-color:rgba(91,195,249,.5)}
.tlx-lb-x:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.tlx-shot{display:block;position:relative;aspect-ratio:16/9;overflow:hidden;background:#0a0d13}
.tlx-shot img{width:100%;height:100%;object-fit:cover}
.tlx-body{display:flex;flex-direction:column;gap:8px;padding:clamp(14px,1.3vw,20px) clamp(14px,1.3vw,20px) clamp(16px,1.5vw,22px);flex:1}
.tlx-t{font-size:clamp(16px,1.35vw,21px);font-weight:800;line-height:1.25;letter-spacing:-.015em;color:var(--ink);
  text-wrap:balance}
/* Body face, sentence case (owner 2026-09-17). This inherited the courses band's
   mono-uppercase stat treatment, which is right for "68 LESSONS" and wrong for a
   sentence - it read as a label rather than a description. Set like the weekly loop's
   old coach reply (.wkl-reply p, removed in the 2026-09-26 rebuild): --body, normal
   case, 1.5 line-height. */
.tlx-meta{display:block;font-family:var(--body);font-size:clamp(13.5px,1.1vw,17px);line-height:1.5;
  letter-spacing:0;color:var(--muted);text-transform:none;text-wrap:pretty}

/* ---- one CTA, the page's shared destination. ---- */
/* LEFT, not centred (owner 2026-09-17): the band's headline, the course covers and
   the "+ N other courses inside" line all start on the same left edge, and a centred
   button was the only thing floating away from it. */
.tlx-foot{display:flex;align-items:center;justify-content:flex-start;gap:16px;flex-wrap:wrap;
  margin-top:clamp(22px,3vh,36px)}
/* The courses band's button and price line, value for value (owner's mocks,
   2026-09-26): sentence case, the price beside it. */
.tlx-foot{gap:clamp(16px,1.8vw,26px)}
.tlx-cta{display:inline-flex;align-items:center;justify-content:center;min-height:54px;font-family:var(--body);font-weight:700;
  font-size:clamp(16px,1.2vw,19px);letter-spacing:0;color:#fff;text-decoration:none;
  background:linear-gradient(180deg,#e21429,#b00f20);padding:14px clamp(24px,2vw,34px);border-radius:10px;
  box-shadow:0 14px 32px rgba(226,20,41,.4), inset 0 1px 0 rgba(255,255,255,.22);
  transition:transform .2s ease,filter .2s ease}
.tlx-cta:hover{color:#fff;transform:translateY(-2px);filter:brightness(1.08)}
.tlx-price{display:flex;flex-direction:column;gap:4px}
.tlx-price b{font-size:clamp(20px,1.7vw,27px);font-weight:700;line-height:1.1;color:var(--ink);letter-spacing:-.01em}
.tlx-pnote{font-size:clamp(13px,1vw,15.5px);color:var(--muted)}
.tlx-note{font-size:12.5px;color:var(--muted)}

@media (max-width: 1100px){ .tlx-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width: 760px){
  .tlx-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tlx-head h2{font-size:clamp(26px,7.4vw,34px)}
  .tlx-head{margin-bottom:18px}
  .tlx-t{font-size:15px}
  .tlx-meta{font-size:13.5px}
  .tlx-body{padding:12px 12px 14px;gap:6px}}

@media (prefers-reduced-motion: reduce){
  .tlx-card,.tlx-cta{transition:none}
  .tlx-card:hover,.tlx-cta:hover{transform:none}
  .tlx-lb::backdrop{backdrop-filter:none}}

/* ============================================================================
   partials/courses_included.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
/* ============ .cix — "Our Professional Courses". One section, ordinary scrolling. ============ */
.cix{
  /* --disp is here for .cix-cta ONLY, which is the Ask A Coach button copied value
     for value and that button is Orbitron (.akc --disp). Nothing else in this band
     is a display face: the headline is Inter 900 on the owner's 2026-09-17 ask. A
     rule that reaches for var(--disp) without this line does not fall back to the
     body font, it drops the whole font-family declaration. */
  --disp:'Orbitron',sans-serif;
  --body:'Inter',system-ui,sans-serif; --mono:'JetBrains Mono',ui-monospace,monospace;
  --bg:#04070d; --ink:#fff; --muted:#a7b6cd; --faint:#7b8aa2;
  --cyan:#5BC3F9;
  --line:rgba(148,175,214,.16);
  position:relative;isolation:isolate;width:100%;background:var(--bg);color:var(--ink);
  font-family:var(--body);-webkit-font-smoothing:antialiased;overflow:hidden}
.cix *{margin:0;padding:0;box-sizing:border-box}
.cix img{display:block;max-width:100%}

/* Full-bleed backdrop on a real 100%-wide element, NOT a 100vw pseudo-element:
   100vw includes the scrollbar and overflows the page by its width. */
.cix-bg{position:absolute;inset:0;z-index:0}
.cix-bg img{width:100%;height:100%;object-fit:cover;object-position:50% 62%}
/* ---- SEAM BLEND (owner 2026-09-17) ----
   The racing book, this band and the tools band all use the SAME photograph, but each
   crops and positions it independently, so where two of them meet the image jumped -
   a visible horizontal seam straight across the page.
   The overlay above already darkens the edges to ~88%, and that last 12% is exactly
   what showed the cut. Rather than push it to 100% (which would flatten the whole
   photo), the image itself is masked away at the top and bottom: it fades to nothing
   over the outer ~14%, leaving each band's own flat ground at the boundary. Two
   adjacent bands therefore meet on identical flat colour and the join disappears.
   A blur would have to be baked into the asset or cost a filter on a full-bleed layer
   every frame; a mask is free and composites on the GPU.
   -webkit- first for older WebKit, which still needs the prefix for mask-image. */
.cix-bg img{
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 14%,#000 86%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 14%,#000 86%,transparent 100%)}

/* THREE LAYERS, and the order is the point (first listed sits on top) — copied
   value-for-value from .rbk-bg-track::after so this band and the Racing Book
   above it carry the identical blue cast the owner approved on 2026-09-17. The
   photograph is a sunset track whose warm mid-band would otherwise read as a
   different palette from the navy page; the blue wash goes UNDER the dark
   gradient so it tints hardest exactly where the dark layer is thinnest. If the
   book's values change, change these with them. */
.cix-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(180deg,rgba(4,7,13,.88) 0%,rgba(4,7,13,.55) 34%,rgba(4,7,13,.34) 62%,rgba(4,7,13,.86) 100%),
  linear-gradient(180deg,rgba(64,132,224,.16) 0%,rgba(64,132,224,.30) 58%,rgba(64,132,224,.18) 100%),
  radial-gradient(1000px 560px at 74% 20%,rgba(91,157,255,.07),transparent 60%)}

/* Gutter on the OUTER element, centred 1280 box inside - the same arrangement as
   .rbk-stick (5vw) + .rbk-head (max-width:1280;margin:0 auto) in the racing book.
   The gutter used to sit inside the 1280 box, which indented this headline 48px
   right of the book's at 1440 and made the two bands look misaligned. */
.cix{padding-left:5vw;padding-right:5vw}
.cix-in{position:relative;z-index:2;width:100%;max-width:1280px;margin:0 auto;
  padding:clamp(40px,6vh,80px) 0 clamp(40px,6vh,80px)}

/* ---- head: same face as .rbk-head h2 (Inter 900, .025em, accent line #5BC3F9). ---- */
.cix-head{margin-bottom:clamp(22px,3vh,38px)}
.cix-head h2{font-family:var(--body);font-weight:900;font-size:clamp(30px,4vw,62px);
  line-height:1.06;letter-spacing:.025em;text-transform:none;text-wrap:balance}
.cix-head h2 .cix-g{color:var(--cyan)}
.cix-sub{color:#b4c1d4;font-size:clamp(15px,1.3vw,21px);line-height:1.45;margin-top:clamp(8px,1vw,14px);max-width:60ch}

/* ---- the four thumbnails + the counted remainder. ONE tree, reflowed by column
   count only. The "+ N other courses inside" line is `--body` DELIBERATELY: it is a
   sentence, not a button, and this band wears the same Inter face as the Racing Book
   headline it sits under (the book dropped Orbitron for Inter on 2026-09-17). It was
   written as var(--disp) while the token block defined no display font, which does
   not fall back to the body font - it drops the declaration. ---- */
.cix-more{margin-top:clamp(16px,2vh,24px);font-family:var(--body);font-weight:700;font-size:12.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--cyan)}
.cix-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.5vw,20px)}
/* THE WHOLE CARD IS A SOLID PANEL (owner 2026-09-17). The title and lesson count used
   to sit straight on the track photograph with nothing behind them, and against a
   bright kerb or a white car they were close to unreadable. A text-shadow would have
   been a patch that still fails over the brightest part of the image; an opaque card
   fixes it everywhere and matches how the driver-story and drill cards on this page
   already work (#0A0E15 is the same --dst-card value).
   The card is a flex column so the covers stay aligned even when a title wraps to two
   lines - "Complete Driving Technique - Foundations" does at this width. */
.cix-card{display:flex;flex-direction:column;text-decoration:none;color:inherit;cursor:pointer;
  background:#0A0E15;border:1px solid var(--line);border-radius:12px;overflow:hidden;
  box-shadow:0 14px 30px rgba(0,0,0,.45);
  transition:border-color .25s ease,transform .25s ease,box-shadow .25s ease}
.cix-card:hover{border-color:rgba(91,195,249,.45);transform:translateY(-2px);
  box-shadow:0 18px 38px rgba(0,0,0,.55)}
.cix-card:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.cix-shot{display:block;position:relative;aspect-ratio:16/9;overflow:hidden;background:#0a0d13}
.cix-shot img{width:100%;height:100%;object-fit:cover}
.cix-body{display:flex;flex-direction:column;gap:10px;padding:clamp(14px,1.3vw,20px) clamp(14px,1.3vw,20px) clamp(16px,1.5vw,22px);flex:1}
.cix-t{font-size:clamp(15px,1.25vw,19px);font-weight:700;line-height:1.28;letter-spacing:-.01em;color:var(--ink);
  text-wrap:balance}
.cix-meta{font-family:var(--body);font-weight:600;font-size:clamp(11px,.85vw,12.5px);
  letter-spacing:.14em;color:var(--muted);text-transform:uppercase;margin-top:auto}

/* ---- one CTA, the page's shared destination. ---- */
/* LEFT, not centred (owner 2026-09-17): the band's headline, the course covers and
   the "+ N other courses inside" line all start on the same left edge, and a centred
   button was the only thing floating away from it. */
.cix-foot{display:flex;align-items:center;justify-content:flex-start;gap:16px;flex-wrap:wrap;
  margin-top:clamp(22px,3vh,36px)}
/* The red of the Ask A Coach button (.akc-btn), in sentence case as the owner's mock
   draws it (2026-09-26) rather than that button's tracked Orbitron caps. */
.cix-foot{gap:clamp(16px,1.8vw,26px)}
.cix-cta{display:inline-flex;align-items:center;justify-content:center;min-height:54px;font-family:var(--body);font-weight:700;
  font-size:clamp(16px,1.2vw,19px);letter-spacing:0;color:#fff;text-decoration:none;
  background:linear-gradient(180deg,#e21429,#b00f20);padding:14px clamp(24px,2vw,34px);border-radius:10px;
  box-shadow:0 14px 32px rgba(226,20,41,.4), inset 0 1px 0 rgba(255,255,255,.22);
  transition:transform .2s ease,filter .2s ease}
.cix-cta:hover{color:#fff;transform:translateY(-2px);filter:brightness(1.08)}
.cix-price{display:flex;flex-direction:column;gap:4px}
.cix-price b{font-size:clamp(20px,1.7vw,27px);font-weight:700;line-height:1.1;color:var(--ink);letter-spacing:-.01em}
.cix-pnote{font-size:clamp(13px,1vw,15.5px);color:var(--muted)}
.cix-note{font-size:12.5px;color:var(--muted)}

@media (max-width: 1100px){ .cix-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width: 760px){
  .cix-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cix-head h2{font-size:clamp(26px,7.4vw,34px)}
  .cix-head{margin-bottom:18px}
  .cix-t{font-size:14px}
  .cix-body{padding:12px 12px 14px;gap:8px}}

@media (prefers-reduced-motion: reduce){
  .cix-card,.cix-cta{transition:none}
  .cix-card:hover,.cix-cta:hover{transform:none}}

/* ============================================================================
   partials/faq_split.html -- moved here from that partial's inline <style>
   (2026-09-22). It rendered inside the HTML on every visit; here it is
   cached, hashed and compressed once.
   ============================================================================ */
  .fqx{
    --disp:'Orbitron',sans-serif; --body:'Inter',sans-serif; --mono:'JetBrains Mono',monospace;
    --bg:#04070d; --ink:#fff; --lead:#d4ddec; --muted:#a7b6cd; --faint:#7b8aa2;
    --cyan:#5BC3F9; --blue:#5b9dff; --violet:#b98cff; --red:#e21429; --red-2:#b00f20; --green:#34d399; --gold:#F5B041;
    --line:rgba(148,175,214,.16); --glass:rgba(8,14,26,.72);
    --grad:linear-gradient(96deg,var(--cyan) 4%,var(--violet) 48%,var(--red) 96%);
  }
  .fqx, .fqx *{margin:0;padding:0;box-sizing:border-box}
  .fqx{color:var(--ink);font-family:var(--body)}
  :where(.fqx) a{color:var(--cyan);text-decoration:none}
  :where(.fqx) a:hover{color:#fff}

  .fqx{position:relative;padding:11vh 6vw 6vh;overflow:hidden;
    background:
      radial-gradient(900px 520px at 16% 18%,rgba(91,157,255,.08),transparent 60%),
      radial-gradient(760px 480px at 90% 88%,rgba(185,140,255,.06),transparent 60%),var(--bg)}
  .fqx-grid-ov{position:absolute;inset:0;pointer-events:none;opacity:.38;
    background:linear-gradient(rgba(148,175,214,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(148,175,214,.05) 1px,transparent 1px);
    background-size:58px 58px;-webkit-mask-image:radial-gradient(circle at 30% 40%,black,transparent 74%);mask-image:radial-gradient(circle at 30% 40%,black,transparent 74%)}
  .fqx-wrap{position:relative;max-width:1240px;margin:0 auto}

  .fqx-head{margin-bottom:26px}
  .fqx-head .fqx-sub{color:var(--muted);font-size:14px;margin-top:10px}
  .fqx-pill{display:inline-flex;align-items:center;gap:8px;font-family:var(--disp);font-weight:700;font-size:10px;letter-spacing:.28em;color:var(--cyan);
    border:1px solid rgba(91,195,249,.42);border-radius:999px;padding:9px 16px;background:rgba(91,195,249,.06)}
  .fqx-pill i{width:6px;height:6px;border-radius:50%;background:var(--cyan);animation:fqxPulse 1.9s ease infinite;font-style:normal}
  @keyframes fqxPulse{0%,100%{opacity:1}50%{opacity:.25}}
  .fqx h2{font-family:var(--disp);font-weight:900;font-size:clamp(26px,3.2vw,44px);line-height:1.08;margin-top:14px}
  /* Solid #5BC3F9, matching every other section headline accent on this page (owner
     2026-09-17). It ran --grad, the cyan -> violet -> red sweep, which is why
     "wondering?" faded through purple into red. --grad is still used by the answer
     panel's top rule below, so the token stays. */
  .fqx h2 .fqx-g{color:var(--cyan)}

  .fqx-qgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px 24px;align-items:start}
  .fqx-qs{display:flex;flex-direction:column;gap:10px}
  .fqx-q{appearance:none;background:rgba(7,12,23,.6);border:1px solid var(--line);border-radius:12px;cursor:pointer;text-align:left;color:var(--muted);
    display:flex;align-items:center;gap:14px;padding:14px 17px;font-family:var(--body);transition:all .25s ease;position:relative;overflow:hidden}
  .fqx-q .fqx-no{font-family:var(--body);font-weight:700;font-size:11.5px;letter-spacing:.04em;color:var(--cyan);width:24px;flex:0 0 auto}
  .fqx-q .fqx-tx{font-size:13.5px;font-weight:600;letter-spacing:.01em;line-height:1.4;color:var(--lead)}
  .fqx-q .fqx-arr{margin-left:auto;flex:0 0 auto;color:var(--cyan);font-size:17px;font-weight:400;line-height:1;transition:transform .25s ease}
  .fqx-q:hover{border-color:rgba(148,175,214,.36)}
  .fqx-q:hover .fqx-tx{color:#fff}
  .fqx-q.fqx-on{border-color:rgba(226,20,41,.55);background:rgba(91,157,255,.07)}
  .fqx-q.fqx-on .fqx-tx{color:#fff}
  .fqx-q:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}

  /* ---- answer panel (full width, below grid) ---- */
  .fqx-ans{position:relative;margin-top:22px;border-radius:16px;border:1px solid rgba(148,175,214,.28);background:var(--glass);
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 34px 80px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.07);
    padding:24px 28px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:20px 40px;align-items:center;overflow:hidden}
  .fqx-ans .fqx-topline{position:absolute;top:0;left:0;right:0;height:2px;background:var(--grad)}
  .fqx-ans .fqx-k{font-family:var(--body);font-weight:700;font-size:12px;letter-spacing:.08em;color:var(--cyan)}
  .fqx-ans h3{font-family:var(--disp);font-weight:800;font-size:clamp(17px,1.7vw,23px);line-height:1.3;margin-top:10px;
    opacity:0;transform:translateY(12px)}
  .fqx-ans p{color:var(--lead);font-size:14.5px;line-height:1.7;margin-top:12px;max-width:64ch;opacity:0;transform:translateY(12px)}
  .fqx-ans.fqx-swap h3,.fqx-ans.fqx-swap p{opacity:1;transform:none;transition:opacity .4s ease .05s,transform .4s cubic-bezier(.2,.7,.2,1) .05s}
  .fqx-ans.fqx-swap p{transition-delay:.12s}
  .fqx-ans .fqx-a[hidden]{display:none}
  .fqx-ans .fqx-side{display:flex;flex-direction:column;align-items:center;gap:12px}
  .fqx-ans .fqx-tagf{font-family:var(--body);font-weight:600;font-size:11px;color:var(--faint)}
  .fqx-ans .fqx-tagf b{color:var(--green)}
  .fqx-btn{font-family:var(--disp);font-weight:800;font-size:11.5px;letter-spacing:.13em;color:#fff;
    background:linear-gradient(180deg,var(--red),var(--red-2));padding:14px 26px;border-radius:10px;white-space:nowrap;
    box-shadow:0 12px 26px rgba(226,20,41,.38), inset 0 1px 0 rgba(255,255,255,.22);transition:transform .2s ease,filter .2s ease}
  .fqx-btn:hover{color:#fff;transform:translateY(-2px);filter:brightness(1.08)}
  /* Parked, the button carries the price (partials/_join_label.html): let it wrap
     on a phone instead of running off the screen. */
  @media (max-width: 640px){
    .fqx-btn:has(.join-lbl){white-space:normal;text-align:center;line-height:1.5}}

  @media (prefers-reduced-motion: reduce){
    .fqx-pill i{animation:none}
    .fqx-q,.fqx-q .fqx-arr,.fqx-ans h3,.fqx-ans p{transition:none}
    .fqx-ans h3,.fqx-ans p{opacity:1;transform:none}}
  @media (max-width: 900px){
    /* minmax(0,1fr), not 1fr: a bare 1fr track grows to its widest child's
       min-content, so one unbreakable button widened the whole FAQ past the
       screen edge (2026-09-26). */
    .fqx-qgrid{grid-template-columns:minmax(0,1fr)}
    .fqx-ans{grid-template-columns:minmax(0,1fr)}
    .fqx-ans .fqx-side{align-items:flex-start}
    /* the JS moves the panel directly below the active question here — the
       column's own gap provides the spacing */
    .fqx-qs .fqx-ans{margin-top:2px}}