/* ============================================================
   League Promotion Page — approved Registration Concept v6.

   Translated from design_mockups/campaign/registration_concept_v6/styles.css.
   Requires css/public/tokens.css + base.css + components.css (loaded by
   public/_base.html). Every rule is scoped under .promo-scope so nothing
   leaks into other public pages.

   "Inspire first. Inform second. Register third."

   The rule that lets a premium campaign carry a full spec sheet:
   INFORMATION IS ENGRAVED ON OBJECTS IN THE ROOM — plates, rails, a
   ledger, a pass — never a grid of web cards on a flat background.

   Scenes: league night → the season → every week → flights → majors &
   final → weekly prizing → the digital clubhouse → the door.

   Gold accumulates down the page (--promo-gold per scene), peaks at the
   championship, and returns only as an edge on the price.

   Built against the campaign photography in static/images/campaign/:
     season/week/flights/hero_clubhouse/prizes/door .. 1086x1448 portrait 3:4
     majors ........................................... 1672x941  landscape
     clubhouse_board .................................. 900x382   product detail
   ============================================================ */

/* ---------- page frame overrides (this page is full-bleed) ---------- */
body.pub-scope.promo-scope { padding-bottom: 0; }
body.pub-scope.promo-scope.promo-has-cta {
  padding-bottom: calc(72px + env(safe-area-inset-bottom));
}
.promo-scope .page { max-width: none; padding: 0; }
body.pub-scope.promo-scope { background: var(--carbon-0); }

.promo-scope {
  --promo-col: 880px;         /* the width information may occupy, so the
                                 photograph always keeps a lane of its own */
  --promo-ease: cubic-bezier(.2, .6, .25, 1);
  --promo-slow: 1100ms;
  --promo-tap: 48px;
}

.promo-scope img,
.promo-scope video { display: block; max-width: 100%; }

.promo-scope .promo-skip {
  position: absolute; left: 16px; top: -60px; z-index: 200;
  background: var(--signal); color: var(--signal-ink);
  font-family: var(--font-cond); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; padding: 12px 20px; transition: top 120ms;
}
.promo-scope .promo-skip:focus { top: 16px; }

/* ============================================================
   SCENE SYSTEM
   Every section is photography first. The hero fills a viewport and sits
   its copy on the floor of the frame; information sections grow with
   their content but keep the same photograph behind them, so the page
   never cuts to a "content area".
   ============================================================ */
.promo-scope .promo-scene {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}
.promo-scope .promo-scene-media { position: absolute; inset: 0; z-index: -2; }
.promo-scope .promo-scene-media img,
.promo-scope .promo-scene-media video {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
}

/* A slow, almost unnoticeable settle. Never parallax.

   Framing and motion are kept in separate custom properties on purpose:
   --promo-zoom / --promo-ty are the *crop* (which frames the subject and must
   survive everywhere); --promo-drift is the *animation* (which reduced motion
   removes). Collapsing these into one `transform` means switching motion off
   also throws away the crop, and the mobile hero falls back to a frame of
   ceiling. */
.promo-scope .promo-scene-media img {
  --promo-zoom: 1;
  --promo-drift: .045;
  --promo-ty: 0%;
  transform: scale(calc(var(--promo-zoom) + var(--promo-drift))) translateY(var(--promo-ty));
}
@media (prefers-reduced-motion: no-preference) {
  html.promo-js .promo-scope .promo-scene-media img {
    transition: transform 2600ms var(--promo-ease);
  }
  html.promo-js .promo-scope .promo-scene.is-in .promo-scene-media img { --promo-drift: 0; }
}
/* Without JS the settle never resolves, so start at rest. */
html:not(.promo-js) .promo-scope .promo-scene-media img { --promo-drift: 0; }
.promo-scope .promo-scene-media .is-media-failed { display: none; }

/* ------------------------------------------------------------
   DESKTOP CROPS.
   Six of the eight frames are portrait 3:4. On a landscape viewport
   `object-fit: cover` is width-driven for them: the full width shows and
   roughly the middle 47% of the height survives at 1440x900. These values
   choose WHICH horizontal band of each photograph that is.
   ------------------------------------------------------------ */
.promo-scope .promo-hero .promo-scene-media img            { object-position: center 52%; } /* friends + screen + table */
.promo-scope .promo-scene--season .promo-scene-media img   { object-position: center 8%; }  /* top band: slatted wall, away from the bin */
.promo-scope .promo-scene--week .promo-scene-media img     { object-position: center 50%; } /* the full swing */
.promo-scope .promo-scene--flights .promo-scene-media img  { object-position: center 48%; }
.promo-scope .promo-scene--majors .promo-scene-media img   { object-position: center center; }
.promo-scope .promo-scene--prizes .promo-scene-media img   { object-position: center 46%; } /* hand on shoulder + trophy case */
.promo-scope .promo-door .promo-scene-media img            { object-position: center 45%; } /* trophy case, couch, empty seat */

/* Scrims keep every headline legible over photography */
.promo-scope .promo-scrim { position: absolute; inset: 0; z-index: -1; }
/* The hero headline crosses a lit simulator screen, so the grade is weighted
   both to the floor of the frame and to the column the copy occupies. */
.promo-scope .promo-scrim--bottom {
  background:
    linear-gradient(to right,
      rgba(4, 6, 9, .82) 0%, rgba(4, 6, 9, .60) 34%,
      rgba(4, 6, 9, .18) 62%, transparent 84%),
    linear-gradient(to top,
      rgba(4, 6, 9, .95) 0%, rgba(4, 6, 9, .70) 30%,
      rgba(4, 6, 9, .30) 62%, rgba(4, 6, 9, .45) 100%);
}
/* Information sections carry real copy over a lit simulator screen, so the
   grade is weighted to the side the copy lives on and released on the other.
   The photograph is recessed, never replaced. */
.promo-scope .promo-scrim--deep {
  background:
    linear-gradient(to right,
      rgba(4, 6, 9, .93) 0%, rgba(4, 6, 9, .88) 34%,
      rgba(4, 6, 9, .62) 66%, rgba(4, 6, 9, .38) 100%),
    linear-gradient(to top, rgba(4, 6, 9, .80), rgba(4, 6, 9, .30) 65%);
}
/* The season frame is by some distance the brightest in the set: a white-walled
   corridor fills its right third and a blue recycling bin sits mid-frame, and
   no crop of a 3:4 source into a landscape viewport can exclude both. This is
   also the most information-dense section on the page, so it takes a heavier
   and more even grade than the rest — the photograph stays as texture behind
   the numerals rather than as a lit subject. */
.promo-scope .promo-scene--season .promo-scrim {
  background:
    linear-gradient(to right, rgba(4, 6, 9, .95) 0%, rgba(4, 6, 9, .91) 45%, rgba(4, 6, 9, .82) 100%),
    linear-gradient(to top, rgba(4, 6, 9, .86), rgba(4, 6, 9, .58) 70%);
}

/* Gold accumulation: a per-scene veil, strength set by --promo-gold.
   0 → .08 → .03 → .06 → .52 → .30 → (none) → .16
   ::after, not ::before, so the veil paints above the scrim exactly as it
   does in the approved prototype. */
.promo-scope .promo-scene::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  opacity: var(--promo-gold, 0);
  background:
    radial-gradient(90% 70% at 50% 60%, rgba(255, 207, 92, .30), transparent 68%),
    linear-gradient(to top, rgba(255, 190, 70, .16), transparent 55%);
}
.promo-scope .promo-scene--season  { --promo-gold: .08; }
.promo-scope .promo-scene--week    { --promo-gold: .03; }
.promo-scope .promo-scene--flights { --promo-gold: .06; }
.promo-scope .promo-scene--majors  { --promo-gold: .52; }
.promo-scope .promo-scene--prizes  { --promo-gold: .30; }
.promo-scope .promo-door           { --promo-gold: .16; }

.promo-scope .promo-scene-inner {
  position: relative; z-index: 2;
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 64px) clamp(48px, 9vh, 110px);
}
/* Information sections: content-driven height, breathing room top and bottom */
.promo-scope .promo-scene--info { align-items: center; }
.promo-scope .promo-scene--info .promo-scene-inner { padding-block: clamp(80px, 12vh, 150px); }
/* information keeps to its lane so the photograph is never fully papered over */
.promo-scope .promo-scene--info .promo-display,
.promo-scope .promo-scene--info .promo-lede,
.promo-scope .promo-scene--info .promo-numerals,
.promo-scope .promo-scene--info .promo-facts,
.promo-scope .promo-scene--info .promo-plates,
.promo-scope .promo-scene--info .promo-steps { max-width: var(--promo-col); }

/* ============================================================
   TYPOGRAPHY
   ============================================================ */
.promo-scope .promo-display {
  font-family: var(--font-cond);
  font-weight: 800; font-style: italic;
  text-transform: uppercase;
  line-height: .95;
  letter-spacing: .005em;
  margin: 0;
  text-wrap: balance;
  overflow-wrap: anywhere;
  text-shadow: 0 4px 40px rgba(0, 0, 0, .7);
}
.promo-scope .promo-display--hero { font-size: clamp(40px, 8.4vw, 104px); max-width: 15ch; }
.promo-scope .promo-display--lg   { font-size: clamp(30px, 5.4vw, 64px); max-width: 18ch; }
.promo-scope .promo-display--md   { font-size: clamp(25px, 3.6vw, 44px); max-width: 22ch; }

.promo-scope .promo-lede {
  color: var(--grey-1);
  font-size: clamp(15px, 1.5vw, 18px);
  max-width: 52ch;
  margin: 18px 0 0;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .7);
}
.promo-scope .promo-lede strong { color: var(--white); font-weight: 600; }
.promo-scope .promo-lede-mark { color: var(--signal); }

.promo-scope .promo-eyebrow {
  font-family: var(--font-cond);
  font-weight: 700; letter-spacing: .26em; text-transform: uppercase;
  font-size: 13px; color: var(--grey-2); margin: 0 0 14px;
}
.promo-scope .promo-wordmark {
  font-family: var(--font-cond); font-weight: 700; font-style: italic;
  letter-spacing: .16em; text-transform: uppercase; font-size: 14px;
  color: var(--grey-1);
}
.promo-scope .promo-wordmark em { color: var(--signal); font-style: italic; }

/* ============================================================
   STATUS, CHIPS, BUTTONS
   ============================================================ */
.promo-scope .promo-status {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; font-size: 13px;
  color: var(--grey-1); margin: 0;
}
.promo-scope .promo-status--block { display: flex; margin-top: 20px; }
.promo-scope .promo-status-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--grey-2);
  flex: none;
}
.promo-scope .promo-status.is-open { color: var(--signal); }
.promo-scope .promo-status.is-open .promo-status-dot { background: var(--signal); }

.promo-scope .promo-facts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
.promo-scope .promo-fact {
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; font-size: 14px;
  color: var(--grey-1);
  border: 1px solid var(--line-2);
  background: rgba(8, 11, 15, .55);
  padding: 8px 15px;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%);
}
.promo-scope .promo-fact--gold { color: var(--trophy); border-color: rgba(255, 207, 92, .4); }

.promo-scope .promo-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }
.promo-scope .promo-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--promo-tap); padding: 0 30px;
  font-family: var(--font-cond); font-weight: 700; font-size: 18px;
  letter-spacing: .1em; text-transform: uppercase; text-align: center;
  border: 1px solid transparent; background: transparent; color: var(--white);
  transition: background 160ms, color 160ms, border-color 160ms, filter 160ms;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%);
}
.promo-scope .promo-btn--primary { background: var(--signal); color: var(--signal-ink); }
.promo-scope .promo-btn--primary:hover { filter: brightness(1.08); }
.promo-scope .promo-btn--ghost { border-color: var(--line-2); color: var(--white); background: rgba(8, 11, 15, .5); }
.promo-scope .promo-btn--ghost:hover { background: rgba(255, 255, 255, .1); }
.promo-scope .promo-btn--block { width: 100%; }
.promo-scope .promo-btn--sm { min-height: 44px; padding: 0 18px; font-size: 15px; flex: none; }

/* ============================================================
   SCENE 1 — LEAGUE NIGHT
   The spec rail answers "what is this league" in the first frame, so no
   visitor has to scroll to find out. It is a machined plate along the
   floor of the photograph, not a row of feature cards.
   ============================================================ */
.promo-scope .promo-hero { min-height: calc(100vh - 58px); min-height: calc(100svh - 58px); }
.promo-scope .promo-hero .promo-scene-inner { padding-bottom: clamp(90px, 15vh, 150px); }
.promo-scope .promo-hero-prize {
  width: min(100%, 520px);
  min-width: 0;
  margin: 0 0 clamp(20px, 3.5vh, 34px);
  padding-left: clamp(12px, 1.5vw, 18px);
  border-left: 2px solid rgba(255, 207, 92, .62);
}
.promo-scope .promo-hero-prize-label {
  margin: 0;
  color: var(--grey-1);
  font-family: var(--font-cond); font-size: clamp(11px, 1.2vw, 13px); font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase;
}
.promo-scope .promo-hero-prize-value {
  max-width: 100%;
  margin: 5px 0 0;
  color: var(--trophy);
  font-family: var(--font-cond); font-size: clamp(38px, 5.6vw, 68px); font-style: italic; font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: .92;
  overflow-wrap: anywhere;
  text-shadow: 0 4px 32px rgba(0, 0, 0, .72);
}
.promo-scope .promo-hero-prize-support {
  margin: 8px 0 0;
  color: var(--signal);
  font-family: var(--font-cond); font-size: clamp(13px, 1.4vw, 16px); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
.promo-scope .promo-hero-prize-sponsored {
  max-width: 100%;
  margin: 9px 0 0;
  color: var(--grey-1);
  font-family: var(--font-cond); font-size: clamp(12px, 1.25vw, 14px); font-weight: 700;
  letter-spacing: .05em;
  overflow-wrap: anywhere;
}
.promo-scope .promo-head {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 0 0 18px;
}
.promo-scope .promo-head-rule { width: 40px; height: 1px; background: var(--line-2); }

.promo-scope .promo-specrail {
  display: flex; flex-wrap: wrap; gap: 0;
  margin-top: 34px;
  border: 1px solid var(--line-1);
  border-left: 2px solid rgba(184, 242, 75, .55);
  background: linear-gradient(180deg, rgba(20, 24, 33, .86), rgba(8, 11, 15, .92));
  max-width: 920px;
}
.promo-scope .promo-specrail-cell {
  flex: 1 1 168px; min-width: 0;
  padding: 13px 20px;
  border-right: 1px solid var(--line-1);
}
.promo-scope .promo-specrail-cell:last-child { border-right: 0; }
.promo-scope .promo-specrail-k {
  display: block;
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase;
  font-size: 10.5px; color: var(--grey-2);
}
.promo-scope .promo-specrail-v {
  display: block; margin-top: 3px;
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  font-size: 17px; color: var(--white);
  font-variant-numeric: tabular-nums;
}

.promo-scope .promo-scroll-cue {
  position: absolute; left: 50%; bottom: 20px; transform: translateX(-50%);
  z-index: 3; width: var(--promo-tap); height: var(--promo-tap);
  display: grid; place-items: center; color: var(--grey-1);
}
.promo-scope .promo-scroll-cue svg { width: 26px; height: 26px; }
@media (prefers-reduced-motion: no-preference) {
  .promo-scope .promo-scroll-cue svg { animation: promo-cue 2.6s ease-in-out infinite; }
}
@keyframes promo-cue {
  0%, 100% { transform: translateY(0); opacity: .65; }
  50% { transform: translateY(7px); opacity: 1; }
}

/* ============================================================
   NUMERALS — numerals outrank letters.
   ============================================================ */
.promo-scope .promo-numerals {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: clamp(26px, 6vw, 82px); margin-top: 34px;
}
.promo-scope .promo-numeral { display: flex; flex-direction: column; }
.promo-scope .promo-numeral-value {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  line-height: .8; letter-spacing: -.02em;
  font-size: clamp(84px, 16vw, 190px);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 8px 60px rgba(0, 0, 0, .7);
}
.promo-scope .promo-numeral--gold .promo-numeral-value { color: var(--trophy); }
.promo-scope .promo-numeral-label {
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .34em; text-transform: uppercase;
  font-size: clamp(12px, 1.5vw, 18px); color: var(--grey-1); margin-top: 12px;
}

/* ============================================================
   PLATE — the information object.
   A machined slab with a raking highlight and a single accent edge.
   Green edge = live/included. Gold edge = money/earned.
   Never more than three across; never a uniform tile wall.
   ============================================================ */
.promo-scope .promo-plates { display: grid; gap: 14px; margin-top: 34px; }
@media (min-width: 760px) {
  .promo-scope .promo-plates--2 { grid-template-columns: repeat(2, 1fr); }
  .promo-scope .promo-plates--3 { grid-template-columns: repeat(3, 1fr); }
}
/* a lone plate must not stretch the full information column */
.promo-scope .promo-plates--1 { max-width: 460px; }
.promo-scope .promo-plate {
  position: relative;
  padding: 22px 22px 24px;
  background: linear-gradient(180deg, rgba(22, 27, 37, .90), rgba(9, 12, 17, .94));
  border: 1px solid var(--line-1);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%);
}
/* the raking highlight that makes the slab read as metal, not as a div */
.promo-scope .promo-plate::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, .02) 62%);
}
.promo-scope .promo-plate::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--signal); opacity: .62;
}
.promo-scope .promo-plate--gold::after { background: var(--trophy); opacity: .78; }
.promo-scope .promo-plate--quiet::after { background: var(--line-2); opacity: 1; }
/* Prizes are money, but the championship frame two scenes earlier is the
   gold peak. These plates take gold on the kicker only, so the ramp keeps
   rising toward the crown instead of flattening into a wall of gold. */
.promo-scope .promo-plate--prize .promo-plate-k { color: var(--trophy); }

.promo-scope .promo-plate-k {
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase;
  font-size: 11px; color: var(--grey-2); margin: 0 0 10px;
}
.promo-scope .promo-plate-h {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: .01em; line-height: 1.02;
  font-size: clamp(20px, 2.3vw, 27px); margin: 0; color: var(--white);
}
.promo-scope .promo-plate--gold .promo-plate-h { color: var(--trophy); }
.promo-scope .promo-plate-p { color: var(--grey-1); font-size: 14.5px; margin: 10px 0 0; }

/* ============================================================
   STEPS — what actually happens in a week. A sequence, not a card grid.
   ============================================================ */
.promo-scope .promo-steps {
  display: grid; gap: 0; margin: 34px 0 0; padding: 0; list-style: none;
}
@media (min-width: 760px) { .promo-scope .promo-steps { grid-template-columns: repeat(3, 1fr); } }
.promo-scope .promo-step {
  position: relative;
  padding: 20px 22px 22px;
  border-top: 1px solid var(--line-2);
  background: linear-gradient(180deg, rgba(10, 13, 18, .62), rgba(10, 13, 18, .18));
}
@media (min-width: 760px) {
  .promo-scope .promo-step { border-right: 1px solid var(--line-1); }
  .promo-scope .promo-step:last-child { border-right: 0; }
}
.promo-scope .promo-step-n {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  font-size: 15px; letter-spacing: .1em; color: var(--signal);
  font-variant-numeric: tabular-nums;
}
.promo-scope .promo-step-h {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  text-transform: uppercase; font-size: clamp(19px, 2.1vw, 24px);
  line-height: 1.04; margin: 8px 0 0; color: var(--white);
}
.promo-scope .promo-step-p { color: var(--grey-1); font-size: 14.5px; margin: 8px 0 0; }

/* ============================================================
   LEDGER — the honest answer to "what am I actually buying?"
   Two opposed columns. This is the section that must never be ambiguous.
   ============================================================ */
.promo-scope .promo-ledger { display: grid; gap: 16px; margin-top: 30px; }
@media (min-width: 820px) { .promo-scope .promo-ledger { grid-template-columns: 1fr 1fr; } }
.promo-scope .promo-ledger-col {
  padding: 24px 24px 26px;
  background: rgba(8, 11, 15, .88);
  border: 1px solid var(--line-1);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%);
}
.promo-scope .promo-ledger-col--in { border-top: 2px solid var(--signal); }
.promo-scope .promo-ledger-col--out { border-top: 2px solid var(--trophy); }
.promo-scope .promo-ledger-h {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: .04em;
  font-size: clamp(19px, 2.1vw, 24px); margin: 0; color: var(--white);
}
.promo-scope .promo-ledger-col--in .promo-ledger-h { color: var(--signal); }
.promo-scope .promo-ledger-col--out .promo-ledger-h { color: var(--trophy); }
.promo-scope .promo-ledger-list { list-style: none; margin: 16px 0 0; padding: 0; }
.promo-scope .promo-ledger-list li {
  position: relative; padding-left: 26px; margin-top: 11px;
  color: var(--grey-1); font-size: 15px; line-height: 1.5;
}
.promo-scope .promo-ledger-list li strong { color: var(--white); font-weight: 600; }
.promo-scope .promo-ledger-list li::before {
  position: absolute; left: 0; top: 0;
  font-family: var(--font-cond); font-weight: 800; font-size: 15px;
}
.promo-scope .promo-ledger-col--in .promo-ledger-list li::before { content: "+"; color: var(--signal); }
.promo-scope .promo-ledger-col--out .promo-ledger-list li::before { content: "\2212"; color: var(--trophy); }
.promo-scope .promo-ledger-note { color: var(--grey-2); font-size: 14px; margin: 16px 0 0; }

/* ============================================================
   SCENE 7 — THE DIGITAL CLUBHOUSE (sticky on desktop)
   Placed seventh on purpose: the board is the proof that the season
   continues after the round. It is never the hero of this page.

   The image is a pre-cropped, sponsor-free detail of the real product,
   presented in perspective with glass bloom and a reflection, which is
   how this brand shows its own software.
   ============================================================ */
.promo-scope .promo-wall {
  position: relative; display: block;
  background:
    radial-gradient(120% 80% at 20% 40%, rgba(20, 32, 18, .55), transparent 70%),
    var(--carbon-0);
}
.promo-scope .promo-wall-grid { display: block; }

.promo-scope .promo-wall-stage {
  position: relative;
  display: grid; place-items: center;
  padding: clamp(40px, 7vw, 80px) clamp(18px, 4vw, 56px);
  overflow: hidden;
}
/* the screen is the light of the scene — it lights the room back */
.promo-scope .promo-wall-stage::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(60% 45% at 50% 45%, rgba(120, 200, 60, .22), transparent 72%);
  pointer-events: none;
}

.promo-scope .promo-board {
  position: relative;
  width: 100%; max-width: 720px;
  aspect-ratio: 900 / 382;
  overflow: hidden;
  margin: 0;
  background: var(--carbon-1);
  border: 1px solid rgba(255, 255, 255, .10);
  box-shadow:
    0 44px 100px rgba(0, 0, 0, .8),
    0 0 80px rgba(140, 220, 70, .15);
  /* enough rotation to read as a panel in a room rather than a flat asset;
     below about 10deg at this perspective the effect is invisible */
  transform: perspective(1150px) rotateY(-11deg) rotateX(2deg);
  transform-origin: 62% 50%;
}
.promo-scope .promo-board img { width: 100%; height: 100%; object-fit: cover; }
/* glass: a sweeping bloom and the room reflected off the panel */
.promo-scope .promo-board::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .18) 0%, rgba(255, 255, 255, .03) 26%, transparent 52%),
    linear-gradient(to top, rgba(4, 6, 9, .45), transparent 40%);
}
/* the panel sitting on a surface, not floating in a void */
.promo-scope .promo-board-shadow {
  width: 100%; max-width: 720px; height: 90px; margin-top: -8px;
  background: radial-gradient(60% 100% at 50% 0%, rgba(120, 200, 60, .16), transparent 70%);
  filter: blur(6px);
  pointer-events: none;
}
.promo-scope .promo-board-caption {
  margin: 6px auto 0; max-width: 720px;
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  font-size: 12px; color: var(--grey-2);
}
.promo-scope .promo-board-note {
  margin: 4px auto 0; max-width: 720px;
  font-size: 12px; color: var(--grey-2);
}

.promo-scope .promo-wall-rail {
  padding: clamp(44px, 8vw, 84px) clamp(20px, 5vw, 64px) clamp(56px, 10vw, 104px);
}
.promo-scope .promo-wall-rail-inner { max-width: 1240px; margin: 0 auto; }
.promo-scope .promo-wall-note + .promo-wall-note { margin-top: clamp(38px, 7vw, 70px); }
.promo-scope .promo-wall-note p { color: var(--grey-1); margin: 14px 0 0; max-width: 46ch; font-size: 16px; }

/* what the dashboard actually holds — engraved as a list of surfaces */
.promo-scope .promo-surfaces { list-style: none; margin: 22px 0 0; padding: 0; max-width: 46ch; }
.promo-scope .promo-surfaces li {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  padding: 11px 0; border-top: 1px solid var(--line-1);
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; font-size: 16px;
}
.promo-scope .promo-surfaces li:last-child { border-bottom: 1px solid var(--line-1); }
.promo-scope .promo-surfaces span {
  color: var(--grey-2); font-size: 13.5px; letter-spacing: .04em;
  text-transform: none; font-family: var(--font-ui); font-weight: 400;
}

@media (min-width: 1000px) {
  .promo-scope .promo-wall-grid {
    display: grid;
    grid-template-columns: 1.02fr .98fr;
    gap: 0;
    align-items: start;
  }
  .promo-scope .promo-wall-stage {
    position: sticky; top: 0;
    height: 100svh;
    align-content: center;
  }
  .promo-scope .promo-board,
  .promo-scope .promo-board-shadow { max-width: 620px; }
  .promo-scope .promo-wall-rail {
    padding: 0 clamp(28px, 4vw, 72px);
    display: flex; flex-direction: column;
  }
  .promo-scope .promo-wall-note {
    min-height: 100svh;
    display: flex; flex-direction: column; justify-content: center;
  }
  .promo-scope .promo-wall-note + .promo-wall-note { margin-top: 0; }
}

/* ============================================================
   SCENE 8 — THE DOOR: the ledger, then the passes.
   ============================================================ */
.promo-scope .promo-door .promo-scene-inner { padding-block: clamp(80px, 12vh, 140px); }
/* The door stays one column at every width. Splitting it in two halves the
   registration cards and breaks "Join Open / Men's League" across three lines
   — the one place on the page where a button must never be ambiguous. */
.promo-scope .promo-door-split { display: grid; gap: clamp(48px, 7vw, 84px); }
.promo-scope .promo-door .promo-ledger,
.promo-scope .promo-door .promo-reg,
.promo-scope .promo-door .promo-fineprint,
.promo-scope .promo-door .promo-flow { max-width: 100%; }

.promo-scope .promo-reg { display: grid; gap: 16px; margin-top: 24px; }
@media (min-width: 720px) { .promo-scope .promo-reg--two { grid-template-columns: 1fr 1fr; } }

.promo-scope .promo-sponsor-details {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
  color: var(--grey-2);
  font-size: 13px;
}
.promo-scope .promo-sponsor-details li + li { margin-top: 7px; }

/* the entry pass: a dark card with a machined gold top edge */
.promo-scope .promo-reg-card {
  position: relative;
  background: linear-gradient(180deg, rgba(20, 25, 34, .94), rgba(8, 11, 15, .96));
  border: 1px solid var(--line-2);
  padding: 26px 24px;
  display: flex; flex-direction: column; gap: 12px;
}
.promo-scope .promo-reg-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--trophy), rgba(255, 207, 92, .15));
}
.promo-scope .promo-reg-label {
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; font-size: 15px;
  color: var(--grey-1); margin: 0;
}
.promo-scope .promo-reg-price {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  font-size: clamp(32px, 4vw, 46px); line-height: 1; color: var(--trophy);
  margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
}
.promo-scope .promo-reg-note { color: var(--grey-2); font-size: 14px; margin: 0; }
.promo-scope .promo-reg-card .promo-btn { margin-top: auto; }

.promo-scope .promo-reg-closed {
  border: 1px dashed var(--line-2);
  background: rgba(8, 11, 15, .86);
  padding: 26px 24px; max-width: 580px; margin-top: 24px;
}
.promo-scope .promo-reg-closed p { margin: 8px 0 0; color: var(--grey-1); }

/* the two registration paths, carried over from the previous page */
.promo-scope .promo-flow { display: grid; gap: 14px; margin-top: 30px; }
@media (min-width: 720px) { .promo-scope .promo-flow { grid-template-columns: 1fr 1fr; } }
.promo-scope .promo-flow-card {
  padding: 20px 22px;
  background: rgba(8, 11, 15, .8);
  border: 1px solid var(--line-1);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%);
}
.promo-scope .promo-flow-card h3 {
  font-family: var(--font-cond); font-weight: 800; font-style: italic;
  text-transform: uppercase; font-size: 19px; line-height: 1.05;
  margin: 0; color: var(--white);
}
.promo-scope .promo-flow-card p { color: var(--grey-1); font-size: 14.5px; margin: 8px 0 0; }

.promo-scope .promo-fineprint {
  margin-top: 26px;
  border-left: 3px solid rgba(255, 207, 92, .5);
  padding: 13px 18px;
  background: rgba(255, 207, 92, .07);
  color: var(--grey-1); font-size: 13.5px; line-height: 1.6;
}
.promo-scope .promo-fineprint strong { color: var(--white); }

/* ============================================================
   MOBILE STICKY JOIN BAR — appears after the hero, hidden when closed
   ============================================================ */
.promo-scope .promo-joinbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: none; align-items: center; gap: 12px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: rgba(6, 8, 11, .95);
  border-top: 1px solid var(--line-2);
  transform: translateY(110%);
  transition: transform 260ms var(--promo-ease);
}
.promo-scope .promo-joinbar.is-visible { transform: none; }
.promo-scope .promo-joinbar-name {
  flex: 1; min-width: 0;
  font-family: var(--font-cond); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; font-size: 15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@media (max-width: 999px) {
  body.promo-scope.promo-has-cta .promo-joinbar { display: flex; }
  /* without JS the bar can never be revealed, so show it at rest */
  html:not(.promo-js) .promo-scope .promo-joinbar { transform: none; }
}

/* ============================================================
   REVEALS — crossfade discipline (opacity + a small lift only)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.promo-js .promo-scope [data-reveal] {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity var(--promo-slow) var(--promo-ease),
                transform var(--promo-slow) var(--promo-ease);
  }
  html.promo-js .promo-scope [data-reveal].is-in { opacity: 1; transform: none; }
  html.promo-js .promo-scope [data-reveal][data-delay="1"] { transition-delay: 130ms; }
  html.promo-js .promo-scope [data-reveal][data-delay="2"] { transition-delay: 260ms; }
}

/* ============================================================
   MOBILE — built for ~390px, not a shrunken desktop

   The portrait 3:4 photography is native here: at 390x844 the container is
   narrower than the source, so `object-fit: cover` fits the full height and
   crops only the sides. Almost the whole frame survives, which is why the
   phone gets the strongest version of these images.
   ============================================================ */
@media (max-width: 999px) {
  .promo-scope .promo-scene { align-items: flex-end; }
  .promo-scope .promo-scene-inner { padding-bottom: clamp(40px, 8vh, 84px); }
  .promo-scope .promo-scene--info { align-items: flex-start; }
  .promo-scope .promo-scene--info .promo-scene-inner { padding-block: clamp(56px, 9vh, 96px); }

  /* height-driven crop: object-position Y does nothing here (the full height
     already fits), so biasing the hero toward the people means scaling up and
     translating — otherwise the top 200px is dead ceiling. */
  .promo-scope .promo-scene-media img { object-position: center center; }
  .promo-scope .promo-hero .promo-scene-media img { --promo-zoom: 1.16; --promo-ty: -5%; }
  .promo-scope .promo-scene--season .promo-scene-media img { object-position: 28% center; } /* keeps the recycling bin out of frame */
  .promo-scope .promo-scene--majors .promo-scene-media img { object-position: 52% center; } /* landscape source: hold the crown */

  /* At 390px the copy spans the full width, so the horizontal grade that
     protects a desktop column only buries the photograph. Bottom-weighted
     only, on both scrims. */
  .promo-scope .promo-scrim--bottom {
    background: linear-gradient(to top,
      rgba(4, 6, 9, .93) 0%, rgba(4, 6, 9, .74) 34%,
      rgba(4, 6, 9, .34) 66%, rgba(4, 6, 9, .48) 100%);
  }
  .promo-scope .promo-scrim--deep {
    background: linear-gradient(to top,
      rgba(4, 6, 9, .95) 0%, rgba(4, 6, 9, .86) 45%, rgba(4, 6, 9, .58) 100%);
  }

  .promo-scope .promo-display--hero { font-size: clamp(38px, 12vw, 60px); }
  .promo-scope .promo-hero-prize { margin-bottom: 18px; padding-left: 12px; }
  .promo-scope .promo-hero-prize-value { font-size: clamp(36px, 11vw, 50px); }
  .promo-scope .promo-hero-prize-sponsored { max-width: 32ch; }
  .promo-scope .promo-specrail { margin-top: 26px; }
  .promo-scope .promo-specrail-cell { flex: 1 1 50%; border-bottom: 1px solid var(--line-1); }
  .promo-scope .promo-specrail-cell:nth-child(2n) { border-right: 0; }
  .promo-scope .promo-specrail-cell:nth-last-child(-n+2) { border-bottom: 0; }

  .promo-scope .promo-actions .promo-btn { width: 100%; }
  .promo-scope .promo-numerals { gap: 30px; }
  .promo-scope .promo-board { transform: none; }

  /* the join bar must never cover the last actionable thing on the page */
  body.promo-scope.promo-has-cta .promo-door .promo-scene-inner { padding-bottom: 116px; }
}

/* very small phones: the hero must still hold a headline and a CTA */
@media (max-width: 360px) {
  .promo-scope .promo-display--hero { font-size: clamp(32px, 11vw, 44px); }
  .promo-scope .promo-specrail-cell { padding: 11px 14px; }
  .promo-scope .promo-scene-inner { padding-left: 16px; padding-right: 16px; }
  .promo-scope .promo-joinbar-name { font-size: 13px; }
}

/* short landscape phones: never trap the visitor in a full-height hero */
@media (max-height: 520px) {
  .promo-scope .promo-hero { min-height: 0; }
  .promo-scope .promo-hero .promo-scene-inner { padding-top: 84px; padding-bottom: 56px; }
  .promo-scope .promo-scroll-cue { display: none; }
}

@media print {
  .promo-scope .promo-joinbar,
  .promo-scope .promo-scroll-cue,
  .promo-scope .promo-skip { display: none !important; }
}

/* ============================================================
   REDUCED MOTION — the page must work as a poster.
   tokens.css already disables all animation/transition inside .pub-scope;
   these rules make sure nothing is left mid-state when it does.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .promo-scope [data-reveal] { opacity: 1; transform: none; }
  /* remove the settle, keep the crop */
  .promo-scope .promo-scene-media img { --promo-drift: 0; }
}
