/* ===== Landing page styling =====
   Every pure-marketing section of the landing page: the sticky top nav, the paper-themed
   .btn/.btn--* button family (the landing page's own — distinct from the portal drawer's
   dark-admin .btn-primary/.btn-secondary/.btn-danger in portal-shell.css, which a check of
   every class="..." usage in this file confirmed are never mixed: .btn/.btn--* markup
   appears only in the landing sections landing_page.js builds, .btn-primary/.btn-secondary
   only inside the portal drawer + the legal-ack/race-tour-prompt overlays), the sunset
   stripe, hero, big quote, tandem lanes, how-it-works, events, news, hall of fame,
   leaderboards, FAQ, final CTA, footer, scroll-reveal animation classes, and the auth
   modal. index.html decomposition slice 9 (README_BACKLOG.md) — extracted verbatim from
   that file's first inline <style> block. Linked by index.html, after base.css */

/* ===== LANDING NAV ===== */
#siteNav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in oklab, var(--paper) 92%, transparent);
  backdrop-filter: saturate(120%);
  -webkit-backdrop-filter: saturate(120%);
  border-bottom: 1px solid color-mix(in oklab, var(--ink) 12%, transparent);
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 28px;
  font-family: var(--arch);
  font-size: 0.8125rem;
  letter-spacing: 0.3px;
}
.thin-nav__brand {
  font-family: var(--marker);
  font-size: 0.9375rem;
  letter-spacing: 0.5px;
  margin-right: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink);
  text-decoration: none;
}
#siteNav a {
  position: relative;
  color: var(--ink);
  text-decoration: none;
  opacity: 0.78;
  transition:
    opacity 0.15s,
    color 0.15s;
}
#siteNav a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -5px;
  height: 2px;
  background: var(--accent-red);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.2s ease;
}
#siteNav a:hover,
#siteNav a:focus-visible {
  opacity: 1;
  color: var(--accent-red);
}
#siteNav a:hover::after,
#siteNav a:focus-visible::after {
  transform: scaleX(1);
}
.nav-hide-mobile {
  display: flex;
  gap: 20px;
  align-items: center;
}
#navUserArea {
  display: none;
  align-items: center;
  gap: 10px;
  /* Anchors notifications/bell.js's #navNotifBellPanel dropdown (appended as this
     element's own child) to the nav's right edge instead of the page body. */
  position: relative;
}
/* A returning rider's page while Firebase restores the session (index.html's head
   script + landing_page.js's settleAuthHint): no flash of the logged-out nav. */
.auth-pending #navLoginBtn,
.auth-pending #navGuestBtn {
  visibility: hidden;
}
#navUserPhoto {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  display: none;
}
.nav-user-name {
  font-family: var(--arch);
  font-size: 0.8125rem;
  max-width: 220px;
  white-space: nowrap;
}
#navUserFlag {
  font-size: 1.25rem;
  line-height: 1;
}
.hamburger-btn {
  background: none;
  border: 2px solid var(--ink);
  border-radius: var(--r-sm);
  padding: 5px 8px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: transform 0.12s;
}
.hamburger-btn:hover {
  transform: scale(1.05);
}
.hamburger-btn span {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--ink);
  border-radius: 2px;
}
/* "Play" — opens the full-screen portal dashboard (PT3: it used to be a
   settings gear, which read as "a settings menu", not the whole game).
   Sized to sit in the nav like the Log in button. */
.nav-play-btn {
  padding: 5px 16px;
  font-size: 0.8rem;
  box-shadow: 2px 2px 0 var(--ink);
  white-space: nowrap;
}
/* Gear-family nav button: the box the notification bell wears (the settings gear it was
   named for became the "Bike" button in PT3; the chrome stays for the bell). */
.gear-btn {
  background: none;
  border: 2px solid var(--ink);
  border-radius: var(--r-sm);
  padding: 5px 7px;
  cursor: pointer;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.12s;
}
.gear-btn:hover {
  transform: scale(1.05);
}
.gear-btn svg {
  display: block;
}
/* Nav notification bell (notifications/bell.js) — sits right before the gear button, same
   .gear-btn chrome. Colors (accent border/icon + a small dot) only while the bell actually
   holds a minimized notice; otherwise it reads identically to a plain gear-family button. */
.notif-bell-btn {
  position: relative;
}
.notif-bell-btn.has-unread {
  border-color: var(--accent-red, #d93a25);
  color: var(--accent-red, #d93a25);
}
.notif-bell-dot {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-red, #d93a25);
  border: 1.5px solid var(--paper, #fff);
}
.notif-bell-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  width: 280px;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--r-md, 10px);
  box-shadow: 4px 4px 0 var(--ink);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* [hidden] and a class setting `display` both have equal (0,1,0) specificity, and this
   stylesheet loads after the UA one, so .notif-bell-panel's own `display: flex` above would
   otherwise always win over `[hidden]`'s `display: none` — the panel rendered open no matter
   what bell.js set `.hidden` to. This rule's extra attribute selector raises its specificity
   past the bare class rule so [hidden] actually hides it again. */
.notif-bell-panel[hidden] {
  display: none;
}
.notif-bell-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  text-align: left;
  background: var(--paper-warm);
  border: 1px solid var(--ink-mute);
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  font: inherit;
}
.notif-bell-row:hover {
  border-color: var(--ink);
}
.notif-bell-row-kicker {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
}
.notif-bell-row-title {
  font-weight: 700;
  color: var(--ink);
}
.notif-bell-empty {
  padding: 14px 10px;
  color: var(--ink-mute);
  font-size: 0.85rem;
  text-align: center;
}
/* Overflow "hamburger": reveals the .nav-hide-mobile links on small
   screens. Hidden on desktop, where those links already show inline
   (shown at the same breakpoint that hides them — see the media query). */
.nav-overflow-btn {
  display: none;
}
.nav-overflow-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 12px;
  min-width: 190px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: 4px 4px 0 var(--ink);
  padding: 6px;
  display: none;
  flex-direction: column;
  gap: 2px;
  z-index: 50;
}
.nav-overflow-menu.open {
  display: flex;
}
.nav-overflow-link {
  font-family: var(--arch);
  font-size: 0.875rem;
  letter-spacing: 0.3px;
  color: var(--ink);
  text-decoration: none;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  opacity: 0.85;
  transition:
    background 0.12s,
    opacity 0.12s;
}
.nav-overflow-link:hover {
  opacity: 1;
  background: color-mix(in oklab, var(--ink) 8%, transparent);
}
/* ===== BUTTONS ===== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--arch);
  font-size: 0.875rem;
  padding: 9px 16px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  box-shadow: 3px 3px 0 var(--ink);
  transition:
    transform 0.12s,
    box-shadow 0.12s,
    filter 0.2s;
}
.btn:hover {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--ink);
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn--primary {
  background: var(--accent-red);
  color: var(--paper);
  font-weight: 700;
}
.btn--primary:hover {
  filter: drop-shadow(0 0 8px color-mix(in oklab, var(--accent-pink) 100%, transparent));
}
.btn--big {
  padding: 14px 26px;
  font-size: 1.0625rem;
}
.btn--ghost {
  background: transparent;
  box-shadow: none;
  border-style: dashed;
}

/* ===== SUNSET STRIPE ===== */
.sunset-stripe {
  height: 6px;
  background: linear-gradient(
    90deg,
    var(--accent-pink) 0%,
    var(--accent-red) 35%,
    var(--accent-yellow) 65%,
    var(--accent-blue) 100%
  );
}

/* ===== HERO ===== */
.hero-big {
  display: grid;
  grid-template-columns: 42% 1fr;
  align-items: center;
}
.hero-big__image {
  background: var(--paper-warm);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
/* YouTube Shorts embed, sized 1.5x the original 360px cap (issue: the flat
   360px cap under-filled the hero column badly compared to the old poster
   image, which used the full column width) — same 9:16 aspect ratio,
   just bigger. Tune the max-width further here if it still reads small. */
.hero-big__video-embed {
  position: relative;
  width: 100%;
  max-width: 540px;
  aspect-ratio: 9 / 16;
  max-height: max(560px, 90vh);
  /* The oversized tire tracks (see .hero-tire-smear) bleed all the way across the hero on purpose;
     this keeps the video itself painting above them instead of the track riding over it. */
  z-index: 1;
}
.hero-big__video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  border-radius: var(--r-md);
}
.hero-big__copy {
  padding: 7vh 7vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 22px;
}
.hero-big__title {
  font-family: var(--marker);
  font-size: clamp(44px, 5.5vw, 84px);
  line-height: 0.95;
  letter-spacing: 0.5px;
}
/* "Every" / "Sunday" clash: "Every" sits flush left, "Sunday" is
   indented onto the next line — like the two words skidded past each
   other.
   .hero-big__title-clash is an inline-flex column so its own width is
   set by its widest row (Sunday's indent + word). */
.hero-big__title-clash {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  margin: 64px 0 16px 72px;
  position: relative;
}
/* Wraps "Two dudes" / "One bike" purely for grouping (each line anchors its own tire tracks below,
   via .hero-big__title-top-line). */
.hero-big__title-top {
  display: inline-block;
}
/* Shrink-to-fit anchor for one line's own pair of tracks (see .hero-big__title-top-line below). */
.hero-big__title-top-line {
  position: relative;
}
/* Extra breathing room above "One bike" so its own tread lines don't crowd "Two dudes"'s —
   `margin-top` has no effect on a plain inline box, hence `inline-block` here. */
.hero-big__title-top-line--spaced {
  display: inline-block;
  margin-top: 20px;
}
/* Groups "Two dudes" with the hidden connector slot below so that slot can center under it — mirrors
   .hero-big__title-clash-top's "Occasionally"/"with" pairing, so both blocks land at 2+1+2 = 5 tread
   lines total, not 4 vs 5. */
.hero-big__title-top-pair {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}
/* No visible word here (nothing in this block names a middle connector the way "with" does) — just
   an empty, `aria-hidden` slot sized like .hero-big__title-clash-connector purely so its one tread
   has somewhere to sit, centered under "Two dudes". */
.hero-big__title-top-connector {
  font-size: 0.5em;
  margin-top: 20px;
  position: relative;
}
/* A tire ran clean across the SCREEN (not just the word) and pressed a repeating chevron TREAD into
   it — a CSS mask (shape) over a plain color fill (paint), since a mask can be tiled independently
   of the color underneath it, which a background image alone can't do. Each track is deliberately
   oversized (-100vw/300vw) relative to its own small text anchor and left to blow out past the
   viewport on both sides; base.css's `overflow-x: clip` on <html> then crops it to exactly the
   visible screen width for free, with no JS layout measurement needed at any viewport size — see
   the width/left math for why the color changeover below always lands at a constant 33.333%
   regardless of viewport or word width. `mix-blend-mode: multiply` presses the tread into the
   letters/background instead of sitting as an opaque stamp over them.

   Two coats of the SAME mask+fill, not one (see `::before`/`::after` below): a BLURRED coat (the
   "smear" bleeding between adjacent chevron stamps, where their blur haloes overlap) sitting behind
   a crisp, unblurred copy (the actual legible chevrons) painted on top of it. `--chevron-mask`/
   `--tread-fill` are custom properties (set by the `--chevron`/`--chevron-rev` and `--ink`/`--red`/
   `--blue`/`--yellow` modifiers below) purely so both coats can share the exact same shape and color
   without restating either. */
.hero-tire-smear {
  position: absolute;
  top: 50%;
  left: -100vw;
  width: 300vw;
  height: 0.5em;
  transform: translateY(-50%);
  mix-blend-mode: multiply;
  opacity: 0.6;
  pointer-events: none;
  z-index: 1;
  animation: heroTireSmearReveal 1.1s cubic-bezier(0.3, 0.7, 0.3, 1) both;
  /* A straight, continuous outline framing the whole band top and bottom — deliberately on this
     unmasked outer element, not ::after (the chevron mask would chop it into ragged fragments
     wherever the repeating pattern has a gap). */
  border-top: 1px solid rgba(29, 26, 20, 0.1);
  border-bottom: 1px solid rgba(29, 26, 20, 0.1);
}
/* The smear: a plain, UNMASKED strip of the same color/gradient, blurred soft at its own edges —
   not the chevron shape itself (a mask+blur combo on a thin repeating stroke turned out too faint
   to read against the page once composited). Painted first, so it sits behind `::after`'s crisp
   chevrons; between them it's all that shows, reading as a smeared rectangular mark the chevrons
   are stamped into, carrying the same color. Kept deliberately faint (low opacity, no bleed past
   its own box) so it reads as a light smudge, not a solid bar. */
.hero-tire-smear::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--tread-fill);
  background-repeat: no-repeat;
  filter: blur(3px);
  opacity: 0.1;
}
/* The crisp coat on top: the actual legible, unblurred chevrons. */
.hero-tire-smear::after {
  content: '';
  position: absolute;
  inset: 0;
  mask-image: var(--chevron-mask);
  -webkit-mask-image: var(--chevron-mask);
  mask-repeat: repeat-x;
  -webkit-mask-repeat: repeat-x;
  mask-position: left center;
  -webkit-mask-position: left center;
  mask-size: 34px 100%;
  -webkit-mask-size: 34px 100%;
  background-image: var(--tread-fill);
  background-repeat: no-repeat;
}
/* Every full-size line (Two dudes/One bike/Occasionally/Prizes) gets a tread line near each edge,
   like the two sides of a tire's contact patch; "with" (the one connector) stays a single centered
   line. */
.hero-tire-smear--edge-a {
  top: 26%;
}
.hero-tire-smear--edge-b {
  top: 74%;
}
/* Sinks a track behind everything it overlaps — its own word's letters AND the hero video, both of
   which paint as ordinary non-positioned/auto-z content, so any explicit negative z-index here
   bubbles up and loses to them automatically. `.hero-big__video-embed`'s own explicit z-index keeps
   it above this regardless of how far up the ancestor chain the comparison actually resolves. */
.hero-tire-smear--behind {
  z-index: -1;
}
/* The reveal-animation direction — independent of the chevron's own orientation (--chevron/
   --chevron-rev below) and of the fill gradient's own left/right story (--ink/--red/--blue/--yellow
   further down, which always anchors to the word's edge the same way regardless of this). "Two
   dudes"/"One bike" rolls in left to right (the tire's first pass); "Occasionally"/"with"/"Prizes"
   rolls in right to left, the opposite direction, as if a second pass came back the other way. Both
   finish at the same fully-revealed `inset(0 0 0 0)` — this only affects how the mark animates in on
   load. */
.hero-tire-smear--reveal-ltr {
  clip-path: inset(0 100% 0 0);
}
.hero-tire-smear--reveal-rtl {
  clip-path: inset(0 0 0 100%);
}
/* The chevron glyph itself: --chevron is the baseline left-pointing arrow every single-track line
   ("with", the hidden "and" slot) uses; --chevron-rev is its horizontal mirror, for alternating the
   two edge tracks of a two-track line into a herringbone (one normal, one reversed) instead of two
   parallel copies of the same arrow. */
.hero-tire-smear--chevron {
  --chevron-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 24'%3E%3Cpath d='M22 3 L11 12 L22 21' fill='none' stroke='%23000' stroke-width='4.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.hero-tire-smear--chevron-rev {
  --chevron-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 24'%3E%3Cpath d='M6 3 L17 12 L6 21' fill='none' stroke='%23000' stroke-width='4.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* "Two dudes" / "One bike" plays first (the tire's first pass); "Occasionally"/"with"/"Prizes" plays
   second, as if the same tire kept rolling down the page. */
.hero-tire-smear--delay-a {
  animation-delay: 0.3s;
}
.hero-tire-smear--delay-b {
  animation-delay: 1.1s;
}
/* "Two dudes / One bike" has no word color to pick up, but still darkens after the tire rolls over
   it — faded ink before, full ink after. This block travels LEFT TO RIGHT (opposite of the gradient
   below), so "after" is the opposite physical side too: faded on the left (not reached yet, since the
   tire starts from the left here), full ink on the right (already passed). */
.hero-tire-smear--ink {
  --tread-fill: linear-gradient(90deg, rgba(29, 26, 20, 0.25) 0% 33.333%, var(--ink) 46% 100%);
}
/* "Occasionally" / "with" / "Prizes" each pick up their own word's full-saturation color on the
   screen-left side, fading to faded ink (black) — same value as --ink's own "not reached" stop —
   on the screen-right side. These tracks reveal-in right to left (see --reveal-rtl above): the
   right edge (ink) is what's still hidden early in that animation, and the left edge (color) is
   what's already settled by the time it finishes, so the ink-to-color story reads in step with the
   reveal sweep instead of fighting it. The source is one continuous gradient (never tiled) sitting
   BEHIND the repeating chevron mask, with the changeover landing right at the word's own left edge:
   this element's own local origin sits 100vw before that edge (see `left: -100vw` above) inside a
   300vw-wide box, so the word's left edge is always exactly 100vw / 300vw = 33.333% into it,
   however wide the actual viewport or word happens to be. Keeping this at 90deg (not 270deg) is
   what keeps that 33.333% changeover point — and not just one flat color — inside the visible
   100vw window: a 270deg gradient mirrors which PHYSICAL side of the whole 300vw band each color
   sits on, not just which side of the word's own edge it reads on, so it can push the entire
   transition band off-screen depending on how far across the viewport the word happens to sit. */
.hero-tire-smear--red {
  --tread-fill: linear-gradient(
    90deg,
    var(--accent-red) 0% 33.333%,
    rgba(29, 26, 20, 0.25) 25% 100%
  );
}
.hero-tire-smear--blue {
  --tread-fill: linear-gradient(
    90deg,
    var(--accent-blue) 0% 33.333%,
    rgba(29, 26, 20, 0.25) 25% 100%
  );
}
.hero-tire-smear--yellow {
  --tread-fill: linear-gradient(
    90deg,
    var(--accent-yellow) 0% 33.333%,
    rgba(29, 26, 20, 0.25) 25% 100%
  );
}
@keyframes heroTireSmearReveal {
  to {
    clip-path: inset(0 0 0 0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero-tire-smear {
    animation: none;
  }
  .hero-tire-smear--reveal-ltr,
  .hero-tire-smear--reveal-rtl {
    clip-path: inset(0 0 0 0);
  }
}
/* Groups "Occasionally" with "with" so the connector can center under it (align-items: center) —
   its own width is set by "Occasionally", the wider of the two — independent of "Prizes"' indent
   below, which still comes from the outer .hero-big__title-clash column's flex-start. */
.hero-big__title-clash-top {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.hero-big__title-clash-line1 {
  color: var(--accent-red);
  text-shadow: 4px 4px 0 var(--ink);
  position: relative;
}
/* Half the size of the two flanking lines and a contrasting cool blue against their warm
   red/yellow, so "with" reads as a connector between them rather than a third headline. */
.hero-big__title-clash-connector {
  font-size: 0.5em;
  color: var(--accent-blue);
  text-shadow: 3px 3px 0 var(--ink);
  margin-top: 0.1em;
  position: relative;
}
.hero-big__title-clash-line2 {
  color: var(--accent-yellow);
  text-shadow: 4px 4px 0 var(--ink);
  margin-left: 2.4em;
  position: relative;
}
.hero-big__lede {
  font-size: clamp(17px, 1.5vw, 21px);
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 32ch;
}
.hero-big__countdown {
  display: flex;
  align-items: baseline;
  gap: 12px;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 16px;
  border-radius: var(--r-md);
  width: fit-content;
}
.hero-big__countdown .digits {
  font-family: var(--mono);
  font-size: 2.75rem;
  letter-spacing: 2px;
  line-height: 1;
  color: var(--accent-yellow);
}
.hero-big__countdown .label {
  font-family: var(--arch);
  font-size: 0.6875rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.hero-big__cta-row {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
/* Prize CTA reuses the same gold used on the hero poster art's lettering
   (--accent-yellow) so it visually ties back to the "win prizes" poster copy. */
.hero-big__event-cta--prize {
  background: var(--accent-yellow);
  font-weight: 700;
}
.hero-big__event-cta--fun {
  font-size: 0.75rem;
  padding: 7px 14px;
}
.hero-big__hint {
  font-family: var(--hand);
  font-size: 1.125rem;
  color: var(--ink-mute);
}

/* ===== ROUTE INTRO (PT4) =====
   A dashboard URL (/play, /training, ...) opened while signed out: what that section is, above
   the landing page (site_routes.js's buildRouteIntroHtml; index.html itself carries none). */
.route-intro {
  border-bottom: 2px solid var(--ink);
  background: var(--paper-warm);
  padding: 28px 28px 30px;
}
.route-intro__inner {
  max-width: 880px;
  margin: 0 auto;
}
.route-intro__kicker {
  font-family: var(--arch);
  font-size: 0.6875rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.route-intro__title {
  font-family: var(--marker);
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  line-height: 1.05;
  margin: 6px 0 10px;
}
.route-intro__text {
  font-family: var(--kalam);
  font-size: 1.125rem;
  color: var(--ink-soft);
  margin: 0 0 16px;
  max-width: 60ch;
}
.route-intro__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.route-intro__more {
  align-self: center;
  font-family: var(--arch);
  font-size: 0.875rem;
  color: var(--ink);
}
.auth-guest-btn {
  margin-top: 16px;
  width: 100%;
  justify-content: center;
}
/* A returning rider on a dashboard URL: the dashboard frame shows while the session restores
   (index.html's head script; site_nav.js preselects the section, openPortalDrawer takes over). */
html.dashboard-pending #portalContainer {
  display: flex;
}
html.dashboard-pending body {
  overflow: hidden;
}

/* ===== BIG QUOTE ===== */
.bigquote {
  position: relative;
  padding: 16vh 8vw;
  overflow: hidden;
  isolation: isolate;
  color: var(--paper);
}
.bigquote__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: grayscale(20%) contrast(1.05) brightness(0.5);
  z-index: -2;
}
.bigquote::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      ellipse at 30% 50%,
      color-mix(in oklab, var(--accent-pink) 55%, transparent),
      transparent 60%
    ),
    radial-gradient(
      ellipse at 80% 70%,
      color-mix(in oklab, var(--accent-blue) 45%, transparent),
      transparent 60%
    ),
    linear-gradient(180deg, transparent 0%, color-mix(in oklab, var(--ink) 60%, transparent) 100%);
  z-index: -1;
  pointer-events: none;
}
.bigquote p {
  font-family: var(--marker);
  font-size: clamp(32px, 4vw, 60px);
  line-height: 1.05;
  margin: 0;
  max-width: 22ch;
  text-shadow:
    0 0 18px color-mix(in oklab, var(--accent-pink) 60%, transparent),
    3px 3px 0 var(--ink);
}
.bigquote .who {
  margin-top: 22px;
  font-family: var(--hand);
  font-size: 1.375rem;
  color: var(--accent-yellow);
}

/* ===== TANDEM LANES ===== */
.tandem-lane {
  --p: 0;
  position: relative;
  width: 100%;
  height: var(--lane-h, 240px);
  overflow: hidden;
  pointer-events: none;
  margin: -40px 0;
  z-index: 6;
}
.tandem-lane .rider {
  position: absolute;
  left: 0;
  top: 50%;
  height: 92%;
  width: auto;
  transform: translateX(calc(var(--p) * (100vw + 260%) - 130%)) translateY(-50%) rotate(-1.5deg);
  filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.25));
  will-change: transform;
}
.tandem-lane .rider img {
  height: 100%;
  width: auto;
  display: block;
}
.tandem-lane.is-reverse .rider {
  transform: translateX(calc((1 - var(--p)) * (100vw + 260%) - 130%)) translateY(-50%)
    rotate(1.5deg) scaleX(-1);
}
@media (prefers-reduced-motion: reduce) {
  .tandem-lane {
    display: none !important;
  }
}

/* ===== HOW IT WORKS ===== */
.bigsec {
  max-width: 1280px;
  margin: 0 auto;
  padding: 12vh 6vw;
}
.bigsec__kicker {
  font-family: var(--arch);
  font-size: 0.75rem;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--ink-mute);
  display: block;
  margin-bottom: 14px;
}
.bigsec__title {
  font-family: var(--marker);
  font-size: clamp(40px, 4.5vw, 68px);
  line-height: 1;
  letter-spacing: 0.5px;
  margin: 0;
}
.steprow {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8vw;
  align-items: center;
  padding: 10vh 0;
  max-width: 1280px;
  margin: 0 auto;
}
.steprow + .steprow {
  border-top: 1px solid color-mix(in oklab, var(--ink) 10%, transparent);
}
.steprow.reverse > :first-child {
  order: 2;
}
.steprow__num {
  font-family: var(--marker);
  font-size: 1.25rem;
  letter-spacing: 4px;
  color: var(--accent-red);
}
.steprow__title {
  font-family: var(--marker);
  font-size: clamp(32px, 3.5vw, 52px);
  line-height: 1;
  margin: 10px 0 16px;
  letter-spacing: 0.3px;
}
.steprow__body {
  font-size: clamp(16px, 1.3vw, 19px);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 38ch;
}
.steprow__art {
  aspect-ratio: 4 / 3;
  border-radius: var(--r-lg);
  border: 2px solid var(--ink);
  position: relative;
  overflow: hidden;
  box-shadow: 8px 8px 0 var(--ink);
}
.steprow__art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.steprow__art--a {
  background-color: color-mix(in oklab, var(--accent-yellow) 70%, var(--paper-warm));
}
.steprow__art--b {
  background-color: color-mix(in oklab, var(--accent-blue) 60%, var(--paper-warm));
}
.steprow__art--c {
  background-color: color-mix(in oklab, var(--accent-pink) 55%, var(--paper-warm));
}
.steprow__art--badge {
  position: absolute;
  left: 14px;
  top: 14px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--arch);
  font-size: 0.6875rem;
  letter-spacing: 2px;
  padding: 4px 10px;
  z-index: 2;
}

/* ===== EVENTS ===== */
.events-spacious {
  padding: 12vh 6vw;
  max-width: 1280px;
  margin: 0 auto;
}
.events-spacious__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 36px;
}
.events-spacious__head h2 {
  font-family: var(--marker);
  font-size: clamp(40px, 4.5vw, 60px);
  line-height: 1;
  margin: 0;
}
.events-spacious__note {
  font-size: clamp(15px, 1.3vw, 18px);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 52ch;
  margin: 16px 0 0;
}
.events-spacious__note strong {
  color: var(--ink);
  font-weight: 600;
}
.events-spacious__head button {
  font-family: var(--arch);
  font-size: 0.8125rem;
  letter-spacing: 1px;
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
.scroller-wrap {
  position: relative;
}
.scroll-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-70%);
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  font-size: 1.125rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 5;
  transition:
    opacity 0.2s,
    transform 0.15s;
}
.scroll-arrow:hover {
  transform: translateY(-70%) scale(1.1);
}
.scroll-arrow--left {
  left: -18px;
}
.scroll-arrow--right {
  right: -18px;
}
.scroll-arrow.hidden {
  opacity: 0;
  pointer-events: none;
}
.event-scroller {
  display: flex;
  gap: 18px;
  overflow-x: auto;
  padding: 14px 4px 28px;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.event-scroller::-webkit-scrollbar {
  display: none;
}
.event-poster {
  flex: 0 0 340px;
  background: var(--paper-warm);
  border: 3px solid var(--ink);
  border-radius: var(--r-md);
  padding: 14px;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 4px 4px 0 var(--ink);
  transform: rotate(-1.4deg);
  transition:
    transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.2s;
}
.event-poster:hover {
  transform: rotate(-1.4deg) scale(1.02) translateY(-3px);
  box-shadow: 6px 6px 0 var(--ink);
  z-index: 2;
}
/* Briefly called out after a hero "sign up" CTA scrolls it into view
   so the visitor can tell which card the button meant. */
.event-poster--highlight {
  animation: eventPosterHighlightPulse 1.6s ease-out 1;
}
@keyframes eventPosterHighlightPulse {
  0% {
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--accent-yellow) 70%, transparent);
  }
  100% {
    box-shadow: 4px 4px 0 var(--ink);
  }
}
.event-poster__art {
  position: relative;
  height: 180px;
  border-radius: var(--r-sm);
  border: 2px solid var(--ink);
  background-color: color-mix(in oklab, var(--accent-blue) 60%, var(--paper-warm));
  background-size: cover;
  background-position: center;
}
/* Diagonal "rubber stamp" prize badge — see buildPrizeStampHtml (portal.js) and
   buildEventPoster below for the two renderers that place this. */
.event-prize-stamp {
  position: absolute;
  top: 10px;
  right: -8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 11px;
  background: var(--accent-red);
  color: #fff8ec;
  border: 2px solid var(--ink);
  border-radius: 7px;
  font-family: var(--marker);
  font-size: 0.8125rem;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  text-decoration: none;
  transform: rotate(-16deg);
  box-shadow: 2px 2px 0 var(--ink);
  cursor: pointer;
  z-index: 3;
  transition: transform 0.15s ease;
  white-space: nowrap;
}
.event-prize-stamp:hover {
  transform: rotate(-16deg) scale(1.06);
}
.event-prize-stamp .ui-icon-img.event-prize-stamp-icon {
  display: inline-block;
  width: 3em;
  height: 3em;
  vertical-align: -1.1em;
}
.dudes-block h3 .ui-icon-img.section-heading-icon {
  display: inline-block;
  width: 1.7em;
  height: 1.7em;
  vertical-align: -0.32em;
  margin-right: 4px;
}
.dudes-block h3 .ui-icon-img.your-dudes-heading-icon {
  width: 2.4em;
  height: 2.4em;
  vertical-align: -0.55em;
}
label .ui-icon-img.inline-form-icon {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.22em;
}
.events-spacious__note .ui-icon-img.inline-text-icon {
  display: inline-block;
  width: 1.6em;
  height: 1.6em;
  vertical-align: -0.4em;
}
.event-poster__meta .ui-icon-img.event-poster-meta-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
}
.tandem-card__stats .ui-icon-img.tandem-card-verified-icon {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.2em;
}
.ui-icon-img.invite-joined-icon,
.ui-icon-img.admin-event-prize-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
}
.event-poster__art.swatch-red {
  background-color: color-mix(in oklab, var(--accent-red) 55%, var(--paper-warm));
}
.event-poster__art.swatch-yellow {
  background-color: color-mix(in oklab, var(--accent-yellow) 60%, var(--paper-warm));
}
.event-poster__art.swatch-blue {
  background-color: color-mix(in oklab, var(--accent-blue) 60%, var(--paper-warm));
}
.event-poster__art.swatch-pink {
  background-color: color-mix(in oklab, var(--accent-pink) 55%, var(--paper-warm));
}
.event-poster__art.swatch-lime {
  background-color: color-mix(in oklab, var(--accent-lime) 55%, var(--paper-warm));
}
.event-poster__kicker {
  font-family: var(--arch);
  font-size: 0.6875rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.event-poster__title {
  font-family: var(--marker);
  font-size: 1.375rem;
  line-height: 1.05;
}
.event-poster__desc {
  font-size: 0.875rem;
  color: var(--ink-soft);
  flex: 1;
  /* Honor the line breaks admins type into the description textarea (e.g. a
     multi-line prize breakdown) instead of collapsing them to one line. */
  white-space: pre-line;
  line-height: 1.5;
}
.event-poster__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  font-family: var(--arch);
  font-size: 0.75rem;
  color: var(--ink-soft);
}
.event-poster__spots {
  font-family: var(--hand);
  font-size: 1.125rem;
}
.event-poster__spots strong {
  color: var(--accent-red);
}
.event-poster__cta {
  margin-top: auto;
  align-self: flex-start;
}
.events-empty {
  font-family: var(--hand);
  font-size: 1.375rem;
  color: var(--ink-mute);
  padding: 40px 0;
}

/* ===== NEWS ===== */
.news-spacious {
  padding: 8vh 6vw 12vh;
  max-width: 1280px;
  margin: 0 auto;
}
.news-spacious__head {
  margin-bottom: 36px;
}
.news-spacious__head h2 {
  font-family: var(--marker);
  font-size: clamp(40px, 4.5vw, 60px);
  line-height: 1;
  margin: 0;
}
.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px;
}
.news-card {
  background: var(--paper-warm);
  border: 3px solid var(--ink);
  border-radius: var(--r-md);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 4px 4px 0 var(--ink);
  text-decoration: none;
  color: inherit;
  transition:
    transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.2s;
}
.news-card:hover {
  transform: translateY(-4px);
  box-shadow: 6px 6px 0 var(--ink);
}
.news-card__art {
  height: 160px;
  border-radius: var(--r-sm);
  border: 2px solid var(--ink);
  background-size: cover;
  background-position: center;
  background-color: color-mix(in oklab, var(--accent-lime) 55%, var(--paper-warm));
  background-image: linear-gradient(
    135deg,
    color-mix(in oklab, var(--accent-blue) 55%, var(--paper-warm)) 0%,
    color-mix(in oklab, var(--accent-pink) 45%, var(--paper-warm)) 100%
  );
}
.news-card__kicker {
  font-family: var(--arch);
  font-size: 0.6875rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.news-card__title {
  font-family: var(--marker);
  font-size: 1.25rem;
  line-height: 1.1;
}
.news-card__excerpt {
  font-size: 0.875rem;
  color: var(--ink-soft);
  flex: 1;
}
.news-card__cta {
  font-family: var(--arch);
  font-size: 0.75rem;
  letter-spacing: 0.5px;
  color: var(--ink);
  margin-top: auto;
}
.news-empty {
  font-family: var(--hand);
  font-size: 1.375rem;
  color: var(--ink-mute);
  padding: 20px 0;
}

/* ===== HALL OF FAME ===== */
.hof-spacious {
  position: relative;
  padding: 10vh 6vw;
  background: var(--ink);
  color: var(--paper);
  isolation: isolate;
  overflow: hidden;
}
.hof-spacious::before {
  content: '';
  position: absolute;
  inset: 60% -10% -10% -10%;
  background-image:
    linear-gradient(
      to right,
      color-mix(in oklab, var(--accent-pink) 65%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      to bottom,
      color-mix(in oklab, var(--accent-pink) 65%, transparent) 1px,
      transparent 1px
    );
  background-size: 5vw 5vw;
  transform: perspective(700px) rotateX(62deg);
  transform-origin: top center;
  mask-image: linear-gradient(to bottom, var(--ink) 0%, var(--ink) 60%, transparent 100%);
  /* PT1: faint enough that the text in front of it stays readable. */
  opacity: 0.2;
  z-index: -1;
}
.hof-spacious::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 22%;
  transform: translateX(-50%);
  width: min(560px, 55vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in oklab, var(--accent-yellow) 55%, transparent) 0%,
    color-mix(in oklab, var(--accent-pink) 45%, transparent) 45%,
    transparent 70%
  );
  filter: blur(20px);
  z-index: -1;
  opacity: 0.7;
}
.hof-spacious__inner {
  max-width: 1280px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}
.neon-text {
  color: var(--paper);
  text-shadow:
    0 0 8px color-mix(in oklab, var(--accent-pink) 100%, transparent),
    0 0 22px color-mix(in oklab, var(--accent-pink) 80%, transparent),
    4px 4px 0 var(--ink);
}
.tandem-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 28px;
}
.tandem-card {
  position: relative;
  background: var(--paper);
  color: var(--ink);
  border: 2px solid color-mix(in oklab, var(--accent-pink) 100%, var(--paper));
  border-radius: var(--r-md);
  padding: 18px 20px 20px;
  box-shadow:
    4px 4px 0 var(--ink),
    0 0 28px color-mix(in oklab, var(--accent-pink) 55%, transparent);
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition:
    transform 0.2s ease-out,
    box-shadow 0.2s;
}
.tandem-card:hover {
  transform: translateY(-3px);
  box-shadow:
    6px 6px 0 var(--ink),
    0 0 40px color-mix(in oklab, var(--accent-pink) 75%, transparent);
}
.tandem-card:nth-child(3n) {
  border-color: color-mix(in oklab, var(--accent-blue) 100%, var(--paper));
  box-shadow:
    4px 4px 0 var(--ink),
    0 0 28px color-mix(in oklab, var(--accent-blue) 65%, transparent);
}
.tandem-card:nth-child(3n):hover {
  box-shadow:
    6px 6px 0 var(--ink),
    0 0 40px color-mix(in oklab, var(--accent-blue) 80%, transparent);
}
.tandem-card:nth-child(3n + 1) {
  border-color: color-mix(in oklab, var(--accent-yellow) 100%, var(--paper));
  box-shadow:
    4px 4px 0 var(--ink),
    0 0 28px color-mix(in oklab, var(--accent-yellow) 65%, transparent);
}
.tandem-card:nth-child(3n + 1):hover {
  box-shadow:
    6px 6px 0 var(--ink),
    0 0 40px color-mix(in oklab, var(--accent-yellow) 80%, transparent);
}
.tandem-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 10px;
}
.tandem-card__rank {
  font-family: var(--marker);
  font-size: 2.375rem;
  line-height: 1;
  letter-spacing: 0.5px;
}
.tandem-card__flags {
  font-size: 1.875rem;
  letter-spacing: 2px;
  line-height: 1;
}
.tandem-card__names {
  font-family: var(--marker);
  font-size: 1.375rem;
  line-height: 1.1;
  letter-spacing: 0.3px;
  margin: 0;
}
.tandem-card__lore {
  font-family: var(--hand);
  font-size: 1.125rem;
  line-height: 1.25;
  color: var(--ink-soft);
  margin: 0;
}
.tandem-card__stats {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px dashed var(--ink-mute);
  font-family: var(--arch);
  font-size: 0.6875rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.tandem-card__stats strong {
  display: block;
  font-family: var(--mono);
  font-size: 1.625rem;
  font-weight: 400;
  letter-spacing: 1px;
  color: var(--ink);
  margin-bottom: -2px;
}

/* ===== LORE TEASER (#lore) — a single card linking to the /lore page ===== */
.lore-teaser {
  padding: 8vh 6vw;
  background: var(--paper-warm);
  border-top: 3px solid var(--ink);
}
.lore-teaser__card {
  display: block;
  max-width: 820px;
  margin: 0 auto;
  padding: clamp(20px, 4vw, 36px);
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: 8px 8px 0 var(--ink);
  color: var(--ink);
  text-decoration: none;
  rotate: -0.6deg;
  transition: box-shadow 0.2s;
}
.lore-teaser__card:hover,
.lore-teaser__card:focus-visible {
  box-shadow: 10px 10px 0 var(--accent-red);
}
.lore-teaser__title {
  display: block;
  font-family: var(--marker);
  font-size: clamp(28px, 3.6vw, 48px);
  line-height: 1.05;
  margin-bottom: 14px;
}
.lore-teaser__cta {
  display: inline-block;
  font-family: var(--arch);
  font-size: 0.875rem;
  border: 2px solid var(--ink);
  border-radius: 999px;
  padding: 4px 14px;
  background: var(--accent-yellow);
}

/* ===== LEADERBOARDS (below the hero, landing_leaderboards.js) =====
   A Players/Clubs tab toggle picks ONE board; pickLeaderboardRows pads a short real list
   with curated placeholder rows up to the top-20 cap (re-ranked sequentially) instead of
   an all-or-nothing swap — same "obviously flavor, not a bug" idiom the neighboring
   tandem-card grid above already used for its own Top Tandems, before that section became
   Reviews, just blended in rather than shown wholesale. That top 20 is split across two
   side-by-side columns of 10 (ranks 1-10 / 11-20), not one long scrolling list. */
.leaderboards-spacious {
  position: relative;
  padding: 8vh 6vw 10vh;
  max-width: none;
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  isolation: isolate;
  overflow: hidden;
}
/* Same synthwave grid-floor treatment as .hof-spacious (the Reviews section) — a perspective
   grid fading up from the bottom third, behind the tiles. */
.leaderboards-spacious::before {
  content: '';
  position: absolute;
  inset: 60% -10% -10% -10%;
  background-image:
    linear-gradient(
      to right,
      color-mix(in oklab, var(--accent-blue) 65%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      to bottom,
      color-mix(in oklab, var(--accent-blue) 65%, transparent) 1px,
      transparent 1px
    );
  background-size: 5vw 5vw;
  transform: perspective(700px) rotateX(62deg);
  transform-origin: top center;
  mask-image: linear-gradient(to bottom, var(--ink) 0%, var(--ink) 60%, transparent 100%);
  /* PT1: faint enough that the text in front of it stays readable. */
  opacity: 0.2;
  z-index: -1;
}
.leaderboards-spacious::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 18%;
  transform: translateX(-50%);
  width: min(560px, 55vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in oklab, var(--accent-pink) 55%, transparent) 0%,
    color-mix(in oklab, var(--accent-blue) 45%, transparent) 45%,
    transparent 70%
  );
  filter: blur(20px);
  z-index: -1;
  opacity: 0.7;
}
.leaderboards-spacious__inner {
  max-width: 1280px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}
.leaderboards-tabs {
  display: flex;
  gap: 10px;
  margin-bottom: 22px;
}
.leaderboards-tab {
  font-family: var(--arch);
  font-size: 0.875rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  padding: 9px 22px;
  background: var(--paper);
  color: var(--ink);
  border: 2px solid var(--ink);
  border-radius: var(--r-md);
  cursor: pointer;
  box-shadow:
    3px 3px 0 var(--ink),
    0 0 14px color-mix(in oklab, var(--accent-pink) 30%, transparent);
  transition:
    transform 0.15s ease-out,
    box-shadow 0.15s;
}
.leaderboards-tab:hover {
  transform: translateY(-2px);
  box-shadow:
    4px 4px 0 var(--ink),
    0 0 22px color-mix(in oklab, var(--accent-pink) 45%, transparent);
}
/* Active state inverts to an accent fill rather than var(--ink) now that the section
   background is var(--ink) itself — an ink-on-ink active tab would be invisible. Colored
   to match that tab's own tile glow below (blue for players, pink for clubs) rather than
   one fixed color, so the tab reads as "this is the color you're about to see". */
.leaderboards-tab.active {
  color: var(--paper);
  border-color: var(--paper);
}
.leaderboards-tab.active[data-leaderboard-tab='players'] {
  background: var(--accent-blue);
}
.leaderboards-tab.active[data-leaderboard-tab='clubs'] {
  background: var(--accent-pink);
}
.leaderboards-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
}
/* A grid item's default min-width is auto (its content's min-content size), not 0 — so
   without this, a column whose rows happen to carry longer content (a longer club name,
   the tier/member-count meta line) has a larger min-content width than its sibling, and
   "1fr 1fr" only splits the space left AFTER each track's own minimum is met — the two
   columns could render unequal widths, throwing the whole grid (still centered by
   .leaderboards-spacious's margin) visibly off-center. */
.leaderboards-column {
  min-width: 0;
}
.leaderboards-rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* min-height + the name's single-line clamp below keep a club row (name + tier/member-count
   meta line) and a player row (name only) the exact same height — without both, a longer
   club name wrapping to 2 lines made that column's tiles visibly taller than the players
   column's, row for row. The name/meta line-heights below are pinned explicitly rather than
   left at the font's own "normal" metric — Permanent Marker/Caveat (both decorative Google
   Fonts) render noticeably taller default line boxes than a plain sans-serif, which is what
   let a club row's actual content height sneak past this min-height even though the numbers
   looked like they should've fit. */
.leaderboard-row {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 88px;
  background: var(--paper);
  color: var(--ink);
  border: 2px solid color-mix(in oklab, var(--accent-blue) 100%, var(--paper));
  border-radius: var(--r-md);
  padding: 14px 20px;
  box-shadow:
    3px 3px 0 var(--ink),
    0 0 20px color-mix(in oklab, var(--accent-blue) 40%, transparent);
  transition:
    transform 0.15s ease-out,
    box-shadow 0.15s;
}
.leaderboard-row:hover {
  transform: translateY(-3px);
  box-shadow:
    5px 5px 0 var(--ink),
    0 0 32px color-mix(in oklab, var(--accent-blue) 60%, transparent);
}
/* Club tiles get an h-flipped drop shadow (offset left instead of right) AND a pink glow
   (instead of the players tab's blue) purely to visually distinguish the two tabs' tiles
   from one another. */
.leaderboard-row--flip {
  border-color: color-mix(in oklab, var(--accent-pink) 100%, var(--paper));
  box-shadow:
    -3px 3px 0 var(--ink),
    0 0 20px color-mix(in oklab, var(--accent-pink) 40%, transparent);
}
.leaderboard-row--flip:hover {
  box-shadow:
    -5px 5px 0 var(--ink),
    0 0 32px color-mix(in oklab, var(--accent-pink) 60%, transparent);
}
.leaderboard-row__rank {
  font-family: var(--marker);
  font-size: 1.5rem;
  line-height: 1;
  width: 2.2em;
  flex-shrink: 0;
  text-align: center;
}
.leaderboard-row__emoji {
  font-size: 1.5rem;
  flex-shrink: 0;
  line-height: 1;
}
.leaderboard-row__emoji .ui-icon-img.leaderboard-row-fallback-icon {
  display: inline-block;
  width: 1.5rem;
  height: 1.5rem;
}
.leaderboard-row__main {
  flex: 1;
  min-width: 0;
}
.leaderboard-row__name {
  font-family: var(--marker);
  font-size: 1.2rem;
  line-height: 1.2;
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leaderboard-row__name a {
  color: var(--ink);
  text-decoration: none;
}
.leaderboard-row__name a:hover {
  text-decoration: underline;
}
.leaderboard-row__meta {
  display: block;
  font-family: var(--hand);
  font-size: 1rem;
  line-height: 1.2;
  color: var(--ink-soft);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leaderboard-row__stats {
  display: flex;
  gap: 18px;
  flex-shrink: 0;
}
.leaderboard-row__stat {
  text-align: right;
  font-family: var(--mono);
  font-size: 1.25rem;
}
.leaderboard-row__stat-label {
  display: block;
  font-family: var(--arch);
  font-size: 0.75rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.leaderboards-empty {
  color: color-mix(in oklab, var(--paper) 70%, var(--ink));
  font-family: var(--hand);
  font-size: 1.05rem;
}
@media (max-width: 760px) {
  .leaderboards-columns {
    grid-template-columns: 1fr;
    gap: 36px;
  }
}
@media (max-width: 640px) {
  .leaderboard-row__stats {
    gap: 10px;
  }
  .leaderboard-row__meta {
    display: none;
  }
}

/* ===== FAQ ===== */
.faq-spacious {
  padding: 12vh 6vw;
  max-width: 880px;
  margin: 0 auto;
}
.faq-acc {
  border-top: 1px solid var(--ink);
}
.faq-acc__item {
  border-bottom: 1px solid var(--ink);
  padding: 26px 8px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 22px;
  align-items: baseline;
}
.faq-acc__q {
  font-family: var(--marker);
  font-size: clamp(18px, 2vw, 24px);
  letter-spacing: 0.3px;
  margin: 0 0 8px;
}
.faq-acc__a {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0;
  grid-column: 1 / -1;
  max-width: 60ch;
}
.faq-acc__plus {
  font-family: var(--marker);
  font-size: 1.625rem;
  color: var(--accent-red);
}

/* ===== FINAL CTA ===== */
.final-cta {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  padding: 20vh 6vw;
  text-align: center;
  overflow: hidden;
  isolation: isolate;
}
.final-cta > * {
  position: relative;
  z-index: 1;
}
.synthwave-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.synthwave-bg::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 18%;
  width: min(600px, 58vw);
  aspect-ratio: 1;
  border-radius: 50%;
  transform: translateX(-50%);
  background:
    linear-gradient(
      180deg,
      transparent 0%,
      transparent 40%,
      var(--ink) 40%,
      var(--ink) 44%,
      transparent 44%,
      transparent 52%,
      var(--ink) 52%,
      var(--ink) 55%,
      transparent 55%,
      transparent 64%,
      var(--ink) 64%,
      var(--ink) 66%,
      transparent 66%
    ),
    radial-gradient(
      circle at 50% 35%,
      color-mix(in oklab, var(--accent-yellow) 90%, transparent) 0%,
      color-mix(in oklab, var(--accent-pink) 90%, transparent) 55%,
      color-mix(in oklab, var(--accent-red) 80%, transparent) 80%,
      transparent 100%
    );
  filter: drop-shadow(0 0 30px color-mix(in oklab, var(--accent-pink) 60%, transparent));
}
.synthwave-bg::after {
  content: '';
  position: absolute;
  inset: 56% 0 -8% 0;
  background-image:
    linear-gradient(
      to right,
      color-mix(in oklab, var(--accent-pink) 80%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      to bottom,
      color-mix(in oklab, var(--accent-pink) 80%, transparent) 1px,
      transparent 1px
    );
  background-size: 7vw 7vw;
  transform: perspective(560px) rotateX(58deg);
  transform-origin: top center;
  mask-image: linear-gradient(to bottom, var(--ink) 0%, var(--ink) 70%, transparent 100%);
}
.scanlines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.02) 0px,
    rgba(255, 255, 255, 0.02) 1px,
    transparent 1px,
    transparent 4px
  );
  mix-blend-mode: overlay;
  opacity: 0.5;
}
.final-cta h2 {
  font-family: var(--marker);
  font-size: clamp(44px, 6.5vw, 88px);
  line-height: 0.95;
  margin: 0 0 24px;
  color: var(--paper);
  text-shadow:
    0 0 18px color-mix(in oklab, var(--accent-pink) 70%, transparent),
    5px 5px 0 color-mix(in oklab, var(--accent-red) 100%, var(--ink));
}
.final-cta h2 em {
  font-style: normal;
  color: var(--accent-yellow);
}
.final-cta p {
  font-size: 1.1875rem;
  line-height: 1.5;
  color: color-mix(in oklab, var(--paper) 70%, var(--ink));
  max-width: 36ch;
  margin: 0 auto 32px;
}

/* ===== FOOTER ===== */
.spacious-footer {
  padding: 52px 6vw 36px;
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  font-family: var(--arch);
  font-size: 0.8125rem;
  color: var(--ink-mute);
}
.spacious-footer a {
  color: var(--ink-mute);
  text-decoration: none;
}
.spacious-footer a:hover {
  color: var(--ink);
}

/* ===== REVEAL ON SCROLL ===== */
.reveal {
  opacity: 0;
  transform: translateY(40px);
  transition:
    opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.8s ease-out;
  filter: blur(5px);
  will-change: opacity, transform, filter;
}
.reveal.reveal-in {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}
.reveal--right {
  transform: translateX(50px) translateY(20px);
}
.reveal--right.reveal-in {
  transform: translate(0);
}
.reveal--left {
  transform: translateX(-50px) translateY(20px);
}
.reveal--left.reveal-in {
  transform: translate(0);
}
.reveal-stagger > * {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 0.6s ease-out,
    transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal-stagger.reveal-in > * {
  opacity: 1;
  transform: translateY(0);
}
.reveal-stagger.reveal-in > *:nth-child(1) {
  transition-delay: 0.05s;
}
.reveal-stagger.reveal-in > *:nth-child(2) {
  transition-delay: 0.15s;
}
.reveal-stagger.reveal-in > *:nth-child(3) {
  transition-delay: 0.25s;
}
.reveal-stagger.reveal-in > *:nth-child(4) {
  transition-delay: 0.35s;
}
.reveal-stagger.reveal-in > *:nth-child(5) {
  transition-delay: 0.45s;
}
.reveal-stagger.reveal-in > *:nth-child(6) {
  transition-delay: 0.55s;
}
.reveal-stagger.reveal-in > *:nth-child(7) {
  transition-delay: 0.65s;
}
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-stagger > * {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }
}

/* ===== AUTH MODAL ===== */
#authOverlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1100;
  padding: 20px;
}
.auth-modal {
  position: relative;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: var(--r-lg);
  padding: 40px 36px 36px;
  width: min(440px, 100%);
  box-shadow: 8px 8px 0 var(--ink);
}
.auth-modal h2 {
  font-family: var(--marker);
  font-size: 2rem;
  letter-spacing: 0.5px;
  margin-bottom: 10px;
}
.auth-modal p {
  font-size: 1rem;
  color: var(--ink-soft);
  margin-bottom: 24px;
  line-height: 1.45;
}
.auth-close-btn {
  position: absolute;
  top: 14px;
  right: 16px;
  background: none;
  border: none;
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-mute);
  padding: 0;
}
.auth-close-btn:hover {
  color: var(--ink);
}

/* ===== LEADERBOARD MOCK-ROW PREVIEW ===== */
.leaderboard-row__name-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
}
.leaderboard-row__name-btn:hover {
  color: var(--accent, #c0392b);
}
.mock-preview-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1100;
  padding: 20px;
}
.mock-preview-overlay.is-open {
  display: flex;
}
.mock-preview-card {
  position: relative;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: var(--r-lg);
  padding: 36px 32px 32px;
  width: min(420px, 100%);
  box-shadow: 8px 8px 0 var(--ink);
  text-align: center;
}
.mock-preview-close {
  position: absolute;
  top: 12px;
  right: 14px;
  background: none;
  border: none;
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-mute);
  padding: 0;
}
.mock-preview-close:hover {
  color: var(--ink);
}
.mock-preview-kicker {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-mute);
  margin-bottom: 6px;
}
.mock-preview-title {
  font-family: var(--marker);
  font-size: 1.7rem;
  margin: 0 0 4px;
}
.mock-preview-sub {
  color: var(--ink-soft);
  margin: 0 0 18px;
}
.mock-preview-stats {
  display: flex;
  justify-content: center;
  gap: 28px;
  margin-bottom: 18px;
}
.mock-preview-stat-value {
  font-family: var(--marker);
  font-size: 1.4rem;
}
.mock-preview-stat-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
}
.mock-preview-note {
  font-size: 0.9rem;
  color: var(--ink-soft);
  line-height: 1.45;
  margin-bottom: 20px;
}
.mock-preview-cta {
  width: 100%;
}

/* Cross-cutting mobile responsive pass (nav, hero, steprow, events/FAQ/final-CTA
   section padding) — grouped here at the end rather than inline with each section
   above, matching how it sat in index.html's original single stylesheet. */
/* Responsive */
@media (max-width: 900px) {
  .hero-big {
    grid-template-columns: 1fr;
  }
  .hero-big__image {
    /* No boxed panel on mobile — the warm background + big min-height
       (sized for the old poster art) made the video read as a separate
       framed widget sitting on top of the title instead of one hero. */
    min-height: 0;
    background: none;
    padding: 20px 16px 0;
  }
  .hero-big__copy {
    padding: 3vh 6vw 6vh;
  }
  .steprow {
    grid-template-columns: 1fr;
    gap: 26px;
  }
  .steprow.reverse > :first-child {
    order: 0;
  }
  .nav-hide-mobile {
    display: none;
  }
  /* Inline links are hidden here, so surface them via the overflow menu. */
  .nav-overflow-btn {
    display: flex;
  }
}
@media (max-width: 600px) {
  #siteNav {
    padding: 10px 16px;
    gap: 12px;
  }
  .events-spacious {
    padding: 8vh 5vw;
  }
  .faq-spacious {
    padding: 8vh 5vw;
  }
  .final-cta {
    padding: 14vh 5vw;
  }
}
