/* ==========================================================================
   Lyrixsa AI — JV / Affiliate Recruitment Page
   Design tokens mirror the Lyrixsa AI sales page so the two read as one brand.
   ========================================================================== */

:root{
  /* Surfaces — same ladder as the sales page */
  --bg:#101114; --s1:#17181D; --s2:#1E2026; --s3:#262930;
  --border:#2A2D35; --border-strong:#3A3E48;

  /* Ink */
  --t1:#EDEDEC; --t2:#9B9FA8; --t3:#63666F;

  /* Accent */
  --accent:#F2A93C;
  --accent-soft:rgba(242,169,60,.12);
  --accent-border:rgba(242,169,60,.55);
  --ink-on-accent:#1A1300;

  /* Semantic */
  --success:#7FD9A8; --success-soft:rgba(127,217,168,.12);
  --danger:#E8735F;  --danger-soft:rgba(232,115,95,.12);
  --info:#7FB2D9;    --info-soft:rgba(127,178,217,.12);
  --fast:#B79CE8;    --fast-soft:rgba(183,156,232,.12);

  /* Certificate palette, carried over for the license section */
  --cert-bg:#0B0B0D; --cert-gold:#C9A24B; --cert-ink:#F1F0ED;
  --cert-label:#9A9A9E; --cert-rule:#2A2A2E;

  /* Type */
  --sans:'Inter',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  --display:'Space Grotesk','Inter',sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --emoji:'Apple Color Emoji','Segoe UI Emoji','Noto Color Emoji','Twemoji Mozilla','Segoe UI Symbol',sans-serif;

  /* Rhythm */
  --wrap:1180px; --wrap-narrow:820px;
  --r-sm:8px; --r:12px; --r-lg:18px; --r-xl:26px;
  --head-h:64px;
}

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

html{scroll-behavior:smooth; scroll-padding-top:calc(var(--head-h) + 16px); -webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}

body{
  margin:0; background:var(--bg); color:var(--t1);
  font:400 16px/1.65 var(--sans);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
body.is-locked{overflow:hidden}

img,svg,video{max-width:100%;height:auto;display:block}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit;color:inherit}

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

.wrap{width:100%;max-width:var(--wrap);margin:0 auto;padding:0 24px}
.wrap-narrow{max-width:var(--wrap-narrow)}
@media(max-width:640px){.wrap{padding:0 18px}}

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

/* ---------------------------------------------------------------- skip link */
.skip{position:absolute;left:12px;top:-60px;z-index:200;background:var(--accent);color:var(--ink-on-accent);
  padding:10px 16px;border-radius:var(--r-sm);font-weight:700;transition:top .18s}
.skip:focus{top:12px;text-decoration:none}

/* ==========================================================================
   HEADER
   ========================================================================== */
.site-head{
  position:sticky;top:0;z-index:90;
  background:rgba(16,17,20,.86);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border-bottom:1px solid var(--border);
}
.head-row{display:flex;align-items:center;gap:20px;height:var(--head-h)}
.brand{display:flex;align-items:center;gap:10px;flex:0 0 auto}
.brand img{height:30px;width:auto}
.brand-mark{font:700 18px/1 var(--display);letter-spacing:-.01em;color:var(--t1)}
.brand-tag{font:500 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--accent);
  border:1px solid var(--accent-border);background:var(--accent-soft);padding:4px 7px;border-radius:5px}

.nav{display:flex;align-items:center;gap:4px;margin-left:auto}
/* :not(.btn) matters — `.nav a` (0,1,1) outranks `.btn-primary` (0,1,0), so
   without it the nav's grey link colour wins over the button's dark ink and the
   gold CTA renders grey-on-gold at 1.33:1. It only looked right on :active
   because that state re-specified the colour. */
.nav a:not(.btn){
  font:500 13.5px/1 var(--sans);color:var(--t2);padding:9px 11px;border-radius:var(--r-sm);
  white-space:nowrap;transition:color .16s,background .16s;
}
.nav a:not(.btn):hover{color:var(--t1);background:var(--s2);text-decoration:none}
.nav a.ext::after{content:'↗';font-size:10px;margin-left:4px;opacity:.6}

/* The way back to the main JV page, highlighted on the subpages.
   Selector is (0,2,1) to match `.nav a:not(.btn)` and win on order — a bare
   `.nav a.nav-home` would tie and the grey would keep the colour.
   Chip treatment rather than a second gold fill: `.btn-primary` already owns the
   solid gold at the end of the row, and two filled golds read as two CTAs. */
.nav a.nav-home:not(.btn){
  color:var(--accent);background:var(--accent-soft);
  box-shadow:inset 0 0 0 1px var(--accent-border);
}
.nav a.nav-home:not(.btn):hover{color:var(--t1);background:var(--accent-soft)}

.nav-toggle{display:none;margin-left:auto;background:var(--s2);border:1px solid var(--border);
  color:var(--t1);width:42px;height:38px;border-radius:var(--r-sm);cursor:pointer;align-items:center;justify-content:center}
.nav-toggle span{display:block;width:17px;height:1.5px;background:currentColor;position:relative}
.nav-toggle span::before,.nav-toggle span::after{content:'';position:absolute;left:0;width:17px;height:1.5px;background:currentColor}
.nav-toggle span::before{top:-5px}.nav-toggle span::after{top:5px}

@media(max-width:1080px){
  .nav{
    position:fixed;inset:var(--head-h) 0 auto 0;flex-direction:column;align-items:stretch;gap:2px;
    background:var(--s1);border-bottom:1px solid var(--border);padding:14px 18px 20px;
    max-height:calc(100dvh - var(--head-h));overflow-y:auto;
    transform:translateY(-8px);opacity:0;pointer-events:none;transition:opacity .18s,transform .18s;
  }
  .nav.open{transform:none;opacity:1;pointer-events:auto}
  .nav a:not(.btn){padding:12px 10px;font-size:15px;border-bottom:1px solid var(--border)}
  .nav .btn{margin-top:12px;justify-content:center}
  .nav-toggle{display:flex}
}

/* ------------------------------------------------------------ countdown bar */
.cd-bar{
  background:linear-gradient(90deg,rgba(242,169,60,.14),rgba(242,169,60,.05) 60%,transparent);
  border-bottom:1px solid var(--border);
}
.cd-row{display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;padding:9px 0}
.cd-label{font:500 10.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--accent)}
.cd-clock{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-weight:500}
.cd-unit{display:flex;flex-direction:column;align-items:center;min-width:40px;
  background:var(--s2);border:1px solid var(--border);border-radius:6px;padding:4px 6px}
.cd-unit b{font-size:16px;line-height:1.1;color:var(--t1);font-weight:500;font-variant-numeric:tabular-nums}
.cd-unit i{font-style:normal;font-size:8.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
.cd-sep{color:var(--t3)}
.cd-note{font-size:12px;color:var(--t2)}
@media(max-width:640px){.cd-note{display:none}.cd-row{gap:10px}}

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font:600 14.5px/1 var(--sans);letter-spacing:.01em;
  padding:13px 22px;border-radius:10px;border:1px solid transparent;cursor:pointer;
  transition:transform .14s,box-shadow .16s,background .16s,border-color .16s;
  text-align:center;
}
.btn:hover{text-decoration:none;transform:translateY(-1px)}
.btn:active{transform:none}

.btn-primary{background:var(--accent);color:var(--ink-on-accent);box-shadow:0 4px 18px rgba(242,169,60,.22)}
.btn-primary:hover{background:#F7B754;box-shadow:0 7px 26px rgba(242,169,60,.3)}

.btn-ghost{background:var(--s2);color:var(--t1);border-color:var(--border-strong)}
.btn-ghost:hover{background:var(--s3);border-color:var(--accent-border)}

.btn-outline{background:transparent;color:var(--accent);border-color:var(--accent-border)}
.btn-outline:hover{background:var(--accent-soft)}

.btn-sm{padding:9px 15px;font-size:13px;border-radius:8px}
.btn-lg{padding:16px 30px;font-size:16px;border-radius:12px}
.btn-block{width:100%}
.head-row .btn{flex:0 0 auto}

.cta-pair{display:flex;flex-wrap:wrap;gap:12px}
.cta-pair.center{justify-content:center}

/* Two buttons sharing one row, each taking half of it. Needed because the pair's
   natural width (625px + gap) exceeds the step-2 column (502px), so flex-wrap
   stacked them — "side by side" is only possible if they stop being natural
   width. flex-basis:0 makes the split even regardless of label length.

   line-height goes to 1.3 because .btn assumes a single line at line-height:1,
   and these labels wrap to two; the padding drops to keep the button the same
   visual weight as the one-line buttons elsewhere on the page.

   Under 520px the basis is released and they stack again — at phone width half a
   track is ~160px, which would wrap each label to three lines.

   This rule was RETIRED for a while, when the two "Request … Approval →" buttons
   it exists for were collapsed into a single email CTA because the JVZoo product
   IDs did not exist yet. They do now (452965 front end, 452989 bundle), the two
   real marketplace links are back in section 01, and so is this. */
.cta-split .btn{flex:1 1 0;min-width:0;line-height:1.3;padding-top:11px;padding-bottom:11px}
@media(max-width:520px){
  .cta-split .btn{flex:1 1 100%}
}

/* Page-head section nav (swipes / assets / jv-doc). These rows carry one button
   per section — seven on assets.html — and at natural width flex-wrap leaves the
   last one alone on its own line: 6+1 at 768px on assets, 5+1 from 820px down on
   swipes. flex-grow makes wrapped items fill their line instead, so a broken row
   reads as a deliberate two-line block rather than a stub.

   Gap and padding tweaks were probed first and rejected — they move the
   breakpoint where the orphan appears without removing it, which looks fixed
   only on the width it was tuned on. Verified 1440 down to 360: every line
   fills its track, no label wraps to a second line.

   Scoped modifier, not a change to .cta-pair or .btn: both are used all over
   the site (four .cta-pair on index.html alone) and growing them globally would
   stretch the hero and final-CTA pairs to full width. */
.cta-nav .btn{flex:1 1 auto}

/* ==========================================================================
   SECTION SCAFFOLD
   ========================================================================== */
section{position:relative}
.sec{padding:84px 0;border-top:1px solid var(--border)}
.sec-alt{background:var(--s1)}
.sec-tight{padding:56px 0}
@media(max-width:640px){.sec{padding:60px 0}}

.eyebrow{
  display:inline-flex;align-items:center;gap:8px;
  font:500 10.5px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);margin:0 0 16px;
}
.eyebrow::before{content:'';width:22px;height:1px;background:var(--accent);opacity:.6}
.eyebrow.no-rule::before{display:none}

h1,h2,h3,h4{font-family:var(--display);font-weight:700;letter-spacing:-.02em;margin:0 0 14px;line-height:1.14}
h1{font-size:clamp(30px,5.2vw,52px)}
h2{font-size:clamp(25px,3.6vw,38px)}
h3{font-size:clamp(18px,2.1vw,22px);letter-spacing:-.01em}
h4{font-size:16px;letter-spacing:-.005em}

.lede{font-size:clamp(16px,1.5vw,18.5px);color:var(--t2);max-width:66ch;margin:0 0 26px;line-height:1.68}
.sec-head{margin-bottom:44px;max-width:74ch}
.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}
.sec-head.center .eyebrow{justify-content:center}
p{margin:0 0 16px}
p:last-child{margin-bottom:0}

.hr{height:1px;background:var(--border);border:0;margin:44px 0}

/* ------------------------------------------------------------------- chips */
.chip{
  display:inline-flex;align-items:center;gap:6px;
  font:500 10.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  padding:5px 9px;border-radius:5px;border:1px solid var(--border-strong);
  background:var(--s3);color:var(--t2);white-space:nowrap;
}
.chip-fe{border-color:rgba(127,217,168,.45);background:var(--success-soft);color:var(--success)}
.chip-bundle{border-color:var(--accent-border);background:var(--accent-soft);color:var(--accent)}
.chip-oto{border-color:rgba(127,178,217,.45);background:var(--info-soft);color:var(--info)}
.chip-tbc{border-color:rgba(232,115,95,.5);background:var(--danger-soft);color:var(--danger)}
/* FastPass is a standalone offer, not a step in the OTO sequence, so it cannot
   wear .chip-oto. Its own hue: green means front end / included, amber means
   the bundle, blue means the numbered OTO ladder and red means unconfirmed —
   all four already carry meaning on this page. */
.chip-fast{border-color:rgba(183,156,232,.45);background:var(--fast-soft);color:var(--fast)}
.chip-live{border-color:rgba(127,217,168,.45);background:var(--success-soft);color:var(--success)}
.chip-row{display:flex;flex-wrap:wrap;gap:8px}

/* TBC inline marker — everything the vendor still has to supply */
.tbc{
  display:inline-flex;align-items:center;gap:5px;
  font:500 11.5px/1 var(--mono);letter-spacing:.06em;
  color:var(--danger);background:var(--danger-soft);
  border:1px dashed rgba(232,115,95,.5);border-radius:5px;padding:4px 8px;white-space:nowrap;
}
.tbc::before{content:'▲';font-size:8px}

/* ==========================================================================
   HERO
   ========================================================================== */
.hero{
  position:relative;overflow:hidden;padding:70px 0 76px;border-top:0;
  background:
    radial-gradient(900px 460px at 78% -8%,rgba(242,169,60,.13),transparent 62%),
    radial-gradient(700px 400px at 6% 8%,rgba(127,178,217,.07),transparent 60%);
}
.hero::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(var(--border) 1px,transparent 1px),linear-gradient(90deg,var(--border) 1px,transparent 1px);
  background-size:64px 64px;opacity:.16;
  mask-image:radial-gradient(ellipse 78% 62% at 50% 34%,#000,transparent);
  -webkit-mask-image:radial-gradient(ellipse 78% 62% at 50% 34%,#000,transparent);
}
.hero > *{position:relative;z-index:1}
.hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:52px;align-items:start}
@media(max-width:980px){.hero-grid{grid-template-columns:1fr;gap:38px}}

/* ------------------------------------------------------------- hero headline */
/* Two beats in the h1 and a proof bar under it, replacing three same-weight
   sentences. The previous version ranged three lines left at one measure with the
   third stepped down in size; it read evenly but flat, because all three beats
   asked for the same amount of attention and the accent was spent entirely on
   the middle one — which left the payout clause reaching for an underline sweep
   as a third emphasis on a line that was already the least important of the three.
     Here the weight follows the argument. The setup drops to roughly half the
   display size in --t2 (it is a concession — every tool does make a song — and a
   concession set at 52px argues with itself). The payload keeps the full clamp
   and the accent, and is now the only full-size line, which is what lets its
   measure go out to 26ch without the stack looking ragged: at 19ch a 62-character
   sentence broke into four short lines.
     The old .h1-l1 / .h1-kick / .h1-kick-t classes and their nowrap and
   width:min-content machinery are gone with the markup they described. Nothing
   here is centred, shrink-wrapped, or holding a hand-tuned break: one left edge,
   every line, every width. */
.hero h1.hero-h1{
  margin:0 0 20px;line-height:1.06;text-wrap:balance;max-width:26ch;
  display:flex;flex-direction:column;gap:.3em;
}
/* Beat 1 in the payload's own typography, at the vendor's request: same family,
   same inherited size, sentence case, --t1. It was mono/uppercase/.34em/--t2 --
   a caption treatment, and the four costs of scaling a caption to 52px are
   measured in _dev/_apply_setup_match.py's docstring. Short version: mono caps at
   .1em tracking set this sentence on three lines against the h1's 26ch measure
   and added 186px to the hero; this sets it on two and adds 86px.
     600 rather than the h1's 700 -- measured identical in height and line count,
   so the hierarchy between a concession and the claim it sets up is free. The
   payload keeps var(--accent), which is now the only thing marking which of the
   two lines is the claim. */
.hero h1 .h1-setup{
  font:600 1em/1.06 var(--display);letter-spacing:-.02em;
  color:var(--t1);
}
/* The payload. Inherits the h1's clamp; em is reset to normal weight-for-weight
   as elsewhere in this stylesheet. */
.hero h1 .h1-payload{font-style:normal;color:var(--accent);display:block}

/* ---------------------------------------------------------- hero proof bar */
/* Beat 3, and the page's money summary in one row. It is a <p> outside the h1 on
   purpose: putting it inside meant a single heading 30 words long in the document
   outline and in every screen reader's heading list.
     The left accent rule replaces the underline sweep the old third beat used —
   same job (mark this as load-bearing without spending a second colour on the
   text) at a fraction of the visual noise, and it survives a line wrap, which the
   sweep could not.
     This is also where .hero-deck's two facts moved to. The deck sat between the
   DSP strip and the sub-paragraph and stated "You keep 50% flat"; with the proof
   bar also carrying a rate, the hero would have said 50% twice within three
   inches — the same fault the .hero-cta-note comment describes. One statement,
   with the funnel total added beside it. */
.hero-proof{
  margin:0 0 24px;padding:14px 0 14px 18px;
  border-left:3px solid var(--accent);
  display:flex;flex-direction:column;gap:7px;
  max-width:52ch;
}
.hero-proof .hp-claim{
  font:600 clamp(16px,1.75vw,20px)/1.35 var(--display);
  letter-spacing:-.015em;color:var(--t1);
}
/* Mono for the numbers, matching every other figure on the page. Wraps as a row
   rather than stacking, so at narrow widths it reflows into two or three lines
   instead of becoming a three-item list. */
.hero-proof .hp-money{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 7px;
  font-size:13px;color:var(--t2);
}
/* Each figure travels with its own label: .hp-m is the unit that wraps, so a
   number can never end up on a line with its label stranded beneath it. */
.hero-proof .hp-m{display:inline-flex;align-items:baseline;gap:5px;white-space:nowrap}
.hero-proof .hp-money b{
  font:600 15px/1 var(--mono);color:var(--accent);letter-spacing:-.01em;
}
.hero-proof .hp-money i{font-style:normal;color:var(--t3)}

@media(max-width:980px){
  /* Single column: the 26ch measure that kept the payload to three lines against
     a 621px track would hold it to a narrow ribbon across the full width. */
  .hero h1.hero-h1{max-width:32ch}
}
@media(max-width:560px){
  .hero h1.hero-h1{max-width:none;margin-bottom:18px;gap:.34em}
  /* No setup-size override here any more. The old one pinned the line to 11.5px
     because .34em of the clamp floor fell under 11px; at the payload's 1em there
     is no floor to guard, and this rule would now undo the vendor's change at the
     width where most affiliates read the page. */
  .hero-proof{padding:12px 0 12px 14px;border-left-width:2px}
}

.hero-sub{font-size:clamp(15.5px,1.6vw,18px);color:var(--t2);max-width:56ch;margin:0 0 28px;line-height:1.66}

.hero-facts{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 28px;padding:0;list-style:none}
.hero-facts li{
  display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--t1);
  background:var(--s2);border:1px solid var(--border);border-radius:8px;padding:9px 13px;
}
.hero-facts li b{color:var(--accent);font-weight:600;font-family:var(--mono);font-size:13px}

.hero-cta-note{font-size:12.5px;color:var(--t3);margin:14px 0 0}
/* -------------------------------------------------------- destination strip */
/* Sits between the headline and the money deck, so its margins are tighter than
   a normal block — it reads as part of the headline's evidence rather than as a
   separate paragraph. Icon set and order are lifted from the /publisher strip,
   which is the authoritative list. */
.hero-dsp{display:flex;align-items:center;flex-wrap:wrap;gap:8px 12px;margin:0 0 22px}
.hero-dsp-lbl{font:500 10px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--t3)}
/* Wraps, because twelve marks will not hold one row at the narrow end of the
   hero column. */
.hero-dsp-row{display:inline-flex;align-items:center;flex-wrap:wrap;gap:10px}
/* The source SVGs are solid white; dimming reads as brand-neutral next to the
   gold accent instead of competing with it. */
.hero-dsp-row img{width:21px;height:21px;display:block;opacity:.85;flex:0 0 auto;transition:opacity .18s}
.hero-dsp:hover .hero-dsp-row img{opacity:1}
.hero-dsp-mk{
  display:inline-flex;align-items:center;justify-content:center;
  width:21px;height:21px;border-radius:5px;
  background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);
  font:600 9px/1 var(--mono);letter-spacing:.02em;color:rgba(255,255,255,.82);
  flex:0 0 auto;
}
/* The "+" closes the row, so it reads as "and others" rather than a twelfth
   named service. */
.hero-dsp-mk.mk-plus{font-size:12px;color:rgba(255,255,255,.6)}
@media(max-width:560px){
  /* Label on its own line so the marks keep a full line to wrap into instead of
     being squeezed into the tail of the label. */
  .hero-dsp{gap:9px 10px}
  .hero-dsp-lbl{flex-basis:100%}
  .hero-dsp-row{gap:9px}
}

/* -------------------------------------------------------- launch window */
/* Timeline panel in the hero. Replaced the old .launch-card definition list:
   same five facts, but the two numbers a partner plans around (promo window,
   pre-launch runway) are set as figures instead of sitting in row four of a
   table, and the dates run down a spine so the order is readable at a glance. */
.lw{
  position:relative;isolation:isolate;
  background:
    radial-gradient(120% 80% at 100% 0,rgba(242,169,60,.10),transparent 58%),
    linear-gradient(180deg,var(--s2),var(--s1) 44%);
  border:1px solid var(--border-strong);border-radius:var(--r-xl);
  padding:26px 26px 22px;
  box-shadow:0 26px 60px rgba(0,0,0,.42),inset 0 1px 0 rgba(255,255,255,.035);
}
/* A lit rim along the top edge rather than a gold border on all four sides —
   inset from the corners so it reads as light falling on the card. */
.lw::before{
  content:'';position:absolute;left:26px;right:26px;top:-1px;height:1px;
  background:linear-gradient(90deg,transparent,var(--accent-border) 20%,var(--accent) 50%,var(--accent-border) 80%,transparent);
  opacity:.9;
}

.lw-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin-bottom:20px}
.lw-eyebrow{display:block;font:500 10px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;
  color:var(--t3);margin-bottom:10px}
/* h2 in the markup now, not h3: the hero's only heading above this is the h1, so
   h3 was a level skip for a screen reader walking the outline. The size is set
   here explicitly, so the global h2 rule doesn't apply. */
.lw-head h2{margin:0;font:600 26px/1 var(--display);letter-spacing:-.025em;color:var(--t1)}
.lw-head h2 span{color:var(--t3);font-weight:400}

.lw-phase{
  flex:none;display:inline-flex;align-items:center;gap:7px;
  font:500 9.5px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;white-space:nowrap;
  color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-border);
  padding:7px 11px;border-radius:999px;
}
.lw-phase i{width:5px;height:5px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px rgba(242,169,60,.2);animation:lw-pulse 2.4s ease-in-out infinite}
@keyframes lw-pulse{0%,100%{opacity:1}50%{opacity:.3}}
@media(prefers-reduced-motion:reduce){.lw-phase i{animation:none}}
/* set by initLaunchWindow once the cart has closed */
.lw.is-over .lw-phase{color:var(--t3);background:transparent;border-color:var(--border-strong)}
.lw.is-over .lw-phase i{background:var(--t3);box-shadow:none;animation:none}

.lw-figs{
  display:grid;grid-template-columns:1fr 1fr;gap:1px;margin-bottom:22px;
  background:var(--border);border:1px solid var(--border);border-radius:var(--r);overflow:hidden;
}
.lw-fig{background:rgba(0,0,0,.26);padding:14px 15px;display:flex;align-items:baseline;gap:11px}
.lw-fig-n{font:600 31px/1 var(--display);letter-spacing:-.035em;color:var(--accent);font-variant-numeric:tabular-nums}
.lw-fig-k{font:500 10.5px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--t2)}
.lw-fig-k small{display:block;margin-top:6px;font:400 11px/1.45 var(--sans);
  letter-spacing:0;text-transform:none;color:var(--t3)}

.lw-rail{list-style:none;margin:0;padding:0;position:relative}
/* Every row on the rail is a fixed date now — the webinar was the one TBC and it
   is scheduled — so the spine runs the full height between the first and last
   node instead of fading out short of an open-ended row. */
.lw-rail::before{
  content:'';position:absolute;left:5px;top:10px;bottom:10px;width:1px;
  background:linear-gradient(180deg,var(--accent-border),var(--border-strong) 70%,var(--border));
}
.lw-step{position:relative;padding:0 0 18px 27px}
.lw-step:last-child{padding-bottom:2px}
.lw-step::before{
  content:'';position:absolute;left:0;top:5px;width:11px;height:11px;border-radius:50%;
  background:var(--s1);border:2px solid var(--border-strong);
}
.lw-step.is-done::before{background:var(--accent);border-color:var(--accent);box-shadow:0 0 0 4px rgba(242,169,60,.13)}
.lw-step.is-next::before{border-color:var(--accent);box-shadow:0 0 0 4px rgba(242,169,60,.11)}

.lw-k{display:block;font:500 9.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--t3);margin-bottom:8px}
.lw-when{display:flex;flex-wrap:wrap;align-items:baseline;gap:5px 10px}
.lw-when b{font:600 14.5px/1.3 var(--display);color:var(--t1)}
.lw-when i{
  font:500 10.5px/1 var(--mono);font-style:normal;letter-spacing:.06em;white-space:nowrap;
  color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-border);
  border-radius:5px;padding:5px 7px;
}
.lw-note{display:block;margin-top:7px;max-width:46ch;font-size:12px;line-height:1.55;color:var(--t3)}

.lw-foot{margin:18px 0 0;padding-top:15px;border-top:1px solid var(--border);
  font-size:11.5px;line-height:1.65;color:var(--t3)}

@media(max-width:520px){
  .lw{padding:22px 18px 20px;border-radius:var(--r-lg)}
  .lw::before{left:18px;right:18px}
  .lw-head{flex-direction:column;gap:12px}
  .lw-figs{grid-template-columns:1fr}
}

/* ==========================================================================
   MARQUEE
   ========================================================================== */
.marquee{
  border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  background:var(--s2);overflow:hidden;padding:13px 0;
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.mq-track{display:flex;width:max-content;animation:mq 42s linear infinite}
.marquee:hover .mq-track{animation-play-state:paused}
.mq-group{display:flex;align-items:center;gap:0;flex:0 0 auto}
.mq-group span{
  font:500 11.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--t2);padding:0 20px;white-space:nowrap;
}
.mq-group span b{color:var(--accent);font-weight:500}
.mq-group span::after{content:'◆';margin-left:20px;font-size:6px;color:var(--accent);opacity:.55;vertical-align:middle}
@keyframes mq{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ==========================================================================
   GRIDS & CARDS
   ========================================================================== */
.grid{display:grid;gap:18px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
@media(max-width:980px){.g3,.g4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.g2,.g3,.g4{grid-template-columns:1fr}}

.card{
  background:var(--s1);border:1px solid var(--border);border-radius:var(--r-lg);padding:24px;
  transition:border-color .18s,transform .18s,background .18s;
}
.card-hover:hover{border-color:var(--border-strong);transform:translateY(-2px)}
.card h3{margin-bottom:9px}
.card p{font-size:14.5px;color:var(--t2);margin:0}
.card p + p{margin-top:12px}

/* --- section 05 feature shots ----------------------------------- */
/* A screenshot inside a feature card. _apply_features_shots.py pre-crops each
   thumbnail and writes its real width and height onto the <img>, so no
   aspect-ratio is set here on purpose: the attributes already reserve the right
   box before the image loads (which is what stops the cards reflowing as the
   images arrive), and they do it per image. Most are 16:10; the mini-player
   strip is 1086:207, and a fixed ratio here would squash it. */
.feat-shot{
  margin:0 0 15px;border:1px solid var(--border);border-radius:var(--r-sm);
  overflow:hidden;background:var(--s3)
}
.feat-shot img{width:100%;height:auto;display:block}
/* Same register as .shot-cap, one step tighter — it sits inside a card, not
   under a full-width figure. */
.feat-shot figcaption{
  font:400 10.5px/1.45 var(--mono);color:var(--t3);letter-spacing:.02em;
  padding:7px 10px;border-top:1px solid var(--border);background:var(--s1)
}
/* The Library card carries two figures. The second closes up against the first
   so the pair reads as one unit rather than two unrelated pictures. */
.feat-shot + .feat-shot{margin-top:-5px}
/* --- /section 05 feature shots ---------------------------------- */
.card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
.card-ico{
  width:38px;height:38px;flex:0 0 auto;border-radius:10px;display:grid;place-items:center;font-size:17px;
  background:var(--accent-soft);border:1px solid var(--accent-border);color:var(--accent);font-family:var(--emoji)
}
.card-num{
  font:500 11px/1 var(--mono);letter-spacing:.1em;color:var(--t3);
  border:1px solid var(--border);border-radius:5px;padding:5px 8px;background:var(--s2);flex:0 0 auto
}

/* --------------------------------------------------------------- stat tiles */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media(max-width:900px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:20px 18px}
.stat b{display:block;font:700 clamp(22px,3vw,30px)/1.1 var(--display);color:var(--accent);margin-bottom:7px;
  font-variant-numeric:tabular-nums}
.stat span{display:block;font-size:12.5px;color:var(--t2);line-height:1.5}
.stat cite{display:block;font:400 10.5px/1.4 var(--mono);color:var(--t3);margin-top:8px;font-style:normal;letter-spacing:.04em}

/* ------------------------------------------------------------------ figures */
figure{margin:0}
.shot{
  border:1px solid var(--border);border-radius:var(--r);overflow:hidden;background:var(--s2);
  box-shadow:0 12px 34px rgba(0,0,0,.3);
}
.shot img{width:100%;display:block}
.shot-cap{font:400 11.5px/1.5 var(--mono);color:var(--t3);padding:9px 12px;border-top:1px solid var(--border);
  background:var(--s1);letter-spacing:.03em}
.shot-bar{display:flex;align-items:center;gap:6px;padding:8px 11px;border-bottom:1px solid var(--border);background:var(--s3)}
.shot-bar i{width:8px;height:8px;border-radius:50%;background:var(--border-strong)}
.shot-bar em{margin-left:6px;font:400 11px/1 var(--mono);color:var(--t3);font-style:normal;letter-spacing:.03em}

/* --- section 04 product hero ------------------------------------- */
/* The box render beside the first screenshot. .85fr/1.15fr, not 1fr/1fr: the box
   is near-square (1.08) and the capture is landscape (1.58), so equal columns
   leave the box ~100px the taller of the two and the row reads lopsided. */
.prod-hero{display:grid;grid-template-columns:.85fr 1.15fr;gap:44px;
  align-items:center;margin-bottom:76px}

/* No .shot frame here, on purpose. .shot's border + fake browser bar means "this
   is a capture of the app"; a physical box inside browser chrome would read as a
   screenshot of a box. Frameless, with a glow to seat the cut-out on the dark
   page and a shadow to give it a floor. */
.prod-box{margin:0;position:relative;display:grid;place-items:center;padding:4px 0}
.prod-box::before{
  content:'';position:absolute;inset:-8% -3% 2%;z-index:0;pointer-events:none;
  background:radial-gradient(56% 50% at 50% 45%,rgba(242,169,60,.15),transparent 70%);
}
.prod-box img{
  position:relative;z-index:1;display:block;width:100%;max-width:410px;height:auto;
  filter:drop-shadow(0 24px 38px rgba(0,0,0,.55));
}
.prod-box figcaption{
  position:relative;z-index:1;margin-top:18px;text-align:center;max-width:34ch;
  font:400 11.5px/1.55 var(--mono);color:var(--t3);letter-spacing:.03em;
}

@media(max-width:900px){
  /* Stacked, and the box is capped smaller than its desktop slot — at full
     column width on a phone it fills the screen before the copy gets a word in. */
  .prod-hero{grid-template-columns:1fr;gap:30px;margin-bottom:52px}
  .prod-box img{max-width:300px}
  .prod-box figcaption{margin-top:14px}
}
/* --- /section 04 product hero ------------------------------------ */

/* ==========================================================================
   SPLIT ROWS
   ========================================================================== */
.split{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.split.narrow-media{grid-template-columns:1.1fr .9fr}
.split + .split{margin-top:72px}
.split.flip .split-media{order:-1}
@media(max-width:900px){
  .split,.split.narrow-media{grid-template-columns:1fr;gap:32px}
  .split.flip .split-media{order:0}
  .split + .split{margin-top:52px}
}
.ticks{list-style:none;margin:20px 0 0;padding:0;display:grid;gap:11px}
.ticks li{position:relative;padding-left:30px;font-size:14.5px;color:var(--t2);line-height:1.55}
.ticks li::before{
  content:'✓';position:absolute;left:0;top:2px;
  width:19px;height:19px;border-radius:5px;display:grid;place-items:center;font-size:10.5px;
  background:var(--success-soft);color:var(--success);border:1px solid rgba(127,217,168,.4)
}
.ticks.crosses li::before{content:'✕';background:var(--danger-soft);color:var(--danger);border-color:rgba(232,115,95,.4)}
.ticks li b{color:var(--t1);font-weight:600}

/* ==========================================================================
   FUNNEL TABLE
   ========================================================================== */
.table-scroll{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--s1);
  -webkit-overflow-scrolling:touch}
table.data{width:100%;border-collapse:collapse;min-width:840px;font-size:14px}
table.data th,table.data td{padding:15px 16px;text-align:left;border-bottom:1px solid var(--border);vertical-align:top}
table.data thead th{
  font:500 10.5px/1.3 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--t3);
  background:var(--s2);position:sticky;top:0;z-index:2;border-bottom:1px solid var(--border-strong);white-space:nowrap
}
table.data tbody tr:last-child td{border-bottom:0}
table.data tbody tr:hover{background:rgba(255,255,255,.014)}
table.data tr.row-hi{background:var(--accent-soft)}
table.data tr.row-hi:hover{background:rgba(242,169,60,.16)}
.t-name{font:600 14.5px/1.3 var(--display);color:var(--t1);display:block;margin-bottom:5px}
.t-desc{font-size:12.5px;color:var(--t2);line-height:1.5;display:block}
.t-price{font:500 16px/1 var(--mono);color:var(--accent);white-space:nowrap}
.t-price small{display:block;font-size:10.5px;color:var(--t3);margin-top:5px;letter-spacing:.05em}
.scroll-hint{font:400 11.5px/1 var(--mono);color:var(--t3);margin:12px 0 0;letter-spacing:.05em}
@media(min-width:1000px){.scroll-hint{display:none}}

/* ----------------------------------- per-product approval links (#approvals)
   Nine cards, one per sellable product — section D of jv-doc.html. They sat
   under the funnel table in section 02 of index.html until the block moved;
   .apv-jump below is the pointer left behind there. Three columns at full
   width: nine divides evenly, so no card is ever orphaned on a short last
   row, and the pitch paragraph needs ~34 characters of measure to avoid reading
   as a column of two-word lines.

   The card is a flex column with the CTA pinned to the card floor by
   margin-top:auto ON THE BUTTON — see the note on that rule for why .apv-page is
   the wrong element to put it on. The pitch paragraphs differ by up to three
   lines, and without it the nine "Request approval" buttons sit at nine different
   heights and the grid stops scanning as a set.

   .apv-card-hi tints the bundle, matching tr.row-hi in the table above, because
   both mark the same product for the same reason. */
.apv-jump{font-size:13px;color:var(--t2);margin:14px 0 0;line-height:1.6}

/* .sec-head's own 44px, less the .apv grid's 20px, so the cards start where
   every other section's content starts. Tightened here rather than by
   dropping .apv{margin-top}, which also spaces the grid from the funnel-table
   jump line if this block is ever previewed elsewhere. */
#approvals .sec-head{margin-bottom:24px}

.apv{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:20px}
@media(max-width:920px){.apv{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.apv{grid-template-columns:1fr}}

.apv-card{
  display:flex;flex-direction:column;
  background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:18px;
  transition:border-color .18s,transform .18s;
}
.apv-card:hover{border-color:var(--border-strong);transform:translateY(-2px)}
.apv-card-hi{background:var(--accent-soft);border-color:var(--accent-border)}
.apv-card-hi:hover{border-color:var(--accent)}

.apv-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:12px}
.apv-pay{font:500 17px/1 var(--mono);color:var(--accent);white-space:nowrap;text-align:right}
.apv-pay small{display:block;font-size:9.5px;color:var(--t3);margin-top:5px;letter-spacing:.11em}

.apv-name{font-size:15px;margin:0 0 5px;line-height:1.25}
.apv-meta{font:400 11.5px/1 var(--mono);color:var(--t3);margin:0 0 11px;letter-spacing:.04em}
.apv-why{font-size:13px;color:var(--t2);line-height:1.55;margin:0 0 14px}
.apv-caveat{font-size:12px;margin:-6px 0 14px;line-height:1.5}

/* margin-top:auto goes on the BUTTON, not on the link below it. It collects the
   card's free space ABOVE the CTA, so the button and the two links under it drop
   to the card floor as one block and the CTAs across a row share a baseline.
   Putting it on .apv-page instead only levels the bottom of the card — which
   flexbox does unaided — and leaves each button wherever its copy happened to
   end: the two cards with a caveat line carry one extra 26px row, and their
   buttons sat 26px below their row-mates. Measured, not assumed. */
.apv-card .btn{margin-top:auto}
/* min-height reserves TWO line boxes on all nine cards. Eight labels fit on one
   line and "Unlimited Song Creation & Expanded Publisher Monetization" needs
   two; without the reservation that card has one line less slack above its
   button, so its CTA sat 19px above its row-mates. Reserving here rather than
   trimming the label keeps the product's full name on the one link whose job
   is to name it, and stops a future long name breaking the row again.
   line-height is explicit because the reserved height must be a multiple of
   the real line box. */
.apv-page{display:block;padding-top:12px;font-size:12px;line-height:1.45;
  min-height:calc(12px + 2 * 1.45em);color:var(--t2)}
.apv-page:hover{color:var(--accent)}
.apv-card .apv-page + .apv-id{margin-top:6px}
.apv-id{display:block;font:400 10px/1 var(--mono);color:var(--t3);letter-spacing:.1em}

.apv-foot{font-size:13px;color:var(--t2);margin:18px 0 0;line-height:1.65;max-width:74ch}

/* ------------------------------------------------- comparison table (sec 07)
   Six columns instead of the funnel table's four, so it needs its own min-width
   or the capability column crushes. The five competitor columns are deliberately
   narrow and centred: the eye should travel down a column of marks, not read
   them as prose. .cmp-us gets a tinted spine on both sides so the Lyrixsa
   column stays findable after a sideways swipe on mobile. */
.cmp .sec-head{margin-bottom:24px}
table.cmp-table{min-width:900px}
table.cmp-table tbody th{
  font:600 13.5px/1.45 var(--sans);letter-spacing:0;color:var(--t1);
  width:34%;min-width:280px
}
table.cmp-table tbody th b{color:var(--t1)}
table.cmp-table thead th:not(:first-child),
table.cmp-table tbody td{text-align:center;white-space:nowrap}
table.cmp-table th.cmp-us,table.cmp-table td.cmp-us{
  background:var(--accent-soft);
  border-left:1px solid var(--accent-border);border-right:1px solid var(--accent-border)
}
table.cmp-table thead th.cmp-us{color:var(--accent)}
table.cmp-table tr.row-hi td.cmp-us{background:rgba(242,169,60,.17)}
table.cmp-table tbody tr:hover td.cmp-us{background:rgba(242,169,60,.13)}
.cmp-y,.cmp-p,.cmp-n{font-size:15px;line-height:1;font-weight:700}
.cmp-y{color:var(--success)}
.cmp-p{color:var(--accent)}
.cmp-n{color:var(--t3);font-weight:400}
.cmp-key{display:flex;flex-wrap:wrap;gap:8px 22px;margin-top:14px;
  font:400 12px/1.4 var(--mono);color:var(--t3)}
.cmp-key b{margin-right:5px;font-size:13px}

/* ==========================================================================
   NOTICE / CALLOUT BLOCKS
   ========================================================================== */
.notice{
  display:grid;grid-template-columns:26px 1fr;gap:14px;
  border:1px solid var(--border-strong);border-left:3px solid var(--accent);
  background:var(--s2);border-radius:var(--r);padding:18px 20px;
}
.notice-ico{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;font-size:12px;
  background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-border)}
/* h3 and h4 both, because a notice's correct heading level depends on where it
   sits: one nested under a section h3 is an h4, one sitting directly under the
   section h2 is an h3. The look is identical either way — the tag is there for
   the document outline, not for the type. */
.notice :is(h3,h4){margin:0 0 7px;font-size:14.5px;font-family:var(--sans);font-weight:700;
  letter-spacing:0;line-height:1.35}
.notice p{margin:0;font-size:13.5px;color:var(--t2);line-height:1.6}
.notice p + p{margin-top:9px}
.notice-warn{border-left-color:var(--danger)}
.notice-warn .notice-ico{background:var(--danger-soft);color:var(--danger);border-color:rgba(232,115,95,.45)}
.notice-good{border-left-color:var(--success)}
.notice-good .notice-ico{background:var(--success-soft);color:var(--success);border-color:rgba(127,217,168,.45)}
.notice-info{border-left-color:var(--info)}
.notice-info .notice-ico{background:var(--info-soft);color:var(--info);border-color:rgba(127,178,217,.45)}

/* ==========================================================================
   CERTIFICATE PANEL
   ========================================================================== */
.cert-panel{
  background:var(--cert-bg);border:1px solid var(--cert-rule);border-radius:var(--r-lg);padding:26px;
  box-shadow:0 24px 60px rgba(0,0,0,.42);
}
.cert-panel .shot{border-color:var(--cert-rule)}
.cert-rights{display:grid;grid-template-columns:repeat(2,1fr);gap:9px;list-style:none;margin:22px 0 0;padding:0}
@media(max-width:520px){.cert-rights{grid-template-columns:1fr}}
.cert-rights li{
  display:flex;align-items:center;gap:9px;font-size:13px;color:var(--cert-ink);
  border:1px solid var(--cert-rule);border-radius:7px;padding:10px 12px;background:rgba(255,255,255,.022)
}
.cert-rights li::before{content:'✓';color:var(--cert-gold);font-size:11px;flex:0 0 auto}
.cert-meta{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--cert-rule);
  border:1px solid var(--cert-rule);border-radius:9px;overflow:hidden;margin-top:20px}
.cert-meta div{background:var(--cert-bg);padding:13px 15px}
.cert-meta dt{font:500 9.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--cert-label);margin:0 0 6px}
.cert-meta dd{margin:0;font:500 13.5px/1.3 var(--mono);color:var(--cert-gold)}


/* --- legal summary: lead takeaway + clause links ---------------- */
/* The one sentence a partner is allowed to put in their copy. It used to be a
   .notice-warn, which made the most useful line on the page look like a warning
   about it. A left keyline in the accent colour says "this is the point" without
   the alarm styling or the icon column. */
.lede-key{margin:0 0 30px;padding:16px 0 16px 20px;border-left:2px solid var(--accent-border);
  font-size:clamp(15px,1.4vw,17px);line-height:1.65;color:var(--t2);max-width:74ch}
.lede-key b{color:var(--t1);font-weight:600}

/* Clause citations. Inline buttons that open the legal dialog at the clause, so
   "(§5.3)" stops being decoration a reader can do nothing with. Sized and spaced
   to sit inside a sentence without breaking its line rhythm — a chip would push
   the line-height around. */
.doc-btn{display:inline;background:none;border:0;padding:0;margin:0;cursor:pointer;
  font:500 12px/1 var(--mono);letter-spacing:.03em;color:var(--t3);
  border-bottom:1px solid var(--border-strong);white-space:nowrap}
.doc-btn:hover,.doc-btn:focus-visible{color:var(--accent);border-bottom-color:var(--accent-border)}

/* The document names themselves read as titles, not citations. */
.doc-btn-lead{font:600 14px/1.5 var(--sans);letter-spacing:0;color:var(--t1)}
.doc-btn-lead::after{content:' ↗';font-size:10px;color:var(--t3)}
.doc-btn-lead:hover::after{color:var(--accent)}

.doc-h{margin:34px 0 16px}
.doc-note{margin:16px 0 0;font-size:12.5px;line-height:1.7;color:var(--t3);max-width:80ch}
.doc-note a{color:var(--t2);border-bottom:1px solid var(--border-strong)}
.doc-note a:hover{color:var(--accent);border-bottom-color:var(--accent-border)}

/* .ticks li is a 19px/1fr grid — the ::before tick, then the content. That works
   when the content is one text run, but these bullets hold a <b>, prose, and one
   or two <button> citations, and EVERY child of a grid becomes its own grid item.
   The first screenshot of this section had the bold lead-in on one line and the
   rest of the sentence broken one word per line, in a 19px column.
     Fixing it in CSS alone isn't possible without unpicking .ticks for the whole
   site, so the markup wraps each bullet's content in a .tick-t span and this rule
   spans it across the content column. Other .ticks lists on other pages are
   untouched. */
#legal .ticks li{gap:11px}
#legal .tick-t{display:block;grid-column:2}
/* Sentences rather than fragments, so a little more air between them. */
#legal .ticks li + li{margin-top:2px}
/* --- /legal summary -------------------------------------------- */

.src-list{list-style:none;margin:0;padding:0;display:grid;gap:11px}
.src-list li{display:grid;grid-template-columns:1fr auto;gap:14px;align-items:baseline;
  padding-bottom:11px;border-bottom:1px solid var(--border);font-size:14px;color:var(--t2)}
.src-list li:last-child{border-bottom:0;padding-bottom:0}
.src-list b{color:var(--t1);font-weight:600}
.src-list cite{font:400 11px/1.4 var(--mono);color:var(--t3);font-style:normal;text-align:right;letter-spacing:.03em;white-space:nowrap}
@media(max-width:640px){
  .src-list li{grid-template-columns:1fr}
  .src-list cite{text-align:left}
}

/* ==========================================================================
   PLAYERS (sample songs)
   ========================================================================== */
.songs{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
@media(max-width:900px){.songs{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.songs{grid-template-columns:1fr}}
.song{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);overflow:hidden;
  transition:border-color .18s}
.song:hover{border-color:var(--border-strong)}
.song-art{aspect-ratio:1;background:linear-gradient(135deg,var(--s3),var(--s1));position:relative;overflow:hidden}
.song-art img{width:100%;height:100%;object-fit:cover}
.song-body{padding:14px 15px 16px}
.song-body h4{margin:0 0 4px;font-size:14.5px}
.song-body p{margin:0 0 12px;font:400 11.5px/1 var(--mono);color:var(--t3);letter-spacing:.05em}
.song audio{width:100%;height:34px;display:block}

/* ==========================================================================
   RESOURCE TABLE
   ========================================================================== */
/* .res-status and .st-ready / .st-build / .st-block were the availability
   chips in section 12's resources table. That section was removed and the
   table was their only user on any page, so they went with it. --success
   and --success-soft stay — .chip-fe and .chip-live use them. */

/* ==========================================================================
   STEPS (how to promote / get link)
   ========================================================================== */
.steps{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;counter-reset:st}
@media(max-width:820px){.steps{grid-template-columns:1fr}}

/* -------------------------------------------- register: form + proof shot */
/* Section 01 split. The ask on the left, proof on the right: the reader meets
   "Get your affiliate link" and its two buttons first, then the payout screen
   and the certificate beside them as the evidence for taking it.

   No `order` here any more. It used to carry `.step{order:2} .reg-proof{order:1}`
   above 1000px, which put the proof column on the left and the card on the
   right while leaving source order card-then-proof. Visual order now matches
   source order, so there is nothing to swap and the tab sequence follows what
   is on screen — the thing `order` costs you.

   The PROOF column is still the wider of the two: the screenshots need the
   pixels more than a column of buttons does. Since it moved from the first
   grid track to the second, the wider track moved with it (.92fr 1.08fr, was
   1.08fr .92fr) — otherwise the swap would have quietly narrowed the
   screenshots by 16% of the row. */
.reg-split{display:grid;grid-template-columns:.92fr 1.08fr;gap:26px;align-items:start}
@media(max-width:1000px){
  .reg-split{grid-template-columns:1fr;gap:22px;max-width:620px;margin-inline:auto}
}
/* No height:100% on either child — stretching one column to the other's height
   only moves the dead space inside whichever lost.

   The proof column (payout screen + certificate) runs about 300px taller than
   the approval card, so instead the card sticks: it stays in view while the
   reader scrolls the two proofs beside it, which is the moment they are most
   likely to act. Turns the leftover column height into a reason to keep the
   buttons on screen rather than a gap. */
@media(min-width:1001px){
  .reg-split > .step{position:sticky;top:calc(var(--head-h) + 20px)}
}

.reg-shot{
  margin:0;background:var(--s1);border:1px solid var(--border);
  border-radius:var(--r-lg);overflow:hidden;
}
/* Crop window. The asset is 1465x1848 (h = 1.2614w); showing 19%–46% of its
   height frames the summary tiles, the payout row and a little air. Height is
   set by aspect-ratio: 0.27 x 1.2614 = 0.3406 of the width, so 1/0.3406 = 2.94.
   The offset is a percentage margin, which resolves against the crop's WIDTH,
   hence 19% x 1.2614 = 23.97%. Keeping both as ratios of the width means the
   crop tracks the image at every breakpoint with no per-query tuning. */
.reg-shot-crop{overflow:hidden;aspect-ratio:2.94;position:relative}
.reg-shot-crop .reg-shot-media{margin-top:-23.97%}

/* The media box is the positioning context for the ring, so the overlay's
   percentages resolve against the image and not the whole figure. */
.reg-shot-media{position:relative;display:block;line-height:0}
.reg-shot-media img{display:block;width:100%;height:auto}
@supports not (aspect-ratio:1){
  /* Old Safari: skip the crop rather than render a squashed frame. */
  .reg-shot-crop{aspect-ratio:auto;overflow:visible}
  .reg-shot-crop .reg-shot-media{margin-top:0}
}

/* The ring. Positioned over the earnings/payout band — TOTAL EARNINGS through
   ESTIMATED NEXT PAYOUT — as a percentage of the screenshot, so it tracks the
   figures at any width. preserveAspectRatio="none" on a 0 0 100 100 viewBox
   lets one ellipse stretch to the band's aspect ratio instead of needing a
   hand-tuned path. */
/* Band measured off the asset (1465x1848): the rule above TOTAL EARNINGS sits at
   y≈505 (27.3%) and the one below the descriptions at y≈740 (40.0%). The ring is
   inset a shade from both so it reads as drawn around the figures rather than
   tracing the dividers. */
.reg-ring{
  position:absolute;left:3.2%;top:26.9%;width:93.6%;height:13.7%;
  overflow:visible;pointer-events:none;
}
.reg-ring ellipse{
  fill:none;stroke:#E8354F;stroke-width:1.15;
  vector-effect:non-scaling-stroke;
  /* Hand-drawn feel: a long dash with one gap, rotated slightly, rather than a
     mechanical vector oval sitting on a UI screenshot. */
  stroke-linecap:round;stroke-dasharray:236 24;stroke-dashoffset:-8;
  transform:rotate(-1.4deg);transform-origin:50% 50%;
  filter:drop-shadow(0 2px 7px rgba(232,53,79,.5));
}
.reg-ring-tag{
  position:absolute;left:3.2%;top:calc(26.9% - 11px);
  transform:translateY(-100%);
  font:600 10.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:#fff;background:#E8354F;border-radius:5px;padding:5px 9px;
  box-shadow:0 4px 14px rgba(232,53,79,.42);white-space:nowrap;
}
@media(max-width:520px){
  /* The tag is wider than the gap above the ring once the shot narrows; tuck it
     inside the ring's top-left instead of letting it collide with the tabs. */
  .reg-ring-tag{font-size:9px;padding:4px 7px;letter-spacing:.08em}
}

.reg-shot-cap{
  font-size:13px;line-height:1.6;color:var(--t2);
  padding:14px 16px;border-top:1px solid var(--border);background:var(--s2);
}
.reg-shot-cap b{color:var(--t1)}
.reg-shot-warn{
  display:block;margin-top:9px;padding-top:9px;border-top:1px dashed var(--border-strong);
  font-size:12px;color:var(--t3);
}

/* Right column of the split: payout screen, then the certificate under it. A
   wrapper rather than two more grid children, so both stay in one column. */
.reg-proof{display:grid;gap:18px;align-content:start}

.reg-cert{
  margin:0;background:var(--s1);border:1px solid var(--cert-rule);
  border-radius:var(--r-lg);overflow:hidden;
}
/* Top half of the certificate. Geometry off the asset (1438x1495): the document
   card sits at x 222-1229 and starts at y=56, so the crop zooms past the asset's
   own dark matte to the card itself — width 1438/1007 = 142.8%, pulled left by
   222/1007 = 22.05%.

   Vertically it runs y=56 to y=785, which ends just above the rights icons: the
   header, the licensee panel and the "your commercial rights" heading, and no
   half-cut row of ticks. As a fraction of the displayed image that is 0.0375 to
   0.5251, i.e. 48.76% of a box 1.4845x the crop width, so the crop is
   0.4876 x 1.4845 = 0.7237 of its own width — hence aspect-ratio 1.3818 — and
   the offset is 0.0375 x 1.4845 = 5.562%. Both margins are percentages, which
   resolve against the crop's width, so the frame tracks the image at every
   breakpoint without per-query tuning. */
.reg-cert-crop{position:relative;overflow:hidden;aspect-ratio:1.3818}
.reg-cert-crop img{
  display:block;width:142.8%;max-width:none;height:auto;
  margin:-5.562% 0 0 -22.05%;
}
/* Fades the cut instead of slicing it, so it reads as a document continuing
   rather than a badly framed screenshot. Section 08 has the rest. */
.reg-cert-crop::after{
  content:"";position:absolute;inset:auto 0 0;height:82px;pointer-events:none;
  background:linear-gradient(to bottom,rgba(23,24,29,0),var(--s1));
}
@supports not (aspect-ratio:1){
  /* Old Safari: show the asset whole rather than an unbounded 142.8% image. */
  .reg-cert-crop{aspect-ratio:auto}
  .reg-cert-crop img{width:100%;margin:0}
  .reg-cert-crop::after{display:none}
}

.reg-cert-cap{
  font-size:13px;line-height:1.6;color:var(--t2);
  padding:14px 16px;border-top:1px solid var(--cert-rule);background:var(--s2);
}
.reg-cert-cap b{color:var(--t1)}
.reg-cert-cap a{display:block;margin-top:7px;font-weight:600}

.step{position:relative;background:var(--s1);border:1px solid var(--border);border-radius:var(--r-lg);padding:26px}
.step-n{
  width:32px;height:32px;border-radius:9px;display:grid;place-items:center;margin-bottom:16px;
  font:600 14px/1 var(--mono);background:var(--accent);color:var(--ink-on-accent)
}
.step h3{margin-bottom:9px}
.step p{font-size:14px;color:var(--t2);margin:0 0 18px}

/* ==========================================================================
   FORMS
   ========================================================================== */
.field{margin-bottom:15px}
.field label{display:block;font:500 11px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--t3);margin-bottom:8px}
.field input,.field select,.field textarea{
  width:100%;background:var(--s3);border:1px solid var(--border-strong);color:var(--t1);
  border-radius:9px;padding:13px 15px;font:400 15px/1.4 var(--sans);transition:border-color .16s,background .16s;
}
.field input::placeholder{color:var(--t3)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:0;border-color:var(--accent);background:var(--s2);box-shadow:0 0 0 3px var(--accent-soft)}
.field input[aria-invalid="true"]{border-color:var(--danger)}
.field .err{display:none;font-size:12px;color:var(--danger);margin-top:7px}
.field.has-err .err{display:block}
.form-note{font-size:12px;color:var(--t3);margin:14px 0 0;line-height:1.6}
.form-ok{
  display:none;text-align:center;padding:14px 0;
}
.form-ok.show{display:block}
.form-ok .ok-ico{width:46px;height:46px;border-radius:50%;margin:0 auto 14px;display:grid;place-items:center;
  font-size:20px;background:var(--success-soft);color:var(--success);border:1px solid rgba(127,217,168,.45)}
/* h3 or h4: the register-step form sits under an h3, the modal's form does not.
   Both get the same confirmation type. */
.form-ok :is(h3,h4){margin:0 0 8px;font-size:18px}
.form-ok p{font-size:14px;color:var(--t2);margin:0}
.is-sent .form-body{display:none}

/* --- submit loading state ---------------------------------------------------
   The spinner is a flex item of .btn, which is already
   `inline-flex;align-items:center;gap:9px` — so it sits after the label at the
   button's own gap with no extra markup and no layout maths. currentColor makes
   one rule correct on the gold primary and the ghost/outline variants alike.

   pointer-events:none stops the hover lift and a second mouse click; the Enter
   key is stopped by the re-entry guard in jv.js, since a focused button still
   fires on Enter with pointer events off. Both are needed — neither alone. */
.btn.is-loading{cursor:progress;pointer-events:none}
.btn.is-loading::after{
  content:'';flex:0 0 auto;width:15px;height:15px;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  animation:btn-spin .62s linear infinite
}
@keyframes btn-spin{to{transform:rotate(360deg)}}
/* The global reduce block forces .001ms/1 iteration on every animation, which
   freezes this ring mid-turn — a broken-looking arc, not a paused one. Hidden
   instead, leaving the "Sending…" label to carry the state. */
@media(prefers-reduced-motion:reduce){.btn.is-loading::after{display:none}}
/* --- /submit loading state ------------------------------------------------ */

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--s1)}
.faq details{border-bottom:1px solid var(--border)}
.faq details:last-child{border-bottom:0}
.faq summary{
  cursor:pointer;list-style:none;padding:19px 22px;padding-right:52px;position:relative;
  font:600 15.5px/1.45 var(--display);color:var(--t1);transition:background .16s;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{background:var(--s2)}
.faq summary::after{
  content:'+';position:absolute;right:22px;top:50%;transform:translateY(-50%);
  font:400 22px/1 var(--mono);color:var(--accent);transition:transform .2s;
}
.faq details[open] summary{background:var(--s2)}
.faq details[open] summary::after{content:'−'}
.faq-a{padding:2px 22px 22px;font-size:14.5px;color:var(--t2);line-height:1.7}
.faq-a > :last-child{margin-bottom:0}

/* ==========================================================================
   RULES
   ========================================================================== */
.rules{list-style:none;counter-reset:r;margin:0;padding:0;display:grid;gap:12px}
.rules li{
  counter-increment:r;position:relative;
  background:var(--s1);border:1px solid var(--border);border-radius:var(--r);
  padding:16px 18px 16px 60px;font-size:14.5px;color:var(--t2)
}
.rules li::before{
  content:counter(r,decimal-leading-zero);position:absolute;left:18px;top:15px;
  font:500 11.5px/1 var(--mono);color:var(--accent);background:var(--accent-soft);
  border:1px solid var(--accent-border);border-radius:6px;width:28px;height:26px;
  display:grid;place-items:center
}
.rules li b{color:var(--t1);font-weight:600;display:block;margin-bottom:4px}

/* ==========================================================================
   CONTACT
   ========================================================================== */
.people{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
@media(max-width:900px){.people{grid-template-columns:1fr}}
.person{background:var(--s1);border:1px solid var(--border);border-radius:var(--r-lg);padding:24px;text-align:center}
.avatar{
  width:74px;height:74px;border-radius:50%;margin:0 auto 16px;display:grid;place-items:center;
  font:600 24px/1 var(--display);background:var(--s3);border:1px solid var(--border-strong);color:var(--t3)
}
.person h3{margin:0 0 5px;font-size:17px}
.person .role{font:500 10.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin:0 0 16px}
.person dl{margin:0;display:grid;gap:9px;text-align:left}
.person dl div{display:grid;grid-template-columns:66px 1fr;gap:10px;font-size:13px;align-items:baseline}
.person dt{font:500 10px/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
.person dd{margin:0;color:var(--t2);word-break:break-word}

/* --- contact avatars ------------------------------------------- */
/* .avatar keeps its size and ring; these two carry artwork inside it instead of
   a letter. The <img> is a child rather than a background so it inherits the
   alt text — the JV manager's photo is a picture of a person and should be
   announced as one, while the two marks are decorative and take alt="". */
.avatar-img{padding:0;overflow:hidden;background:var(--s2)}
.avatar-img img{width:100%;height:100%;object-fit:contain;display:block}
/* A logo needs breathing room inside the ring; a face fills it. */
.avatar-img:not(.avatar-photo) img{padding:15px;box-sizing:border-box}
.avatar-photo{background:var(--s3);border-color:var(--accent-border)}
.avatar-photo img{object-fit:cover}

/* The named contact is the one a partner is looking for, so the card says so
   with a gold rim rather than by being bigger and breaking the grid. */
.person-lead{border-color:var(--accent-border);background:
  linear-gradient(180deg,rgba(242,169,60,.055),transparent 42%),var(--s1)}
.person-lead .role{color:var(--accent)}

@media(max-width:860px){.people{grid-template-columns:1fr}}
/* --- /contact avatars ------------------------------------------ */

/* --- contact avatar link ---------------------------------------- */
/* The JV manager's photo links to his Teams chat. The anchor only has to fill
   the avatar's grid cell so the whole circle is the hit area — an inline anchor
   would be sized by its content and the img's height:100% would resolve against
   a collapsed box. Everything visible still comes from .avatar-* above. */
.avatar-link{display:block;width:100%;height:100%;border-radius:50%;text-decoration:none}
.avatar-link:hover{text-decoration:none}
/* The global :focus-visible ring is border-radius:4px, which draws a near-square
   around a circle. Follow the avatar instead. */
.avatar-link:focus-visible{border-radius:50%;outline-offset:4px}
/* --- /contact avatar link --------------------------------------- */


/* ==========================================================================
   FINAL CTA
   ========================================================================== */
.final{
  text-align:center;padding:92px 0;border-top:1px solid var(--border);
  background:radial-gradient(760px 380px at 50% 0%,rgba(242,169,60,.14),transparent 66%),var(--s1);
}
.final h2{max-width:22ch;margin:0 auto 18px}
.final .lede{margin:0 auto 32px;text-align:center}

/* ----------------------------------------------- claims-to-avoid table (14)
   Three roughly equal columns rather than the funnel table's weighting: all
   three are read across, not scanned down. The don't-write column is the row
   header, so it carries the same weight as .cmp-table's capability column. */
.claims{margin-top:34px}
table.claims-table{min-width:820px}
table.claims-table tbody th{
  font:600 13.5px/1.5 var(--sans);letter-spacing:0;color:var(--danger);
  width:31%;min-width:230px
}
table.claims-table tbody td{font-size:13px;color:var(--t2);line-height:1.55}
table.claims-table tbody td:first-of-type{color:var(--t1);font-weight:600}

/* ------------------------------------------------------- mid-page CTA band
   Sits between the contest and the long evidence half of the page. Reads as a
   band rather than a section: a hairline top and bottom, tighter padding than
   .sec, and the same accent wash as .final at lower opacity so the two CTAs
   look related without the mid one competing with the closer. */
.mid-cta{
  padding:58px 0;border-top:1px solid var(--border-strong);border-bottom:1px solid var(--border-strong);
  background:radial-gradient(700px 300px at 50% 0%,rgba(242,169,60,.09),transparent 68%),var(--s1);
}
.mid-cta h2{font-size:clamp(22px,2.9vw,31px);max-width:30ch;margin-bottom:16px}
.mid-cta .lede{margin-bottom:24px;font-size:clamp(15px,1.35vw,17px)}
.mid-cta-note{margin:18px 0 0;font-size:12.5px;line-height:1.6;color:var(--t3);max-width:68ch}
@media(max-width:640px){
  .mid-cta{padding:44px 0}
  .mid-cta .cta-pair .btn{width:100%}
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.site-foot{border-top:1px solid var(--border);background:var(--bg);padding:56px 0 34px;font-size:13.5px;color:var(--t2)}
.foot-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:40px;margin-bottom:40px}
@media(max-width:820px){.foot-grid{grid-template-columns:1fr;gap:30px}}
/* h3 in the markup — the footer's column labels sit directly under the page's
   last h2, so h4 was a level skip. Kept as a mono eyebrow visually. */
.site-foot :is(h3,h4){font:500 10.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--t3);margin:0 0 16px}
.foot-links{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.foot-links a{color:var(--t2);font-size:13.5px}
.foot-links a:hover{color:var(--accent)}
.foot-brand img{height:28px;margin-bottom:14px}
.foot-brand p{font-size:13px;color:var(--t2);max-width:42ch;margin:0 0 12px}
.legal{border-top:1px solid var(--border);padding-top:26px;display:grid;gap:16px}
.legal p{font-size:11.5px;line-height:1.7;color:var(--t3);margin:0}
.legal strong{color:var(--t2);font-weight:600}
.copy{margin-top:24px;padding-top:20px;border-top:1px solid var(--border);
  font:400 11.5px/1 var(--mono);color:var(--t3);letter-spacing:.04em;text-align:center}

/* ==========================================================================
   MODAL — affiliate launch-list signup
   ========================================================================== */
.modal{
  position:fixed;inset:0;z-index:150;display:none;
  align-items:center;justify-content:center;padding:24px;
}
.modal.open{display:flex}
.modal-veil{position:absolute;inset:0;background:rgba(6,7,9,.8);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.modal-box{
  position:relative;width:100%;max-width:470px;max-height:calc(100dvh - 48px);overflow-y:auto;
  background:var(--s1);border:1px solid var(--border-strong);border-radius:var(--r-xl);
  padding:34px 32px 30px;box-shadow:0 34px 90px rgba(0,0,0,.62);
  animation:pop .26s cubic-bezier(.2,.9,.3,1);
}
@keyframes pop{from{opacity:0;transform:translateY(16px) scale(.975)}to{opacity:1;transform:none}}
@media(max-width:520px){.modal{padding:14px}.modal-box{padding:28px 22px 24px;border-radius:var(--r-lg)}}

.modal-x{
  position:absolute;top:14px;right:14px;width:34px;height:34px;border-radius:9px;
  background:var(--s3);border:1px solid var(--border);color:var(--t2);
  cursor:pointer;display:grid;place-items:center;font-size:16px;line-height:1;transition:background .16s,color .16s;
}
.modal-x:hover{background:var(--s2);color:var(--t1)}

.modal-head{text-align:center;margin-bottom:24px}
.modal-badge{
  display:inline-flex;align-items:center;gap:7px;margin:0 0 16px;
  font:500 10px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-border);
  padding:6px 11px;border-radius:20px;
}
.modal-badge::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px rgba(242,169,60,.25)}
.modal-head h2{font-size:24px;margin:0 0 10px}
.modal-head p{font-size:14px;color:var(--t2);margin:0;line-height:1.6}

.modal-perks{list-style:none;margin:0 0 22px;padding:16px 18px;display:grid;gap:10px;
  background:var(--s2);border:1px solid var(--border);border-radius:var(--r)}
.modal-perks li{display:grid;grid-template-columns:17px 1fr;gap:10px;font-size:13px;color:var(--t2);line-height:1.5}
.modal-perks li::before{content:'✓';color:var(--success);font-size:11px;margin-top:2px}

.modal-dates{display:flex;gap:1px;background:var(--border);border:1px solid var(--border);
  border-radius:9px;overflow:hidden;margin-bottom:22px}
.modal-dates div{flex:1;background:var(--s2);padding:12px 13px;text-align:center}
.modal-dates dt{font:500 9px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--t3);margin:0 0 6px}
.modal-dates dd{margin:0;font:600 13px/1.3 var(--display);color:var(--t1)}

/* ==========================================================================
   MOCK PAGE BANNER — used on every placeholder page
   ========================================================================== */
.mock-flag{
  background:repeating-linear-gradient(45deg,rgba(232,115,95,.11) 0 12px,rgba(232,115,95,.05) 12px 24px);
  border-bottom:1px solid rgba(232,115,95,.4);
}
.mock-flag .wrap{display:flex;align-items:center;gap:14px;padding:14px 24px;flex-wrap:wrap}
.mock-flag .chip{border-color:rgba(232,115,95,.55);background:var(--danger-soft);color:var(--danger)}
.mock-flag p{margin:0;font-size:13px;color:var(--t2);flex:1;min-width:240px}

.page-head{padding:56px 0 40px;border-bottom:1px solid var(--border);
  background:radial-gradient(660px 300px at 20% 0%,rgba(242,169,60,.08),transparent 62%)}
.page-head h1{font-size:clamp(28px,4.2vw,42px);margin-bottom:14px}
.crumb{display:flex;align-items:center;gap:9px;margin:0 0 18px;font:400 11.5px/1 var(--mono);
  color:var(--t3);letter-spacing:.06em}
.crumb a{color:var(--t2)}
.crumb span{opacity:.5}

/* --- swipe phase headings --------------------------------------- */
/* Splits the twelve-email run into "pre-launch" and "cart open". Twelve .swipe
   blocks in a column is a wall; the divider is what tells a partner which of
   them they need this week. A rule on the left rather than a full border,
   because it sits between cards that already have borders of their own. */
.swipe-phase{margin:36px 0 20px;padding:2px 0 2px 16px;border-left:2px solid var(--accent-border)}
.swipe-phase:first-of-type{margin-top:8px}
.swipe-phase h3{margin:0 0 6px;font:600 15px/1.3 var(--display);letter-spacing:.01em}
.swipe-phase p{margin:0;max-width:66ch;font-size:14px;color:var(--t2)}
/* --- /swipe phase headings -------------------------------------- */

/* swipe blocks on the mock swipes page */
.swipe{background:var(--s1);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin-bottom:20px}
.swipe-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:16px 20px;
  background:var(--s2);border-bottom:1px solid var(--border)}
.swipe-head h3{margin:0;font-size:16px}
.swipe-body{padding:20px}
.swipe-body dl{margin:0 0 18px;display:grid;gap:12px}
.swipe-body dt{font:500 10px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--t3);margin-bottom:6px}
.swipe-body dd{margin:0;font-size:14.5px;color:var(--t1)}
.swipe-body pre{
  margin:0;background:var(--s3);border:1px solid var(--border);border-radius:var(--r);padding:18px;
  font:400 13px/1.75 var(--mono);color:var(--t2);white-space:pre-wrap;word-break:break-word;overflow-x:auto
}
.copy-btn{margin-left:auto}

/* .banner-tile drew section 04's eight sizes with the label inside the
   aspect-ratio box, which is what made the page 4649px wide — see the
   banner spec grid below. Nothing else used it. */


/* --- banner spec grid -------------------------------------------- */
/* Eight banner sizes as a spec sheet. Replaced .banner-tile, which put the label
   INSIDE an aspect-ratio box in a 1fr track: the caption's wrapped height drove
   the box's min-content width through the ratio, and the leaderboard demanded
   3755px inside a 1132px container. The page scrolled 4649px wide.

   So the shape carries no content at all — it cannot be inflated — and the label
   sits under it. Every card's stage row is the same fixed height, which does two
   things: the eight shapes are drawn to one scale so the sizes can honestly be
   compared, and every caption in a row starts at the same y instead of stepping
   raggedly with each shape's height. */
.bnr-specs{display:grid;gap:20px;grid-template-columns:repeat(auto-fill,minmax(198px,1fr))}
.bnr-spec{margin:0;display:grid;grid-template-rows:188px auto;gap:12px;min-width:0}
.bnr-stage{display:grid;place-items:center;min-width:0}
/* Landscape shapes are sized by width, portrait ones by height (set inline), so
   neither axis can exceed the 188px stage. */
.bnr-shape{background:var(--s2);border:1px dashed var(--border-strong);
  border-radius:10px;max-width:100%;max-height:100%}
.bnr-spec figcaption{min-width:0}
.bnr-spec b{display:block;font-size:13px;color:var(--t1);font-weight:600;
  line-height:1.35;margin-bottom:3px}
.bnr-spec span{display:block;font:400 11.5px/1.5 var(--mono);color:var(--t3)}
.bnr-spec em{display:block;font-style:normal;font-size:11.5px;line-height:1.5;
  color:var(--t2);margin-top:2px}
@media(max-width:520px){
  .bnr-specs{gap:16px}
  .bnr-spec{grid-template-rows:150px auto;gap:10px}
}
/* --- /banner spec grid ------------------------------------------- */

/* .rules-group / .rules-note lived here for section 15's three rule groups. The
   section was removed and the rules moved to the footer (.fl-group / .fl-rules),
   so these went with it. `.rules` itself stays — assets.html#usage and
   jv-doc.html still use it. */


/* --- section 08 contest graphic --- */
/* timeline */
.tl{margin:0 0 34px}
.tl-bar{display:flex;gap:3px;height:46px}
.tl-seg{display:grid;place-items:center;border-radius:var(--r-sm);padding:0 12px;overflow:hidden}
.tl-seg span{font:600 12px/1.3 var(--mono);letter-spacing:.05em;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.tl-seg-1{flex:56;background:var(--accent);border:1px solid var(--accent)}
.tl-seg-1 span{color:var(--ink-on-accent)}
.tl-seg-2{flex:44;background:var(--accent-soft);border:1px solid var(--accent-border)}
.tl-seg-2 span{color:var(--accent)}
.tl-marks{display:flex;margin-top:10px}
.tl-mark{flex:1;display:grid;gap:1px;border-left:1px solid var(--border-strong);padding-left:9px}
.tl-mark-mid{flex:1;text-align:center;border-left:0;border-right:0}
.tl-mark-end{text-align:right;border-left:0;border-right:1px solid var(--border-strong);
  padding-left:0;padding-right:9px}
.tl-mark b{font:500 12.5px/1.3 var(--mono);color:var(--t1)}
.tl-mark i{font-style:normal;font:400 12px/1.3 var(--mono);color:var(--t2)}
.tl-mark span{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--t3);margin-top:3px}
@media(max-width:700px){
  .tl-bar{height:auto;flex-direction:column;gap:6px}
  .tl-seg{padding:12px}
  .tl-marks{display:grid;gap:10px}
  .tl-mark,.tl-mark-mid,.tl-mark-end{text-align:left;border:0;border-left:1px solid var(--border-strong);
    padding:0 0 0 9px}
}

/* prize hub — one pool, six cash places, ported from the sales page's #workflow-overview.
   1fr/240px/1fr with a circular core and a dashed ring orbiting it. No image: the
   whole diagram is these tokens, so it is crisp at any width and stacks on a phone.
     Two rows, every item explicitly placed: a board heading over each spoke
   column in row 1, the two columns flanking the core in row 2. The headings are
   children of the hub rather than of their columns so they share row 1 and the
   spokes below them start at the same y whatever either heading wraps to —
   nesting them left the columns centring independently and the two sets of
   spokes eight pixels out of step. The core spans both rows and centres against
   them, its aspect-ratio:1 disc setting the height it needs. */
.cx-hub{position:relative;margin:0 0 34px;display:grid;
  grid-template-columns:1fr 240px 1fr;gap:14px 28px}
.cx-board-h{grid-row:1;align-self:end;margin:0;
  font:500 10.5px/1.3 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--accent)}
.cx-board-h span{display:block;margin-top:5px;font:400 11px/1.4 var(--mono);
  letter-spacing:0;text-transform:none;color:var(--t3)}
.cx-board-h.left{grid-column:1}
.cx-board-h.right{grid-column:3;text-align:right}
/* min-width:0 on every grid item, not just the inner div. A grid item defaults to
   min-width:auto — min-content — so the 1fr track refuses to shrink below the
   longest unwrappable line in it, and on a phone that stretched the whole page
   past the viewport and clipped the section headline. */
.cx-hub>*{min-width:0}
/* align-content:center, not start. Beside a 240px circle the three spokes are
   ~190px tall, so top-aligning left the gap under them lopsided. Centred, the
   three prizes sit on the core's axis. */
.cx-col{display:grid;gap:11px;align-content:center;grid-row:2}
.cx-col.left{grid-column:1}
.cx-col.right{grid-column:3}

/* the core, and the "circle" — a dashed ring inset from the disc, not a border.
   Spanning both rows keeps the disc centred against heading + spokes together
   rather than against the spokes alone. */
.cx-core{position:relative;grid-column:2;grid-row:1 / span 2;align-self:center;
  aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;text-align:center;padding:26px;
  border:1px solid var(--accent-border);
  background:radial-gradient(circle at 50% 34%,rgba(242,169,60,.20),transparent 64%),
             linear-gradient(160deg,var(--s3),var(--s1) 72%);
  box-shadow:0 0 0 10px rgba(242,169,60,.045),0 22px 60px rgba(0,0,0,.5)}
.cx-core::before{content:'';position:absolute;inset:-19px;border-radius:50%;
  border:1px dashed rgba(242,169,60,.34)}
.cx-core span{display:block;font:500 9.5px/1 var(--mono);letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent);margin-bottom:9px}
.cx-core strong{display:block;font:700 clamp(34px,4.2vw,44px)/1 var(--display);
  letter-spacing:-.03em;color:var(--t1)}
.cx-core small{display:block;margin-top:11px;font-size:11.5px;line-height:1.5;color:var(--t2)}
.cx-core small b{color:var(--t1);font-weight:600}

/* a spoke: medal tile, place + threshold, prize. The prize is `flex:none` and the
   text `flex:1`, so mirroring the right column is one flex-direction and nothing
   has to be re-pinned. */
.cx-spoke{display:flex;align-items:center;gap:11px;
  background:linear-gradient(150deg,var(--s2),var(--s1) 70%);
  border:1px solid var(--border);border-radius:13px;padding:12px 14px}
.cx-spoke i{display:grid;place-items:center;width:32px;height:32px;flex:none;
  border-radius:9px;background:var(--s3);border:1px solid var(--accent-border);
  font-family:var(--emoji);font-style:normal;font-size:15px;line-height:1}
.cx-spoke span{flex:1;min-width:0}
.cx-spoke b{display:block;font:500 10.5px/1 var(--mono);letter-spacing:.11em;
  text-transform:uppercase;color:var(--t1)}
.cx-spoke em{display:block;font-style:normal;font-size:11.5px;line-height:1.45;
  color:var(--t3);margin-top:4px}
.cx-spoke strong{flex:none;font:600 20px/1 var(--display);color:var(--t1)}
.cx-spoke-1{background:linear-gradient(150deg,rgba(242,169,60,.16),rgba(242,169,60,.03));
  border-color:var(--accent-border)}
.cx-spoke-1 strong{color:var(--accent);font-size:23px}
.cx-col.right .cx-spoke{flex-direction:row-reverse;text-align:right}

@media(max-width:1040px){
  .cx-hub{grid-template-columns:1fr 200px 1fr;gap:12px 18px}
  .cx-core{padding:20px}
  .cx-core strong{font-size:32px}
  .cx-core small{display:none}
  .cx-spoke em{display:none}
}
/* Single column below 900px. The two-row placement is overridden to auto and all
   five items are re-sequenced with `order` — source order is head/head/core/col/col,
   which stacked would put both board headings above both sets of prizes. Reordered
   it reads core, then each heading directly above its own three spokes.
     Every override here is written `.cx-hub .cx-…` on purpose. A media query adds
   no specificity, so a bare `.cx-col{grid-column:auto}` loses to the
   `.cx-col.left{grid-column:1}` above it — the three-column grid then survives
   into the phone layout and, because grid tracks won't shrink below min-content,
   forces the whole page wider than the viewport and clips the headline. */
@media(max-width:900px){
  .cx-hub{grid-template-columns:1fr;max-width:560px;margin-left:auto;margin-right:auto;gap:14px}
  .cx-hub .cx-col,.cx-hub .cx-core,.cx-hub .cx-board-h{grid-column:auto;grid-row:auto}
  .cx-hub .cx-core{order:1;align-self:auto;margin-bottom:10px;aspect-ratio:auto;
    border-radius:var(--r-xl);padding:26px 22px}
  /* Each heading immediately precedes its own column in the stack, so the label
     reads as a caption on the three prizes under it rather than floating. */
  .cx-hub .cx-board-h{align-self:auto;text-align:left}
  .cx-hub .cx-board-h.left{order:2}
  .cx-hub .cx-col.left{order:3}
  .cx-hub .cx-board-h.right{order:4;text-align:left;margin-top:6px}
  .cx-hub .cx-col.right{order:5}
  .cx-core::before{inset:-10px;border-radius:calc(var(--r-xl) + 6px)}
  .cx-core strong{font-size:44px}
  .cx-core small{display:block}
  .cx-hub .cx-col{gap:10px;margin-bottom:8px}
  .cx-spoke em{display:block}
  .cx-hub .cx-col.right .cx-spoke{flex-direction:row;text-align:left}
}

/* qualification */
.qual{margin-top:22px;background:var(--s1);border:1px solid var(--border-strong);
  border-left:3px solid var(--accent);border-radius:var(--r-lg);padding:24px}
.qual-head{display:flex;gap:14px;align-items:flex-start}
.qual-ico{flex:0 0 auto;width:26px;height:26px;border-radius:7px;display:grid;place-items:center;
  font-size:12px;font-weight:700;background:var(--accent-soft);color:var(--accent);
  border:1px solid var(--accent-border);margin-top:2px}
.qual-head h3{margin:0 0 8px;font-size:17px}
.qual-head p{margin:0;font-size:14px;line-height:1.65;color:var(--t2)}
.qual-tiers{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:20px 0 0}
@media(max-width:860px){.qual-tiers{grid-template-columns:repeat(2,1fr)}}
@media(max-width:460px){.qual-tiers{grid-template-columns:1fr}}
/* The tiers split into one group per contest board, each three prizes wide, so
   the threshold ladder a partner reads is the ladder of the board they are
   actually on. --qb-3 keeps the two groups on the same 3-up track count at every
   width the 4-up rule above would have re-flowed. */
.qual-boards{display:grid;gap:20px;margin-top:20px}
.qual-board .qb-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:0}
.qual-board .qb-head b{font:500 10.5px/1 var(--mono);letter-spacing:.13em;
  text-transform:uppercase;color:var(--accent)}
.qual-board .qb-head span{font:400 11.5px/1.4 var(--mono);color:var(--t3)}
.qual-tiers-3{grid-template-columns:repeat(3,1fr);margin-top:11px}
@media(max-width:860px){.qual-tiers-3{grid-template-columns:repeat(3,1fr)}}
@media(max-width:560px){.qual-tiers-3,
  .qual-tiers.qual-tiers-3{grid-template-columns:1fr}}
.qual-tier{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);
  padding:14px 15px;display:grid;gap:4px}
.qual-tier b{font:600 21px/1 var(--display);color:var(--accent)}
.qt-need{font-size:12.5px;color:var(--t1)}
.qt-gross{font:400 11.5px/1.4 var(--mono);color:var(--t3)}
.qual-eg{margin:18px 0 0;padding-top:16px;border-top:1px solid var(--border);
  font-size:13px;line-height:1.7;color:var(--t2)}
.qual-eg b{color:var(--t1)}
/* A second .qual-eg directly under the first. Both would draw the separator rule,
   putting two hairlines 16px apart, so the sibling drops its own. It carries the
   ranking basis and the Tie-break chip, relocated out of the notice the vendor
   removed from #contest -- see _dev/_apply_drop_ranking_notice.py. */
.qual-eg-open{border-top:0;padding-top:0;margin-top:10px}

/* .foot-legal / .fl-group / .fl-rules / .fl-terms / .fl-foot styled the inline
   rule block that used to close every footer. The rules became two documents in
   the legal dialog (assets/js/affiliate-docs.js), which reuses .lg-cl, so all of
   it went. Nothing in the footer needs a numbered grid any more — .foot-doc-sep
   above is the whole of what replaced it. */

/* ==========================================================================
   LEGAL DIALOG  (footer document viewer)
   Ported from the sales page along with the mechanic. Scoped under
   #legal-modal so nothing here can reach the signup modal, which uses its own
   .modal-* system and sits at a lower z-index.
   ========================================================================== */
#legal-modal[hidden]{display:none}
#legal-modal{position:fixed;inset:0;z-index:200}
#legal-modal .lg-scrim{position:absolute;inset:0;background:rgba(6,7,9,.8);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
#legal-modal .lg-box{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(920px,calc(100vw - 32px));height:min(86dvh,900px);
  display:flex;flex-direction:column;
  background:var(--s1);border:1px solid var(--border-strong);
  border-radius:var(--r-xl);overflow:hidden;
  box-shadow:0 40px 90px rgba(0,0,0,.7);
  animation:lg-pop .26s cubic-bezier(.2,.9,.3,1);
}
/* Its own keyframe rather than the signup modal's .pop, for two reasons, both
   of which were live bugs when this used .pop:
     1. .pop animates to transform:none, which wipes the translate(-50%,-50%)
        this box is centred with — so the box sat off-centre for the whole 260ms
        and snapped into place at the end.
     2. .pop scales. getBoundingClientRect reports post-transform pixels, so
        measuring a deep-link offset mid-animation came back 2.5% short — on the
        11,400px scroll to Terms §14 that put the clause 288px down the panel
        instead of at the top. Translation cancels out when you subtract two
        rects; scale does not. So this one only moves and fades. */
@keyframes lg-pop{
  from{opacity:0;transform:translate(-50%,calc(-50% + 14px))}
  to{opacity:1;transform:translate(-50%,-50%)}
}
@media(prefers-reduced-motion:reduce){#legal-modal .lg-box{animation:none}}
#legal-modal .lg-head{flex:none;display:flex;align-items:flex-start;gap:16px;
  padding:22px 24px 18px;border-bottom:1px solid var(--border);background:var(--s2)}
#legal-modal .lg-head > div{min-width:0;flex:1}
#legal-modal .lg-eyebrow{display:block;font:500 10px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);margin-bottom:8px}
#legal-modal h2{font:600 21px/1.25 var(--display);letter-spacing:-.015em;margin:0 0 6px;color:var(--t1)}
#legal-modal .lg-date{margin:0;font:400 10.5px/1 var(--mono);letter-spacing:.05em;color:var(--t3)}
#legal-modal .lg-x{flex:none;width:34px;height:34px;border-radius:9px;cursor:pointer;
  background:var(--s3);border:1px solid var(--border-strong);color:var(--t2);
  font-size:14px;line-height:1;display:grid;place-items:center;transition:color .15s,border-color .15s}
#legal-modal .lg-x:hover{color:var(--t1);border-color:var(--accent-border)}

#legal-modal .lg-tabs{flex:none;display:flex;gap:7px;overflow-x:auto;
  padding:12px 24px;border-bottom:1px solid var(--border);background:rgba(0,0,0,.28)}
#legal-modal .lg-tabs button{flex:none;cursor:pointer;padding:7px 12px;border-radius:999px;
  background:transparent;border:1px solid var(--border-strong);
  font:400 9.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--t2);transition:color .15s,border-color .15s,background .15s}
#legal-modal .lg-tabs button:hover{color:var(--t1);border-color:var(--t3)}
#legal-modal .lg-tabs button[aria-selected="true"]{
  background:var(--accent-soft);border-color:var(--accent-border);color:var(--accent)}

/* A legal document is long-form reading, so the text gets a measure rather than
   the full 920px of the dialog. */
#legal-modal .lg-body{flex:1;min-height:0;overflow-y:auto;padding:26px 30px 40px;
  font-size:13.5px;line-height:1.75;color:var(--t2);overscroll-behavior:contain}
#legal-modal .lg-body > *{max-width:74ch}
#legal-modal .lg-body p{margin:0 0 13px}
#legal-modal .lg-body h3{display:flex;align-items:baseline;gap:11px;
  font:600 15.5px/1.3 var(--display);letter-spacing:-.01em;color:var(--t1);
  margin:32px 0 12px;padding-top:18px;border-top:1px solid var(--border);scroll-margin-top:8px}
#legal-modal .lg-body h3:first-child{margin-top:0;padding-top:0;border-top:0}
#legal-modal .lg-body h3 > span{flex:none;min-width:26px;height:26px;border-radius:7px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent-soft);border:1px solid var(--accent-border);color:var(--accent);
  font:400 10.5px/1 var(--mono)}
#legal-modal .lg-body h4{display:flex;align-items:baseline;gap:9px;
  font:600 13.5px/1.4 var(--display);color:var(--t1);margin:22px 0 9px}
#legal-modal .lg-body h4 > span{flex:none;font:400 10px/1 var(--mono);letter-spacing:.05em;color:var(--t3)}
#legal-modal .lg-body h4.lg-plain{font:500 10.5px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--accent);margin-top:30px}
#legal-modal .lg-body p.lg-cl{padding-left:46px;position:relative;margin-bottom:11px}
#legal-modal .lg-body p.lg-cl > b{position:absolute;left:0;top:0;font-weight:400;
  font:400 10.5px/1.75 var(--mono);color:var(--t3)}
#legal-modal .lg-body ul,#legal-modal .lg-body ol{margin:0 0 15px;padding-left:22px}
#legal-modal .lg-body li{margin-bottom:7px}
#legal-modal .lg-body ul{list-style:none;padding-left:18px}
#legal-modal .lg-body ul > li{position:relative;padding-left:14px}
#legal-modal .lg-body ul > li::before{content:'';position:absolute;left:0;top:.62em;
  width:5px;height:5px;border-radius:50%;background:var(--accent);opacity:.65}
#legal-modal .lg-body em{font-style:normal;font-weight:600;color:var(--t1)}
#legal-modal .lg-body a{color:var(--accent);border-bottom:1px solid var(--accent-border);word-break:break-word}
#legal-modal .lg-body a:hover{border-bottom-color:var(--accent)}
#legal-modal .lg-body .lg-loading{color:var(--t3);font-family:var(--mono);font-size:12px}

#legal-modal .lg-foot{flex:none;display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:12px;padding:14px 24px;border-top:1px solid var(--border);background:var(--s2)}
#legal-modal .lg-foot p{margin:0;font-size:10.5px;line-height:1.6;color:var(--t3);max-width:600px}
#legal-modal .lg-foot .btn{flex:none}

@media(max-width:640px){
  /* Full-bleed on a phone, so the centring transform goes and the animation
     with it — the from-state has to match or the box slides in from off-screen. */
  #legal-modal .lg-box{width:100vw;height:100dvh;border-radius:0;border:0;
    left:0;top:0;transform:none;animation:lg-pop-full .22s ease-out}
  #legal-modal .lg-head{padding:18px 18px 15px}
  #legal-modal h2{font-size:18px}
  #legal-modal .lg-tabs{padding:11px 18px}
  #legal-modal .lg-body{padding:20px 18px 34px;font-size:13px}
  #legal-modal .lg-foot{padding:12px 18px}
}
@keyframes lg-pop-full{from{opacity:0}to{opacity:1}}

/* --- footer document controls ------------------------------------------- */
/* Buttons styled as the footer's links are, so the column reads as a list of
   documents rather than a row of controls. */
.foot-docs{list-style:none;margin:0 0 14px;padding:0;display:grid;gap:10px}
.foot-doc{
  appearance:none;background:none;border:0;padding:0;cursor:pointer;
  font-family:inherit;font-size:13.5px;color:var(--t2);text-align:left;
  transition:color .15s ease;
}
.foot-doc:hover,.foot-doc:focus-visible{color:var(--accent)}
.foot-doc::after{content:' ↗';font-size:10px;color:var(--t3)}
.foot-doc:hover::after{color:var(--accent)}
/* The page you're already on, in the partner-pages column — named, not linked. */
.foot-here{font-size:13.5px;color:var(--t3)}
.foot-here::after{content:' — you are here';font:400 10px/1 var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--accent);opacity:.7}
/* --- footer affiliate documents ----------------------------------- */
/* The programme's own two documents sit under the vendor's three, divided. They
   are different in kind — three are contracts Lyrixsa is bound by, two are terms
   this launch sets — and the dialog's footer line says so. A rule rather than a
   second heading keeps the column one scannable list. */
.foot-doc-sep{margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}

/* The bold lead-in on each affiliate clause. NOT a <b>: p.lg-cl > b is
   absolutely positioned into the 46px gutter to render the clause number, so a
   second <b> in the same paragraph stacks on top of the number and the body text
   runs under both. A span carries the emphasis and stays in the text flow. */
#legal-modal .lg-body p.lg-cl .lg-lead{font-weight:600;color:var(--t1)}
/* --- /footer affiliate documents ---------------------------------- */
.foot-doc-note{margin:0 0 10px;font-size:11.5px;line-height:1.6;color:var(--t3)}
.foot-doc-note a{color:var(--t2);border-bottom:1px solid var(--border-strong)}
.foot-doc-note a:hover{color:var(--accent);border-bottom-color:var(--accent-border)}

/* Inline clause opener, for body prose that cites a section. */
.lg-link{
  appearance:none;background:none;border:0;padding:0;cursor:pointer;
  font:inherit;color:var(--accent);border-bottom:1px solid var(--accent-border);
}
.lg-link:hover{border-bottom-color:var(--accent)}

/* ═══════════════════════════════ SECTION 02 · MUSIC PROOF ═══ */
/* Ported from the sales page's #ai-proof block. Scoped to #market throughout:
   nothing here may reach another section, and the red ring in particular must
   not repaint an unrelated <strong>. The vinyl is the sales page's reskin
   (285px disc, 50% radius, repeating-radial-gradient grooves) with the spin
   animation removed — this page loads no Spotify player to drive it. */

#market .proof-case{
  display:grid; grid-template-columns:1.05fr .95fr; align-items:stretch;
  margin-top:26px; background:var(--s1);
  border:1px solid var(--border); border-radius:var(--r-xl); overflow:hidden;
}
#market .proof-case.reverse .proof-case-copy{order:2}
#market .proof-case.reverse .proof-case-media{order:1}

#market .proof-case-copy{padding:38px; align-self:center; min-width:0}
#market .case-label{
  display:inline-flex; padding:7px 10px; margin-bottom:18px;
  border:1px solid var(--accent-border); border-radius:99px;
  font-family:var(--mono); font-size:10.5px; font-weight:500;
  letter-spacing:.11em; text-transform:uppercase; color:var(--accent);
}
#market .proof-case-copy h3{
  font-family:var(--display); font-size:clamp(23px,3.1vw,32px);
  line-height:1.12; letter-spacing:-.025em; margin:0 0 14px;
}
#market .proof-case-copy h3 em{color:var(--accent); font-style:normal}
#market .proof-case-copy p{color:var(--t2); font-size:15px; line-height:1.7; margin:0}

/* the sales page's .quote treatment: gold rule, dark panel, the circled figure */
#market .money-proof{
  display:flex; align-items:center; gap:18px; margin:26px 0 0; padding:20px;
  background:var(--bg); border-left:3px solid var(--accent);
}
#market .money-proof strong{display:block; font-size:15.5px; color:var(--t1)}
#market .money-proof small{display:block; color:var(--t3); font-size:11.5px; margin-top:3px}
#market .money-num-wrap{
  position:relative; display:inline-flex; align-items:center;
  justify-content:center; min-width:104px; flex:0 0 auto;
}
#market .money-num{
  font-family:var(--display); font-size:29px; font-weight:700;
  color:var(--t1); position:relative; z-index:2; white-space:nowrap;
}
/* the hand-drawn ellipse — deliberately off-round and off-axis so it reads as
   drawn on rather than as a border-radius box */
#market .proof-ring{
  position:absolute; inset:-9px -12px; z-index:1; pointer-events:none;
  border:3px solid #ff4d4d; border-radius:49% 53% 46% 55%;
  transform:rotate(-5deg); filter:drop-shadow(0 0 1px rgba(255,77,77,.5));
}

#market .mini-proof-grid{margin:20px 0 0}
#market .mini-proof{
  display:flex; align-items:baseline; gap:12px; margin:12px 0;
  color:var(--t2); font-size:14px; line-height:1.5;
}
#market .mini-proof .big{
  flex:0 0 auto; font-family:var(--display); font-weight:700;
  font-size:16px; color:var(--accent);
}

#market .proof-links{
  display:flex; flex-wrap:wrap; gap:16px;
  margin-top:24px; padding-top:24px; border-top:1px solid var(--border);
}
#market .proof-links a{
  font-size:11.5px; color:var(--accent);
  border-bottom:1px dashed var(--accent-border); padding-bottom:2px;
}
#market .proof-links a:hover{border-bottom-style:solid}

/* the framed estimate sheet — a fake browser chrome over a dark ledger */
#market .proof-stat-image{
  margin-top:24px; background:#0b0c0f; border:1px solid var(--border);
  border-radius:var(--r-lg); overflow:hidden; max-width:100%;
  box-shadow:0 20px 60px rgba(0,0,0,.22);
}
#market .fake-browser-top{
  height:32px; background:var(--s2); border-bottom:1px solid var(--border);
  display:flex; align-items:center; gap:6px; padding:0 10px;
  color:var(--t3); font-size:9px;
}
#market .fake-browser-top span{width:6px; height:6px; border-radius:50%; background:#363943}
#market .fake-browser-top b{
  font-family:var(--mono); font-weight:400; margin-left:5px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
#market .estimate-sheet{padding:17px 18px 15px; background:linear-gradient(145deg,#121419,#0c0d10)}
#market .sheet-label{
  font-family:var(--mono); font-size:9px; letter-spacing:.1em;
  color:var(--t3); margin-bottom:11px;
}
#market .sheet-row{
  display:flex; justify-content:space-between; align-items:center;
  gap:14px; min-width:0; padding:11px 0; border-bottom:1px solid var(--border);
  font-size:11.5px; color:var(--t2);
}
#market .sheet-row span{min-width:0; overflow-wrap:anywhere}
#market .sheet-row strong{
  font-family:var(--display); font-size:16px; color:var(--t1);
  position:relative; z-index:2; white-space:nowrap;
}
/* Scoped to `.sheet-row strong.circled` exactly as the sales page scopes it, so
   a stray .circled elsewhere in #market draws nothing. Row padding above is
   11px so consecutive rings never touch. */
#market .sheet-row strong.circled:after{
  content:''; position:absolute; left:-8px; right:-8px; top:-7px; bottom:-7px;
  border:2.5px solid #ff4d4d; border-radius:48% 55% 52% 45%;
  transform:rotate(-2deg); pointer-events:none;
}
#market .sheet-source{font-size:9px; color:var(--t3); margin-top:10px; line-height:1.5}

/* the media panel: a lit stage holding the artwork disc */
#market .proof-case-media{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:20px; padding:38px 30px; min-width:0; overflow:hidden;
  border-left:1px solid var(--border);
  background:
    radial-gradient(circle at 50% 40%,rgba(242,169,60,.20),transparent 36%),
    linear-gradient(145deg,var(--s2),#111216);
}
#market .proof-case.reverse .proof-case-media{border-left:none; border-right:1px solid var(--border)}

#market .proof-photo-card{
  position:relative; flex:0 0 auto;
  width:255px; height:255px; max-width:100%;
  border-radius:50%; border:8px solid #272a2f;
  background:repeating-radial-gradient(circle,#0b0c0e 0 3px,#17191d 4px 6px);
  box-shadow:0 18px 55px rgba(0,0,0,.6);
  display:flex; align-items:center; justify-content:center; overflow:hidden;
}
/* the groove layer carries an off-axis sheen. The sales page rotates this; here
   it is static — there is no player state to drive it and a disc that spins
   forever with no audio reads as a broken widget. */
#market .case-vinyl-spin{
  position:absolute; inset:0; z-index:0; border-radius:50%; pointer-events:none;
  background:repeating-radial-gradient(circle,#0b0c0e 0 3px,#17191d 4px 6px);
}
#market .case-vinyl-spin:before{
  content:''; position:absolute; inset:0; border-radius:50%; pointer-events:none;
  background:conic-gradient(from 0deg,rgba(255,255,255,.075) 0deg,
    rgba(255,255,255,0) 55deg,rgba(255,255,255,0) 300deg,rgba(255,255,255,.055) 360deg);
}
/* the artwork is the centre label, ringed in gold like a pressed record */
#market .proof-photo-card img{
  position:relative; z-index:1;
  width:112px; height:112px; aspect-ratio:1/1; border-radius:50%;
  object-fit:cover; display:block; border:3px solid var(--accent);
}
#market .vinyl-caption{text-align:center; max-width:250px}
#market .vinyl-caption b{
  font-family:var(--display); font-size:25px; color:var(--t1);
  display:inline-block; margin-right:5px;
}
#market .vinyl-caption span{
  display:block; margin-top:8px;
  font-size:10.5px; color:var(--t3); line-height:1.5;
}

#market .proof-foot{
  margin-top:20px; font-size:12px; line-height:1.65; color:var(--t3);
}
#market .proof-foot b{color:var(--t2)}

@media (max-width:900px){
  #market .proof-case,
  #market .proof-case.reverse{grid-template-columns:1fr}
  #market .proof-case.reverse .proof-case-copy,
  #market .proof-case.reverse .proof-case-media{order:initial}
  #market .proof-case-media{
    border-left:none; border-right:none; border-top:1px solid var(--border);
  }
  #market .proof-case.reverse .proof-case-media{
    border-right:none; border-top:none; border-bottom:1px solid var(--border);
  }
  #market .proof-case-copy{padding:30px 24px}
  #market .proof-photo-card{width:215px; height:215px}
}
@media (max-width:560px){
  #market .proof-case-copy{padding:24px 18px}
  #market .proof-photo-card{width:185px; height:185px; border-width:6px}
  #market .proof-photo-card img{width:92px; height:92px}
  #market .money-proof{flex-wrap:wrap; gap:14px}
  #market .sheet-row{font-size:11px}
  #market .sheet-row strong{font-size:14px}
}

/* ══════════════════════════ SECTION 03 · CONTENT ID PROOF ═══ */
/* The sales page's #problem-copyright .cr-proof panel, scoped to #audience.
   Same geometry (.92fr/1.08fr, 22px radius, 34px padding), same gold-on-dark
   gradient, same clamp() on the figure. The screenshot is a light web page, so
   it is matted on an elevated dark surface rather than a white card — the
   framed-clipping read, in this page's colours. */

#audience .cr-proof{
  margin:26px 0 0; padding:34px;
  background:
    radial-gradient(circle at 88% 6%, rgba(242,169,60,.10), transparent 46%),
    linear-gradient(140deg, var(--s2) 0%, #15140f 78%);
  border:1px solid var(--border-strong); border-radius:22px;
  display:grid; grid-template-columns:.92fr 1.08fr; gap:30px; align-items:center;
}
#audience .cr-kicker{
  font-family:var(--mono); font-size:11px; letter-spacing:.24em;
  text-transform:uppercase; color:var(--t2); margin-bottom:16px;
}
#audience .cr-num{
  font-family:var(--display); font-weight:700;
  font-size:clamp(32px,4.6vw,58px); line-height:.98; letter-spacing:-.035em;
  color:var(--accent);
}
#audience .cr-proof-h{
  font-family:var(--display); font-size:clamp(18px,2.2vw,26px);
  line-height:1.2; letter-spacing:-.01em; margin:12px 0 14px; color:var(--t1);
}
#audience .cr-proof p{color:var(--t2); font-size:15px; line-height:1.6}
#audience .cr-proof p strong{color:var(--t1); font-weight:600}
#audience .cr-rule{
  width:76px; height:3px; background:var(--accent);
  border-radius:2px; margin:20px 0;
}
#audience .cr-shot{
  background:var(--s3); border:1px solid var(--border-strong);
  border-radius:var(--r); padding:8px;
  box-shadow:0 18px 44px rgba(0,0,0,.45);
}
/* height:auto is required: the tag carries width/height attributes so the
   browser can reserve space before the PNG decodes, and without it the fixed
   height wins once the width scales down and the clipping stretches. */
#audience .cr-shot img{width:100%; height:auto; display:block; border-radius:6px}
#audience .cr-source{
  display:flex; justify-content:space-between; align-items:baseline;
  gap:18px; margin:12px 4px 0; font-size:13px;
}
#audience .cr-source strong{
  font-family:var(--mono); font-weight:500; font-size:11.5px;
  letter-spacing:.06em; text-transform:uppercase; color:var(--t3);
}
#audience .cr-source a{color:var(--accent); font-weight:600; white-space:nowrap}
#audience .cr-source a:hover{text-decoration:underline}

@media (max-width:860px){
  #audience .cr-proof{grid-template-columns:1fr; padding:26px}
}
@media (max-width:560px){
  #audience .cr-proof{padding:20px; border-radius:16px}
  #audience .cr-source{flex-direction:column; gap:6px}
}

/* ═════════════════════════ SECTION 13 · RECIPROCATION ═══ */
/* The boards are light-UI screenshots on a dark page, so each one is matted on
   an elevated surface with a small inset highlight rather than bled to the
   edge — the same framed-clipping treatment section 03 gives the TorrentFreak
   capture, repeated six times.

   The red rings are baked into the PNGs. Nothing here draws one, which is why
   this block has no .proof-ring or .circled rule. */

#reciprocity .recip-stats{
  display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin:0 0 28px;
}
#reciprocity .recip-stat{
  background:var(--s1); border:1px solid var(--border);
  border-left:3px solid var(--accent); border-radius:var(--r);
  padding:18px 20px;
}
#reciprocity .rs-num{
  display:block; font-family:var(--display); font-weight:700;
  font-size:clamp(24px,3vw,34px); line-height:1; letter-spacing:-.03em;
  color:var(--accent);
}
#reciprocity .rs-lab{
  display:block; margin-top:8px; font-size:12.5px; line-height:1.45;
  color:var(--t2);
}

/* Masonry-ish by column count, not by row: the six crops have wildly different
   aspect ratios (1180x377 up to 535x600) and a row-based grid would either
   letterbox the wide ones or crop the tall ones. Columns let each figure keep
   its own height. */
#reciprocity .board-grid{columns:3; column-gap:18px}
#reciprocity .board{
  break-inside:avoid; margin:0 0 18px; padding:12px;
  background:var(--s1); border:1px solid var(--border);
  border-radius:var(--r-lg); overflow:hidden;
}
#reciprocity .board-shot{
  position:relative; display:block; border-radius:var(--r-sm);
  overflow:hidden; background:#fff;
  box-shadow:0 10px 26px rgba(0,0,0,.4);
}
/* height:auto is required. The tags carry intrinsic width/height so the grid
   does not reflow while six PNGs decode, and without this the fixed height
   wins once the column narrows and every board stretches. */
#reciprocity .board-shot img{
  width:100%; height:auto; display:block;
  transition:transform .35s ease;
}
#reciprocity .board-shot:hover img{transform:scale(1.028)}
#reciprocity .board-zoom{
  position:absolute; right:9px; bottom:9px;
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-on-accent);
  background:var(--accent); padding:4px 9px; border-radius:99px;
  opacity:0; transform:translateY(5px); transition:opacity .25s, transform .25s;
}
#reciprocity .board-shot:hover .board-zoom,
#reciprocity .board-shot:focus-visible .board-zoom{opacity:1; transform:none}
#reciprocity .board figcaption{padding:14px 4px 4px}
#reciprocity .board-rank{
  display:block; font-family:var(--display); font-weight:700; font-size:16px;
  letter-spacing:-.01em; color:var(--t1);
}
#reciprocity .board-vendor{
  display:block; margin-top:5px; font-family:var(--mono); font-size:10.5px;
  letter-spacing:.14em; text-transform:uppercase; color:var(--accent);
}
#reciprocity .board-note{
  display:block; margin-top:9px; font-size:13px; line-height:1.55;
  color:var(--t2);
}

@media (max-width:1000px){
  #reciprocity .board-grid{columns:2}
  #reciprocity .recip-stats{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  #reciprocity .board-grid{columns:1}
  #reciprocity .board{padding:10px; border-radius:var(--r)}
}
/* The scale-on-hover is decoration; a reduced-motion reader gets the ring and
   the caption, which is the whole content. */
@media (prefers-reduced-motion:reduce){
  #reciprocity .board-shot img{transition:none}
  #reciprocity .board-shot:hover img{transform:none}
  #reciprocity .board-zoom{transition:none}
}

/* ═══════════════════════ LIVE LAYOUT FIXES · MEASURED ═══ */
/* Three faults found on the deployed page with _dev/_measure.py. Each number
   in the comments is a real getBoundingClientRect reading at 1440px wide, not
   an estimate. See _dev/_apply_layout_fixes.py for the full reasoning. */

/* ── 1. the proof cases ────────────────────────────────────────────────────
   .proof-case-media measured 593x893 holding 356px of content (a 255px disc,
   a 20px gap, an 81px caption). justify-content:center parked that in the
   middle, leaving ~270px of empty gradient above and below — and because the
   cases alternate, the void swapped sides each time.

   FIRST ATTEMPT, AND WHY IT WAS WRONG: align-content:start + padding-top moved
   the 356px to the top. Re-measuring showed 453px and 512px of dead panel
   BELOW the caption — the void was relocated, not removed, and it got worse.
   A 356px column cannot be aligned into looking full beside an 893px one.

   The panel has to FILL. The disc scales with the column instead of sitting at
   a fixed 255px: min() against both the column width and a share of the case
   height, so a tall case gets a big record and a short one gets a small one.
   That is also the honest design — the artwork IS the panel's content, so it
   should be as large as the panel it is given. */
#market .proof-case-media{
  justify-content:center;
  gap:26px;
  padding:44px 34px;
}

/* SECOND ATTEMPT, AND WHY IT WAS WRONG: the container query below was applied
   at every width, with the stacked sizes handed to a max-width:860px block.
   Two bugs, both measured at a 534px viewport:

     .proof-case-media   496 x 69     container-type=size

   69px is the padding and nothing else. `container-type:size` is containment on
   BOTH axes, so the panel stops taking its height from its contents — and once
   .proof-case stacks to one column there is no grid row supplying a height
   either, so it collapsed to zero content-height and `overflow:hidden` clipped
   the disc and the caption away entirely. The panel had no height to give and
   62cqh had nothing to resolve against.

   The second bug hid inside the first: the base stylesheet stacks the case at
   max-width:900px, but the override was written at 860px, so 861–900px got the
   stacked layout with the container query still live.

   So the container query is confined to the side-by-side layout, where the
   panel's height genuinely IS externally determined by the grid row — the only
   condition under which cqh means anything — and the breakpoint matches the one
   that does the stacking. */
@media (min-width:901px){
  /* cqh needs a container to resolve against, and size containment is only safe
     here: above this width the grid row gives the panel its height. */
  #market .proof-case-media{container-type:size}
  #market .proof-photo-card{
    /* 255px was a fixed size ported from the sales page, where this panel sits
       beside much shorter copy. Here it scales: never wider than the column
       allows, never taller than fits alongside the caption.

       The first cap was 360px, which measured as the binding term — the disc
       grew to exactly 360 and left 213px of slack, so the cap was doing the
       deciding rather than the geometry. 100% (the padded column width) is the
       real limit; 62cqh keeps a short case from producing a disc taller than
       its panel. */
    width:min(100%, 62cqh);
    height:auto; aspect-ratio:1/1;
  }
}
@media (max-width:900px){
  /* Stacked: the panel is only as tall as its content, so a fixed, smaller disc
     is right again — there is no tall neighbour to fill against, and no size
     containment, so the panel grows to hold it. */
  #market .proof-photo-card{width:215px; height:auto; aspect-ratio:1/1}
  #market .proof-case-media{padding:34px 24px}
}
@media (max-width:560px){
  #market .proof-photo-card{width:185px; height:auto; aspect-ratio:1/1}
}

/* ── 2. "Request affiliate approval" ───────────────────────────────────────
   .cta-split ended at y=1797 and .form-note began at y=1797 — zero pixels
   apart. The note's 14px top margin was the only separation and the .tbc pill
   on its first line (inline-flex, padding, dashed border) overflowed its line
   box upward onto the buttons.

   Scoped to a step's DIRECT .form-note so the identical class inside step 1's
   form (which sits under a full-width button and needs no rule) is untouched.*/
.step > .form-note{
  margin-top:22px; padding-top:18px;
  border-top:1px solid var(--border);
}
/* Stops the pill overflowing its line box, which is what let it touch the
   button above. Applies wherever .tbc appears inline in prose. */
.tbc{vertical-align:middle}
/* The pill is 11.5px mono inside 12px prose; without this its line is tighter
   than the lines around it and the paragraph looks broken where a pill lands. */
.form-note{line-height:1.75}

/* ── 3. the leaderboard grid ───────────────────────────────────────────────
   columns:3 measured column heights of 610 / 711 / 715 with a lone 250px board
   above a 360px one — a 105px step across the bottom, and the 3.13:1 panorama
   crushed into a 365px column.

   FIRST ATTEMPT, AND WHY IT WAS WRONG: a 2-column grid with the panorama
   spanning leaves FIVE boards to fill four cells. Re-measuring found the
   columns ragged by 460px — worse than the 105px it replaced — because the
   last board sat alone in column 1 with an empty cell beside it.

   Six boards, one of which must be full-width, leaves FIVE — and 5 divides
   evenly by neither 2 nor 3. Any fixed column count therefore leaves a hole
   somewhere. A 6-track grid solves it because the span can VARY by row:

       row 1   the panorama                span 6
       row 2   three boards                span 2 each   = 6
       row 3   the last two boards         span 3 each   = 6

   Every row is full, no cell is empty, and the two boards on the last row are
   simply a little wider than the three above them — which suits them, since
   both are dashboard tables whose text benefits from the extra width.

   At 1000px it drops to 2 per row (3 would be ~180px wide and the dashboard
   text unreadable) and the panorama still spans.

   THIRD ATTEMPT, AND WHY THE NARROW WIDTHS WERE BROKEN: the spans below were
   written once for the 6-track grid and then "reset" inside the narrow media
   queries by `#reciprocity .board{grid-column:span 1}`. That reset is (1,1,0);
   `#reciprocity .board:nth-last-child(-n+2)` is (1,2,0) and a media query adds
   NOTHING to specificity — so the last two boards kept `span 3` inside a
   2-track grid. Measured at a 534px viewport:

     .board-grid   498px   grid-template-columns = 22px 220px 220px
       #0 board-wide  span 1   22px      <- the panorama, 22px wide
       #4             span 3   498px
       #5             span 3   498px

   A span of 3 in a 2-track grid forces a third IMPLICIT column, which is where
   the 22px track came from; the panorama then landed in it 22px wide, and the
   grid had a genuine hole (one row 476px short of its own width).

   Every span is therefore stated at the SAME specificity, and the whole span
   plan lives in one min-width block per layout, so no rule has to be undone by
   a later one. */
#reciprocity .board-grid{
  columns:auto; column-gap:normal;
  display:grid; gap:18px; align-items:start;
  grid-template-columns:1fr;
}
#reciprocity .board{margin:0}
/* ≥1001px — the 6-track plan: 6 / 2+2+2 / 3+3. Each selector below is
   (1,2,0) so they compete on source order alone, not on specificity. */
@media (min-width:1001px){
  #reciprocity .board-grid{grid-template-columns:repeat(6,1fr)}
  #reciprocity .board-grid > .board{grid-column:span 2}
  /* The panorama, marked by class in the markup so a reorder cannot move the
     span onto the wrong figure. */
  #reciprocity .board-grid > .board-wide{grid-column:span 6}
  /* The last two boards widen to span 3 so the final row is full rather than
     leaving a third of it empty. Counted from the END, so the rule survives the
     panorama being anywhere in the source order. */
  #reciprocity .board-grid > .board:nth-last-child(-n+2){grid-column:span 3}
}
/* 641–1000px — two per row, panorama across both. Five boards in a 2-track grid
   would leave the last one alone with an empty cell beside it, so the last board
   spans as well; a lone dashboard table at full width reads better than a hole
   and this is the width where its text needs the room anyway. */
@media (min-width:641px) and (max-width:1000px){
  #reciprocity .board-grid{grid-template-columns:repeat(2,1fr)}
  #reciprocity .board-grid > .board{grid-column:span 1}
  #reciprocity .board-grid > .board-wide{grid-column:span 2}
  #reciprocity .board-grid > .board:nth-last-child(1){grid-column:span 2}
}
/* ≤640px — one per row. grid-template-columns:1fr is already the base value and
   no span is set at this width at all, so there is nothing to undo. */
@media (max-width:640px){
  #reciprocity .board{padding:10px}
}

/* ═════ SECTION 04 · LOCATION IS NOT THE LIMIT ═══ */
/* Ported from the sales page's <style id="lyrixa-location-map"> — same map, same
   projection, same pins. Two substitutions and nothing else: --hdr is --head-h in
   this stylesheet (an unresolved var() in scroll-margin-top computes to 0 and the
   anchor lands under the sticky header, which you only notice by clicking the
   nav), and the mono stack is var(--mono). .lo-lede and .lo-outro are not ported:
   .lede and a .notice do those jobs here.

   Built as real SVG and HTML rather than an image, which is what lets the pins be
   positioned by percentage of the box and still land on the actual city, and lets
   their labels scale with page type instead of with the drawing.

   The flags are hand-drawn SVG. Emoji flags do not render on Windows — Chrome
   shows the two-letter country code instead, so a map of emoji flags would read
   "NG GB US BR IN JP ID AU" on a large share of visitors' machines. */
#location{position:relative;overflow:hidden;scroll-margin-top:calc(var(--head-h) + 16px)}

/* ═════ HERO SECONDARY CTA TARGET ═══ */
/* The hero's second button aims here rather than at #register. html already sets
   scroll-padding-top, so the header is cleared without this rule — the extra
   margin exists so the reader does not land with the two buttons flush at the
   top of the viewport and the card's heading and the vendor-of-record panel
   scrolled off above them. Arriving at two unlabelled buttons is worse than
   arriving slightly short of them.

   tabindex="-1" in the markup is what lets the fragment take focus; it is paired
   with :focus{outline:none} because that focus is programmatic — the reader gets
   a scroll, and a focus ring drawn around a whole two-button row reads as an
   error state. Keyboard users still get every button's own :focus-visible ring. */
#approval-buttons{scroll-margin-top:calc(var(--head-h) + 96px)}
#approval-buttons:focus{outline:none}

#location::before{
  content:'';position:absolute;z-index:0;pointer-events:none;
  left:50%;top:60px;width:1000px;height:1000px;margin-left:-500px;border-radius:50%;
  background:radial-gradient(circle,rgba(242,169,60,.08),transparent 62%)
}
#location > *{position:relative;z-index:1}

/* ---- the map object ---- */
#location .lo-map{
  position:relative;margin:36px auto 0;max-width:1000px;
  border-radius:18px;overflow:hidden;
  background:linear-gradient(165deg,var(--s1),var(--bg) 78%);
  border:1px solid var(--border-strong);
  box-shadow:0 24px 52px rgba(0,0,0,.5)
}
/* The pins are positioned against THIS box, not the card: the card also holds the
   caption bar (and, when narrow, the place list), so pins measured against the
   card drift down off the map and land on the captions. */
#location .lo-plot{position:relative}
/* the drawing sets the plot height, so a pin at 60.06% of it stays on Nairobi at
   every width */
#location .lo-svg{display:block;width:100%;height:auto}
#location .lo-grat{fill:none;stroke:rgba(255,255,255,.045);stroke-width:.6}
/* light enough to read as land at a glance, dark enough that the gold pins and
   routes are still the brightest thing in the frame */
#location .lo-land{fill:#2B2F37;stroke:#41454F;stroke-width:.5}
/* the routes: drawn once, then dashed and animated so the dashes crawl along the
   path — the movement is the point, and a static arc doesn't have it */
#location .lo-route{
  fill:none;stroke:url(#loGrad);stroke-width:1.5;
  stroke-linecap:round;stroke-dasharray:5 9;opacity:.85
}
@media (prefers-reduced-motion:no-preference){
  #location .lo-route{animation:loFlow 3.4s linear infinite}
}
@keyframes loFlow{to{stroke-dashoffset:-56}}

/* ---- the pins ---- */
#location .lo-pins{position:absolute;inset:0;pointer-events:none}
/* The dot is anchored on the city and the label grows away from it, rather than
   the whole pin being centred: centring a 120px-wide tag on the coordinate puts
   the dot in the middle of the text instead of on the place. */
#location .lo-pin{
  position:absolute;transform:translateY(-50%);
  display:flex;align-items:center;gap:7px;white-space:nowrap;margin-left:-4.5px
}
/* right-hand pins keep their label to the left of the dot, or Tokyo and Sydney
   push their names off the edge of the map */
#location .lo-pin.lo-l{
  flex-direction:row-reverse;margin-left:0;margin-right:-4.5px;
  transform:translate(-100%,-50%)
}
/* the dot, with a ring that pulses out of it like a played note */
#location .lo-dot{
  position:relative;flex:none;width:9px;height:9px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 0 3px rgba(242,169,60,.18),0 0 12px rgba(242,169,60,.7)
}
#location .lo-dot::after{
  content:'';position:absolute;inset:-4px;border-radius:50%;
  border:1px solid var(--accent-border)
}
@media (prefers-reduced-motion:no-preference){
  #location .lo-dot::after{animation:loPing 2.8s ease-out infinite}
  #location .lo-pin:nth-child(2n) .lo-dot::after{animation-delay:.7s}
  #location .lo-pin:nth-child(3n) .lo-dot::after{animation-delay:1.4s}
}
@keyframes loPing{
  0%{transform:scale(.7);opacity:.9}
  70%{transform:scale(2.6);opacity:0}
  100%{transform:scale(2.6);opacity:0}
}
/* the tag: flag, place, and a note mark saying a song is playing there */
#location .lo-tag{
  display:inline-flex;align-items:center;gap:7px;
  padding:4px 9px 4px 6px;border-radius:999px;
  background:rgba(16,17,20,.86);border:1px solid var(--border-strong);
  backdrop-filter:blur(3px);box-shadow:0 3px 10px rgba(0,0,0,.5)
}
#location .lo-flag{
  display:block;width:19px;height:13px;flex:none;border-radius:2px;
  box-shadow:0 0 0 1px rgba(255,255,255,.16)
}
#location .lo-name{
  font-family:var(--mono);font-size:10px;letter-spacing:.05em;color:var(--t1)
}
#location .lo-note{flex:none;width:12px;height:12px;display:block;color:var(--accent)}
@media (prefers-reduced-motion:no-preference){
  #location .lo-note{animation:loBob 1.9s ease-in-out infinite}
  #location .lo-pin:nth-child(2n) .lo-note{animation-delay:.45s}
  #location .lo-pin:nth-child(3n) .lo-note{animation-delay:.95s}
}
@keyframes loBob{
  0%,100%{transform:translateY(0);opacity:.75}
  50%{transform:translateY(-2.5px);opacity:1}
}

/* ---- the caption bar across the bottom of the map ---- */
#location .lo-bar{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  gap:10px 26px;padding:14px 20px;
  border-top:1px solid var(--border);background:rgba(0,0,0,.34)
}
#location .lo-bar span{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:10px;
  letter-spacing:.09em;text-transform:uppercase;color:var(--t2)
}
#location .lo-bar svg{width:13px;height:13px;flex:none;color:var(--accent)}

/* ---- narrow ---- */
/* Below ~820px a pin tag is wider than the gap between two pins and the map
   becomes a pile of overlapping chips. The labels drop, leaving the pulsing dots
   on the map — which still says "everywhere" — and the places move into a legible
   list underneath. margin:0 on the <ul> cancels the UA's default block margin,
   which this stylesheet has no global list reset for. */
#location .lo-list{display:none}
@media (max-width:820px){
  #location .lo-tag{display:none}
  #location .lo-list{
    display:flex;flex-wrap:wrap;justify-content:center;gap:7px;
    margin:0;padding:16px 14px;border-top:1px solid var(--border);
    background:rgba(0,0,0,.34)
  }
  #location .lo-list li{
    list-style:none;display:inline-flex;align-items:center;gap:6px;
    padding:5px 10px 5px 7px;border-radius:999px;
    background:var(--s1);border:1px solid var(--border-strong);
    font-family:var(--mono);font-size:9.5px;letter-spacing:.05em;color:var(--t2)
  }
  #location .lo-list .lo-flag{width:16px;height:11px}
  #location .lo-bar{gap:9px 18px;padding:13px 16px}
  #location .lo-bar span{font-size:9px}
}
@media (max-width:560px){
  #location .lo-map{border-radius:14px}
  #location .lo-dot{width:7px;height:7px}
  #location .lo-bar{flex-direction:column;align-items:flex-start}
}

/* ═══════════════════════ SECTION 13 · THE SEVENTH BOARD ═══ */
/* The grid was planned for six: 6 / 2+2+2 / 3+3 across six tracks. A seventh
   board inherits `span 2` and sits alone in a row with four empty tracks after
   it, which on a dark page reads as a missing image rather than as a short row.

   THE SEVEN-BOARD PLAN IS 6 / 2+2+2 / 2+2+2 — the panorama across the top and
   then EVERY other board an equal third, the shape the middle row already had.
   Six non-panorama cards divide by three exactly, so no row is short and no
   card is a special case. The whole of the six-board plan's row-shaping goes
   away: with seven cards there is nothing left to shape.

   Two earlier cuts got this wrong, both by trying to hand the odd row out to
   one card instead of noticing that six divides evenly:

     · flatten the pair rule to span 2, new board span 6 → the five cards above
       it went 2+2+2 then 2+2, so MarketBooks + Early Superstars filled four of
       six tracks. Measured at 1440px: a two-track hole.
     · move the pair rule up one card (3+3) and keep the new board at span 6 →
       every row full, but the two widened cards no longer matched the three
       above them, and a dashboard table at span 3 disagrees with its own
       `sizes="...30vw"` hint, so the browser fetched the wrong candidate width.

   Equal thirds settles both: it is the one shape where every row is full AND
   every card is the width its `sizes` attribute already claims.

   The panorama keeps the full top row. It is 1180x377 — at a third of the width
   it would be a 380px strip four times wider than it is tall, unreadable and
   unlike every other card. It is marked by class in the markup, so this holds
   whatever the source order becomes.

   Both rules below undo a six-board rule rather than add anything, and both are
   stated at the same specificity as the rule they override — a bare
   `.board{grid-column:span 1}` reset would be (1,1,0), would lose, and would
   leave the implicit-column fault this file's earlier note records. */
@media (min-width:1001px){
  #reciprocity .board-grid > .board:nth-last-child(-n+2){grid-column:span 2}
}
/* 641–1000px — two per row. The six-board plan widened the LAST board because
   five cards in a 2-track grid left it alone beside an empty cell. Six
   non-panorama cards pair evenly, so that rule now creates the hole it was
   written to prevent: measured at 900px, Early Superstars sat alone with an
   empty cell and the new board took a full row of its own below it. */
@media (min-width:641px) and (max-width:1000px){
  #reciprocity .board-grid > .board:nth-last-child(1){grid-column:span 1}
  #reciprocity .board-grid > .board-wide{grid-column:span 2}
}
