/* ==========================================================================
   SWIVUL DESIGN SYSTEM v2 - Token2049 + Singapore GP funnel
   Source of law: Styfinity-Brain/artefacts/brand-guidelines/swivul-brand-system.md
   Three colours only: #D1001F / #000000 / #FFFFFF (white at .6/.4 for text ladder).
   Every other tint on these pages is a white-alpha or black-alpha of those three.
   Red alpha appears ONLY as light emitted by a full-strength #D1001F element
   (badge glow, streak glow, red CTA hover) - house call, flagged inline.
   Headlines: Michroma stand-in for Eurostile Extended. UPPERCASE, weight 400 only.
   Body: Hanken Grotesk stand-in for Articulat CF.
   v2 principles: light and depth on every section (skyline, shafts, grain,
   vignette), typography as architecture (hero >= 3x section heads >= 2x body),
   ghost numerals, one full-bleed red ground per page maximum (the brand book's
   sanctioned red-ground combination), motion as polish only (defaults readable
   with JS off; prefers-reduced-motion kills everything).
   ========================================================================== */

/* ------------------------------------------------------------------ tokens */
:root {
  --red: #D1001F;
  --black: #000000;
  --white: #FFFFFF;
  --white-60: rgba(255, 255, 255, 0.6);
  --white-40: rgba(255, 255, 255, 0.4);

  --glass-fill: rgba(255, 255, 255, 0.055);
  --glass-border: rgba(255, 255, 255, 0.22);
  --glass-topcatch: rgba(255, 255, 255, 0.30);

  --font-head: "Eurostile Extended", "Eurostile Extd", "Square721 BT",
               "Michroma", "Saira Extended", ui-sans-serif, sans-serif;
  --font-body: "Articulat CF", "Hanken Grotesk", "Figtree", Inter,
               ui-sans-serif, system-ui, sans-serif;

  /* Type scale v2. Scale contrast is the wow engine:
     hero >= 3x section head >= 2x body. */
  --fs-hero: clamp(3.25rem, 8.6vw, 8.4rem);   /* index hero only */
  --fs-hero-inner: clamp(2.5rem, 6vw, 5.2rem);/* THE inner-page hero scale: week + book share it (2026-08-21: one scale, no lesser pages) */
  --fs-page: clamp(2rem, 4.6vw, 3.6rem);      /* legacy inner-page H1s (.h-page) */
  --fs-h2: clamp(1.7rem, 3.3vw, 2.5rem);      /* section heads (cap 2.5rem: hero-to-head ratio >= 3x at 1440) */
  --fs-venue: clamp(1.25rem, 1.85vw, 1.65rem);/* venue names, H2-adjacent */
  --fs-h3: 0.9375rem;
  --fs-lead: clamp(1.0625rem, 1.8vw, 1.3125rem);
  --fs-body: clamp(1rem, 1.4vw, 1.125rem);
  --fs-caption: 0.8125rem;
  --fs-micro: 0.6875rem;

  --radius-card: 24px;
  --radius-pill: 9999px;

  --space-section: clamp(4rem, 10vw, 8.5rem);
  --container: 1160px;
  --container-wide: 1360px;
}

/* ------------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--black);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
body {
  margin: 0;
  min-height: 100vh;
  background: transparent;
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.7;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img, svg { max-width: 100%; display: block; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
a { color: inherit; }
::selection { background: var(--red); color: var(--white); }
:focus-visible {
  outline: 2px solid var(--white-60);
  outline-offset: 3px;
  border-radius: 4px;
}
/* Anchor targets land clear of the sticky header. */
[id] { scroll-margin-top: 84px; }

/* ---------------------------------------------------- the cinematic ground */
/* Fixed ground, three perceivable layers before any content:
   1. top-light spill + a diagonal atmosphere shaft (white alpha),
   2. a low horizon glow (the city below the frame),
   3. vignette pulling the edges down.
   Red never tints the ambient ground: full-strength red elements do the
   emitting (badges, streak, CTA) - house rule. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--black);
  background-image:
    linear-gradient(112deg,
      rgba(0, 0, 0, 0) 34%,
      rgba(255, 255, 255, 0.028) 46%,
      rgba(0, 0, 0, 0) 58%),
    radial-gradient(95% 60% at 50% -14%,
      rgba(255, 255, 255, 0.075) 0%,
      rgba(0, 0, 0, 0) 62%),
    radial-gradient(130% 70% at 50% 112%,
      rgba(255, 255, 255, 0.055) 0%,
      rgba(255, 255, 255, 0.02) 36%,
      rgba(0, 0, 0, 0) 68%),
    radial-gradient(140% 110% at 50% 45%,
      rgba(0, 0, 0, 0) 48%,
      rgba(0, 0, 0, 0.6) 100%);
}
/* Grain: inline SVG fractal noise, desaturated, at whisper opacity. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* -------------------------------------------------------------- typography */
.h-hero,
.h-page,
.h-section,
.h-card,
.headline {
  font-family: var(--font-head);
  font-weight: 400;
  text-transform: uppercase;
  color: var(--white);
  margin: 0 0 0.75em;
}
.h-hero {
  font-size: var(--fs-hero);
  letter-spacing: 0.01em;
  line-height: 1.04;
}
/* Hero lockup lines: the kicker line runs full width, the payoff line steps
   down so both lines read as one carved block. */
.h-hero .h-hero-line { display: block; }
.h-hero .h-hero-l2 { font-size: 0.775em; letter-spacing: 0.028em; }
.h-page {
  font-size: var(--fs-page);
  letter-spacing: 0.06em;
  line-height: 1.12;
}
/* Inner-page hero: full architecture, one shared scale for week + book so no
   page in the flow reads cheaper than its siblings. */
.h-hero-inner {
  font-size: var(--fs-hero-inner);
  letter-spacing: 0.015em;
}
.h-section {
  font-size: var(--fs-h2);
  letter-spacing: 0.09em;
  line-height: 1.18;
}
.h-card {
  font-size: var(--fs-h3);
  letter-spacing: 0.1em;
  line-height: 1.5;
}
/* Venue names promoted to architecture (v2). */
.venue-card .h-card {
  font-size: var(--fs-venue);
  letter-spacing: 0.06em;
  line-height: 1.28;
}
.lead { font-size: var(--fs-lead); }
.text-60 { color: var(--white-60); }
.text-40 { color: var(--white-40); }
.caption { font-size: var(--fs-caption); line-height: 1.6; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.prose { max-width: 46rem; }
.center .prose, .prose.center { margin-inline: auto; }

/* Section eyebrow: small tracked label above a big head. */
.section-eyebrow {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-micro);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--white-40);
  margin-bottom: 1.1rem;
}

/* ------------------------------------------------------------------ layout */
.container {
  width: min(100% - 48px, var(--container));
  margin-inline: auto;
}
.container-wide {
  width: min(100% - 48px, var(--container-wide));
  margin-inline: auto;
}
.section { padding-block: var(--space-section); }
.section-tight { padding-block: calc(var(--space-section) * 0.45); }
.section-rule { border-top: 1px solid rgba(255, 255, 255, 0.08); }
/* Sections never sit on flat black: give any section a sided light well. */
.section, .section-tight { position: relative; }
.glow-left::before,
.glow-right::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.glow-left::before {
  background:
    radial-gradient(60% 85% at -8% 30%, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0) 60%),
    linear-gradient(75deg, rgba(0,0,0,0) 40%, rgba(255,255,255,0.018) 50%, rgba(0,0,0,0) 60%);
}
.glow-right::before {
  background:
    radial-gradient(60% 85% at 108% 40%, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0) 60%),
    linear-gradient(115deg, rgba(0,0,0,0) 40%, rgba(255,255,255,0.018) 50%, rgba(0,0,0,0) 60%);
}

/* ------------------------------------------------------------------- glass */
.glass,
.glass-card,
.glass-pill {
  background: var(--glass-fill);
  -webkit-backdrop-filter: blur(24px) saturate(120%);
  backdrop-filter: blur(24px) saturate(120%);
  border: 1px solid var(--glass-border);
  box-shadow:
    inset 0 1px 0 var(--glass-topcatch),
    0 24px 60px rgba(0, 0, 0, 0.55);
  color: var(--white);
}
.glass-card { border-radius: var(--radius-card); }
.glass-pill { border-radius: var(--radius-pill); }

/* ----------------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 52px;
  padding: 0.95rem 2.4rem;
  border-radius: var(--radius-pill);
  /* UI chrome (buttons, badges, pills, labels) sets in the body face at 600;
     the headline face is reserved for headlines and key figures. */
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.25s ease, border-color 0.25s ease,
              box-shadow 0.25s ease, transform 0.25s ease;
}
/* The one red CTA style. Maximum one per screen-height.
   glow = light emitted by the full-strength red element, house call */
.btn-red {
  background: var(--red);
  border: 1px solid var(--red);
  color: var(--white);
  box-shadow: 0 10px 40px rgba(209, 0, 31, 0.28);
}
.btn-red:hover {
  box-shadow: 0 14px 52px rgba(209, 0, 31, 0.45);
  transform: translateY(-2px);
}
/* Glass secondary (and the deck's default CTA on these pages). */
.btn-glass {
  background: var(--glass-fill);
  -webkit-backdrop-filter: blur(24px) saturate(120%);
  backdrop-filter: blur(24px) saturate(120%);
  border: 1px solid var(--glass-border);
  box-shadow: inset 0 1px 0 var(--glass-topcatch), 0 12px 40px rgba(0, 0, 0, 0.45);
  color: var(--white);
}
.btn-glass:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.42);
  transform: translateY(-2px);
}
.btn-small {
  min-height: 44px;
  padding: 0.55rem 1.4rem;
  font-size: var(--fs-micro);
}
.btn-block-mobile { width: 100%; }
@media (min-width: 720px) { .btn-block-mobile { width: auto; } }

/* ------------------------------------------------------------------ badges */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.6rem 1.2rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.4;
  white-space: nowrap;
}
/* The sanctioned red: public status, red-as-error. A real breathing glow,
   readable from across the room, never carnival. The red lives in the
   full-strength border and its emitted glow; the text sets in white so it
   stays legible in daylight glare on a phone (v3 2026-08-21).
   glow = light emitted by the full-strength red element, house call */
.badge-soldout {
  border: 1px solid var(--red);
  color: var(--white);
  background: transparent;
  animation: soldout-pulse 2.8s ease-in-out infinite;
}
@keyframes soldout-pulse {
  0%, 100% {
    box-shadow: 0 0 12px 0 rgba(209, 0, 31, 0.22),
                inset 0 0 10px rgba(209, 0, 31, 0.08);
  }
  50% {
    box-shadow: 0 0 32px 7px rgba(209, 0, 31, 0.55),
                inset 0 0 14px rgba(209, 0, 31, 0.2);
  }
}
/* The access badge: luminous glass, slow light sweep across the face. */
.badge-access {
  position: relative;
  background-color: rgba(255, 255, 255, 0.09);
  background-image: linear-gradient(110deg,
    rgba(255, 255, 255, 0) 36%,
    rgba(255, 255, 255, 0.22) 50%,
    rgba(255, 255, 255, 0) 64%);
  background-size: 300% 100%;
  background-position: 140% 0;
  background-repeat: no-repeat;
  -webkit-backdrop-filter: blur(24px) saturate(120%);
  backdrop-filter: blur(24px) saturate(120%);
  border: 1px solid rgba(255, 255, 255, 0.32);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35),
              0 0 24px rgba(255, 255, 255, 0.06);
  color: var(--white);
  animation: access-shimmer 6s ease-in-out infinite;
}
@keyframes access-shimmer {
  0%, 46%  { background-position: 140% 0; }
  78%, 100% { background-position: -40% 0; }
}

/* --------------------------------------------------------- eyebrow / rules */
.eyebrow-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.55rem 1.35rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--white-60);
}
.rule-red {
  display: block;
  width: 40px;
  height: 2px;
  background: var(--red);
  border: 0;
  margin: 0 auto 1.75rem;
}

/* ------------------------------------------------------------------ header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(0, 0, 0, 0.7);
  -webkit-backdrop-filter: blur(24px) saturate(120%);
  backdrop-filter: blur(24px) saturate(120%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 68px;
  padding-block: 0.75rem;
}
.header-brand {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  /* Tap target: pad the link to 44px+ without growing the header row. */
  padding-block: 0.75rem;
  margin-block: -0.75rem;
}
.header-lockup { height: 22px; width: auto; }
@media (min-width: 720px) { .header-lockup { height: 26px; } }

/* -------------------------------------------------------------------- hero */
/* Three perceivable depth layers behind the type:
   1. skyline silhouette (inline SVG, white 3-8% alpha, bottom-anchored),
   2. diagonal light shafts + horizon glow,
   3. the red F1 light-trail streak sweeping behind the headline.
   Content sits above all three. */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(5rem, 13vw, 9.5rem) clamp(7rem, 16vw, 12rem);
}
.hero-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.hero-content { position: relative; z-index: 1; }
/* Hero photograph (index.html). Same grade as .venue-media img, darker, because the
   headline sits on it. Two gradients: the top keeps the header legible, the bottom
   dissolves the photo into the page black so the section has no hard edge. */
.hero-photo { position: absolute; inset: 0; overflow: hidden; }
.hero-photo img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%;
  filter: grayscale(1) contrast(1.15) brightness(0.42);
  transform: scale(1.04);
}
.hero-photo::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.25) 28%, rgba(0,0,0,0.15) 60%, rgba(0,0,0,0.92) 100%),
    radial-gradient(ellipse at 50% 45%, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.6) 75%);
}
.hero .hero-photo ~ .skyline { display: none; }
.hero .hero-photo ~ .shaft { opacity: 0.55; }
.hero .eyebrow-pill { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.hero .h-hero { margin-bottom: clamp(1.5rem, 3.5vw, 2.5rem); }
.hero-actions { margin-top: 2.5rem; }
.hero .lead { color: var(--white); }

/* Skyline: bottom-anchored, oversized so towers crop cinematically. */
.skyline {
  position: absolute;
  left: 50%;
  bottom: -2px;
  transform: translateX(-50%);
  width: max(100%, 1440px);
  height: auto;
  max-width: none;
}
/* Diagonal light shafts. */
.shaft {
  position: absolute;
  top: -20%;
  height: 150%;
  width: clamp(160px, 24vw, 380px);
  pointer-events: none;
}
.shaft-a {
  left: 6%;
  transform: rotate(16deg);
  background: linear-gradient(to bottom,
    rgba(255, 255, 255, 0.07) 0%,
    rgba(255, 255, 255, 0.02) 45%,
    rgba(0, 0, 0, 0) 78%);
}
.shaft-b {
  right: 4%;
  width: clamp(120px, 16vw, 260px);
  transform: rotate(-14deg);
  background: linear-gradient(to bottom,
    rgba(255, 255, 255, 0.05) 0%,
    rgba(255, 255, 255, 0.015) 40%,
    rgba(0, 0, 0, 0) 75%);
}
/* The red F1 light trail behind the hero type.
   Core is full-strength #D1001F; the wider strokes are its emitted glow
   (red alpha as light from a full-strength red element) - house call. */
.hero-streak {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  opacity: 0.9;
}
.streak-glow-wide { stroke: rgba(209, 0, 31, 0.16); stroke-width: 44; filter: blur(22px); }
.streak-glow-mid  { stroke: rgba(209, 0, 31, 0.45); stroke-width: 10; filter: blur(7px); }
.streak-core      { stroke: #D1001F; stroke-width: 2.5; }
/* Narrow screens: the arc would cross the sub copy like a strikethrough.
   The mobile hero carries the drama with type, badges and the red band. */
@media (max-width: 719px) { .hero-streak { display: none; } }

/* Hero entrance: pure-CSS polish; content is at opacity 1 the moment the
   animation is unsupported or disabled. */
.hero-content > * { animation: hero-rise 0.9s cubic-bezier(0.22, 0.7, 0.3, 1) both; }
.hero-content > *:nth-child(2) { animation-delay: 0.08s; }
.hero-content > *:nth-child(3) { animation-delay: 0.16s; }
.hero-content > *:nth-child(4) { animation-delay: 0.24s; }
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

/* -------------------------------------------------------------- venue grid */
/* v2: the list is the jewel. Two-column editorial grid, large cards,
   ghost numerals, per-card light shafts on unique angles. */
.venue-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
@media (min-width: 860px) { .venue-grid { grid-template-columns: 1fr 1fr; gap: 2rem; } }
.venue-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 23rem;
  padding: clamp(1.9rem, 3.4vw, 2.9rem);
}
/* Per-card light shaft, angle varies card to card. Gradient peaks at 0.09
   white; the resting card shows it through 0.55 opacity (~0.05 effective),
   and :hover lifts the shaft to full strength so the card visibly wakes. */
.venue-card::before {
  content: "";
  position: absolute;
  inset: -45%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.55;
  transition: opacity 0.35s ease;
  background: linear-gradient(var(--shaft, 115deg),
    rgba(0, 0, 0, 0) 40%,
    rgba(255, 255, 255, 0.09) 50%,
    rgba(0, 0, 0, 0) 60%);
}
.venue-card:hover::before { opacity: 1; }
.venue-grid .venue-card:nth-child(1) { --shaft: 106deg; }
.venue-grid .venue-card:nth-child(2) { --shaft: 132deg; }
.venue-grid .venue-card:nth-child(3) { --shaft: 74deg; }
.venue-grid .venue-card:nth-child(4) { --shaft: 118deg; }
.venue-grid .venue-card:nth-child(5) { --shaft: 62deg; }
.venue-grid .venue-card:nth-child(6) { --shaft: 141deg; }
.venue-card > * { position: relative; z-index: 1; }
.venue-card {
  transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.venue-card:hover {
  transform: translateY(-6px);
  border-color: rgba(255, 255, 255, 0.4);
  box-shadow: inset 0 1px 0 var(--glass-topcatch), 0 34px 80px rgba(0, 0, 0, 0.75);
}
/* Ghost numeral: massive, cropped by the card edge. Wakes with the card. */
.ghost-num {
  position: absolute;
  z-index: 0;
  top: -0.14em;
  right: -0.04em;
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(7rem, 11vw, 10.5rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.05);
  user-select: none;
  pointer-events: none;
  transition: color 0.35s ease;
}
.venue-card:hover .ghost-num { color: rgba(255, 255, 255, 0.09); }
/* Mobile: the numeral is a signature depth layer; keep it perceivable on a
   small dark screen (higher alpha, hard 6rem floor so it still crops the edge). */
@media (max-width: 719px) {
  .ghost-num {
    color: rgba(255, 255, 255, 0.08);
    font-size: max(6rem, clamp(7rem, 11vw, 10.5rem));
  }
}
.venue-card .h-card { margin: 0 0 0.9em; padding-right: 2.5rem; }
.venue-type {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-micro);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--white-40);
  margin-bottom: 1.1em;
}
.venue-line {
  color: var(--white-60);
  font-size: 0.9375rem;
  line-height: 1.75;
  margin-bottom: 1.6em;
  max-width: 34rem;
}
/* The value beat: what Swivul does here. Hairline above, white 100 line. */
.venue-beat {
  margin-top: auto;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.venue-beat-label {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-micro);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--white-40);
  margin-bottom: 0.45rem;
}
.venue-beat-line {
  color: var(--white);
  font-size: 1rem;
  line-height: 1.55;
  margin: 0 0 1.4em;
}
.venue-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* ------------------------------------------------------------------- steps */
/* v3 (2026-08-21): the door-brief treatment. Hairline rules, red Michroma
   numerals as key figures, a Michroma step title, body copy at full body
   scale inside a disciplined column. The section earns its slot between the
   venue grid and the red band instead of whispering across the container. */
.steps {
  list-style: none;
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}
@media (min-width: 860px) { .steps { grid-template-columns: 1fr 1fr 1fr; gap: 0 3.5rem; } }
.step {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 1.9rem 0 2.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  max-width: 26rem;
}
.step-num {
  /* house call: numerals as key figures per brand section 2.
     Red numerals count toward the red budget. */
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(2.75rem, 4.2vw, 3.75rem);
  line-height: 1;
  color: var(--red);
  margin-bottom: 1.2rem;
}
.step-title {
  font-family: var(--font-head);
  font-weight: 400;
  text-transform: uppercase;
  color: var(--white);
  font-size: 1rem;
  letter-spacing: 0.12em;
  line-height: 1.4;
  margin: 0 0 0.7em;
}
.step p { color: var(--white-60); font-size: var(--fs-body); line-height: 1.75; margin: 0; }

/* ------------------------------------------------------- the red moment */
/* The ONE full-bleed red ground per page: the brand book's sanctioned
   red-ground combination. White type only on the red. Black-alpha vignette
   for depth (black is a brand colour; no fourth colour is born here). */
.red-band {
  position: relative;
  background-color: var(--red);
  color: var(--white);
  padding-block: clamp(4.5rem, 11vw, 8.5rem);
  overflow: hidden;
}
.red-band::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(118deg, rgba(255,255,255,0) 42%, rgba(255,255,255,0.09) 50%, rgba(255,255,255,0) 58%),
    radial-gradient(120% 120% at 50% 50%, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, 0.28) 100%);
}
.red-band .container { position: relative; }
.red-band-rule {
  display: block;
  width: 56px;
  height: 2px;
  background: var(--white);
  margin: 0 auto 2.25rem;
}
.red-band-line {
  font-family: var(--font-head);
  font-weight: 400;
  text-transform: uppercase;
  color: var(--white);
  font-size: clamp(1.25rem, 2.7vw, 2.2rem);
  letter-spacing: 0.06em;
  line-height: 1.45;
  margin: 0 auto 1.4em;
  max-width: 62rem;
}
.red-band-answer {
  font-size: clamp(1.7rem, 3.8vw, 3.1rem);
  letter-spacing: 0.05em;
  line-height: 1.25;
  margin-bottom: 0;
}
.red-band-kicker {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-micro);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
  margin-bottom: 1.5rem;
}

/* Legacy quote-panel vocabulary (kept for any page still on it). */
.quote-panel {
  margin-top: 3.5rem;
  padding: clamp(2.25rem, 6vw, 4rem) clamp(1.5rem, 5vw, 4rem);
  text-align: center;
}
.quote-line {
  font-family: var(--font-head);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(1rem, 2.6vw, 1.625rem);
  letter-spacing: 0.1em;
  line-height: 1.6;
  margin: 0 0 1.25em;
}
.quote-line:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------- forms */
.form-card { padding: clamp(1.75rem, 5vw, 3rem); }
.field { margin-bottom: 1.5rem; }
.field-label {
  display: block;
  color: var(--white);
  font-size: var(--fs-caption);
  letter-spacing: 0.02em;
  margin-bottom: 0.5rem;
}
.field-input,
.field-textarea,
.field-select {
  width: 100%;
  min-height: 48px;
  padding: 0.75rem 1rem;
  border-radius: 12px;
  background: var(--glass-fill);
  border: 1px solid var(--glass-border);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
}
.field-textarea { min-height: 110px; resize: vertical; }
.field-input::placeholder,
.field-textarea::placeholder { color: var(--white-40); }
.field-input:focus,
.field-textarea:focus,
.field-select:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.5);
}
.field-select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23FFFFFF' stroke-opacity='0.6' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.5rem;
}
.field-help {
  font-size: var(--fs-caption);
  color: var(--white-40);
  margin-top: 0.4rem;
}

/* ---------------------------------------------- letter panel (week.html)    */
.letter-panel {
  padding: clamp(2rem, 6vw, 3.5rem);
  line-height: 1.85;
}
.letter-panel p { color: var(--white-60); }
.letter-panel .letter-salutation,
.letter-panel .letter-signoff { color: var(--white); }

/* ------------------------------------------------ ledger rows (week.html)   */
.ledger { margin-top: 2rem; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.ledger-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.5rem;
  padding: 1.1rem 0.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--white-60);
  font-size: var(--fs-caption);
  letter-spacing: 0.02em;
}

/* --------------------------------------------------- door grid (book.html)  */
/* v2: the two doors are the jewel of book.html. Equal panels, never ranked:
   identical size, identical red hairline, ghost door numbers, per-door light
   shafts on unique angles, hover lift + white glow. No red button on this
   page (the deck's sanctioned deviation): red lives in hairlines only. */
.door-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  margin-top: 2.5rem;
}
@media (min-width: 720px) { .door-grid { grid-template-columns: 1fr 1fr; gap: 2rem; align-items: stretch; } }
.door-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 26rem;
  padding: clamp(2rem, 4.2vw, 3.1rem);
  transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
/* Per-door light shaft, one unique angle each (the venue-card treatment). */
.door-card::before {
  content: "";
  position: absolute;
  inset: -45%;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(var(--shaft, 112deg),
    rgba(0, 0, 0, 0) 40%,
    rgba(255, 255, 255, 0.05) 50%,
    rgba(0, 0, 0, 0) 60%);
}
/* Mirrored angles: the two doors are equals, so their light is symmetric. */
.door-grid .door-card:nth-child(1) { --shaft: 104deg; }
.door-grid .door-card:nth-child(2) { --shaft: 76deg; }
.door-card > * { position: relative; z-index: 1; }
.door-card:hover {
  transform: translateY(-6px);
  border-color: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 1px 0 var(--glass-topcatch),
              0 0 64px rgba(255, 255, 255, 0.06),
              0 34px 80px rgba(0, 0, 0, 0.75);
}
/* Door number: the ghost-num motif, cropped by the card's top-right corner.
   position restated: the .door-card > * rule above would otherwise pull the
   numeral back into flow (it sits later in the cascade than .ghost-num). */
.door-card .ghost-num {
  position: absolute;
  font-size: clamp(7.5rem, 12vw, 11.5rem);
}
.door-card .h-section { letter-spacing: 0.07em; margin-bottom: 0.85em; padding-right: 2rem; }
.door-copy {
  color: var(--white-60);
  font-size: 0.9375rem;
  line-height: 1.8;
  max-width: 30rem;
}
/* The payoff line each door ends on. Full white: it is the point. */
.door-punch {
  color: var(--white);
  font-size: 1rem;
  line-height: 1.6;
  max-width: 30rem;
}
/* The week brief, typeset as its own object inside Door Two. */
.door-brief {
  list-style: none;
  margin: 0.25rem 0 1.5rem;
  padding: 0;
  max-width: 30rem;
}
.door-brief li {
  display: flex;
  align-items: baseline;
  gap: 1.1rem;
  padding: 0.72rem 0.1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--white);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.door-brief li:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.1); }
.brief-num {
  /* house call: numerals as key figures per brand section 2. White-alpha here:
     book.html's red budget is already spent on its three hairlines. */
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--white-40);
  flex-shrink: 0;
}
.door-card .door-actions {
  margin-top: auto;
  padding-top: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.card-label {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  padding: 0.4rem 1rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--white-60);
  margin-bottom: 1.5rem;
}

/* Support line under any CTA button. */
.btn-support { margin-top: 1.25rem; }

/* ---------------------------------------------------------------- capacity */
.capacity-line {
  color: var(--white-60);
  text-align: center;
  margin: 0;
}

/* --------------------------------------------------------------- CTA close */
/* The closing CTA sits over a faint skyline reprise. */
.cta-close {
  position: relative;
  overflow: hidden;
  padding-block: clamp(5rem, 12vw, 9rem);
  background: radial-gradient(70% 90% at 50% 108%,
    rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0) 62%);
}
.cta-close .skyline { opacity: 1; }
.cta-close .container { position: relative; z-index: 1; }
.cta-close .h-section { margin-bottom: 0.9em; }

/* ------------------------------------------------------------------ footer */
.site-footer {
  position: relative;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-block: 3rem;
  text-align: center;
}
.footer-lockup {
  height: 20px;
  width: auto;
  margin: 0 auto 1.5rem;
}
.site-footer .caption { margin-bottom: 0.35em; }

/* --------------------------------------------------------- motion policy */
/* No scroll-gated reveals anywhere on this funnel: content is fully visible
   with JS off, in print, and in full-page capture. Motion = hero entrance,
   card hovers, badge pulse/shimmer. All of it dies under reduced motion. */

/* -------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn, .venue-card, .door-card { transition: none; }
  .btn-glass:hover, .btn-red:hover, .venue-card:hover, .door-card:hover { transform: none; }
  .venue-card::before, .ghost-num { transition: none; }
  .badge-soldout, .badge-access { animation: none; }
  .hero-content > * { animation: none; }
  .js-motion .reveal { opacity: 1; transform: none; transition: none; }
}

/* ====================================================== venue photography
   Added 2026-08-21. Real CC-licensed night photography of the six venues,
   graded to monochrome so no fourth colour enters the page through a
   photograph. This also closes the glass house-extension flag from the
   2026-08-21 brand audit: the book asks for glass over "a dark, textured
   photographic ground", and these cards now genuinely have one.
   Attribution (required by CC BY / CC BY-SA): assets/venues/CREDITS.md
   and the credit line in the index footer. */
.venue-card > .venue-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.venue-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--img-pos, center 45%);
  filter: grayscale(1) contrast(var(--img-contrast, 1.18)) brightness(var(--img-bright, 0.86));
  transform: scale(1.05);
  transition: filter 0.6s ease, transform 0.9s ease;
}
/* Per-card grade. The six sources are real photographs with wildly different
   luminance (a black-sky night shot and a bright dusk shot cannot take the
   same numbers), so each is tuned to land at the same perceived weight and
   framed so the lit subject, not the sky, fills the card.
   A note on the numbers: brightness() multiplies, so it cannot lift true
   black. The near-black night sources are opened up with contrast() BELOW 1
   (which pulls values toward mid-grey) and brightness ABOVE 1, while the
   bright dusk sources take the opposite treatment. */
.venue-grid .venue-card:nth-child(1) { --img-bright: 0.88; --img-contrast: 1.14; --img-pos: center 42%; }
.venue-grid .venue-card:nth-child(2) { --img-bright: 0.80; --img-contrast: 1.16; --img-pos: center 38%; }
/* Card 3 is framed low on purpose: the hotel's own illuminated sign sits at
   about 38% of the frame and collided with the card's eyebrow, printing the
   venue name twice. The colonnade below it reads better anyway. */
.venue-grid .venue-card:nth-child(3) { --img-bright: 0.86; --img-contrast: 1.12; --img-pos: 0% center; }
.venue-grid .venue-card:nth-child(4) { --img-bright: 1.75; --img-contrast: 0.84; --img-pos: center 50%; }
.venue-grid .venue-card:nth-child(5) { --img-bright: 1.35; --img-contrast: 0.94; --img-pos: center 46%; }
.venue-grid .venue-card:nth-child(6) { --img-bright: 1.55; --img-contrast: 0.86; --img-pos: center 46%; }
/* Scrim: the photograph reads as a photograph at the top of the card, then
   falls to near-black under the copy and the badges so the type never fights
   it. Tuned against a 375px phone, where the copy block is tallest. */
.venue-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      rgba(0, 0, 0, 0.10) 0%,
      rgba(0, 0, 0, 0.42) 26%,
      rgba(0, 0, 0, 0.82) 52%,
      rgba(0, 0, 0, 0.94) 76%),
    linear-gradient(90deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 58%);
}
.venue-card:hover .venue-media img {
  filter: grayscale(1) contrast(1.22) brightness(calc(var(--img-bright, 0.86) * 1.28));
  transform: scale(1.1);
}
/* Layer order over the photograph: shaft above ground, content above both. */
.venue-card::before { z-index: 1; }
.venue-card > *:not(.venue-media):not(.venue-card-link) { position: relative; z-index: 2; }

/* ------------------------------------------------------- the open door
   HOUSE DEVIATION, LOGGED. Green is a FOURTH colour and the Swivul brand
   book defines three ("never invent a green or amber into a three-colour
   brand"). It is here because it carries a meaning red cannot: red says
   closed to the public, green says we can open it. Gated on Shabbir's
   sign-off at VERIFICATION-CHECKLIST row 19.
   To revert: delete this block and swap .badge-invite back to
   .badge-access on the two invite-only cards in index.html. */
:root { --go: #0BDA7D; }
.badge-invite {
  border: 1px solid var(--go);
  color: var(--white);
  background: transparent;
  animation: invite-pulse 2.8s ease-in-out infinite;
}
@keyframes invite-pulse {
  0%, 100% {
    box-shadow: 0 0 12px 0 rgba(11, 218, 125, 0.22),
                inset 0 0 10px rgba(11, 218, 125, 0.08);
  }
  50% {
    box-shadow: 0 0 32px 7px rgba(11, 218, 125, 0.52),
                inset 0 0 14px rgba(11, 218, 125, 0.18);
  }
}
@media (prefers-reduced-motion: reduce) {
  .badge-invite { animation: none; box-shadow: 0 0 14px rgba(11, 218, 125, 0.3); }
  .venue-media img { transition: none; }
  .venue-card:hover .venue-media img { transform: scale(1.05); }
}

/* ============================== badge hierarchy v2 (2026-08-21, Josh's call)
   The confusion this fixes: two pills side by side read as two competing
   statuses. They are not. The red one is the world without Swivul (closed to
   the public); the green one is the world with Swivul (the reason the page
   exists). So the row is now two LABELLED columns, and the green side is the
   hero: larger, lit, and glistening, while the red side drops to a quiet
   factual note.
   Green = Swivul can open this. Red = the public cannot. Nothing else. */
.venue-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem;
  align-items: flex-end;
}
.badge-col { display: flex; flex-direction: column; gap: 0.5rem; }
.badge-cap {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.5625rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--white-40);
  line-height: 1;
}
.badge-col-hero .badge-cap { color: var(--go); }

/* The quiet side. Still red, still true, no longer shouting. */
.badge-soldout {
  font-size: 0.6875rem;
  padding: 0.45rem 1rem;
  letter-spacing: 0.14em;
  animation: none;
  border-color: rgba(209, 0, 31, 0.75);
  color: var(--white-60);
  box-shadow: 0 0 10px rgba(209, 0, 31, 0.16);
}

/* The hero side. Both access states are green now: the distinction the buyer
   needs is "Swivul can get you in", not which mechanism does it.
   Glow pulse (pop) plus a light sweep across the face (glisten). */
.badge-access,
.badge-invite {
  position: relative;
  overflow: hidden;
  font-size: 0.8125rem;
  padding: 0.72rem 1.4rem;
  letter-spacing: 0.15em;
  border: 1px solid var(--go);
  color: var(--white);
  background-color: rgba(11, 218, 125, 0.06);
  background-image: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  animation: invite-pulse 2.8s ease-in-out infinite;
}
/* The glisten: a white sweep travelling across the pill, on its own clock so
   it never syncs with the glow and never reads as a loading bar. */
.badge-access::after,
.badge-invite::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 45%;
  pointer-events: none;
  background: linear-gradient(105deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.42) 50%,
    rgba(255, 255, 255, 0) 100%);
  animation: badge-glisten 5.2s ease-in-out infinite;
}
@keyframes badge-glisten {
  0%, 58%  { left: -50%; }
  92%, 100% { left: 105%; }
}

/* Native select: without an explicit dark colour-scheme the option list
   renders with the OS default white ground while inheriting the field's
   white text, so every option is white on white and the menu looks empty.
   That was the broken Party size dropdown. */
.field-select { color-scheme: dark; }
.field-select option {
  background-color: var(--black);
  color: var(--white);
}

/* One-of-two contact pair (access.html): Telegram or WhatsApp. */
.field-pair-note {
  font-size: var(--fs-caption);
  color: var(--white-40);
  margin: 0 0 0.5rem;
}
.field-error {
  display: none;
  font-size: var(--fs-caption);
  color: var(--red);
  margin-top: 0.5rem;
}
.field-error.is-shown { display: block; }

/* book.html: three doors. */
@media (min-width: 900px) {
  .doors-3 { grid-template-columns: repeat(3, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .badge-access::after,
  .badge-invite::after { animation: none; opacity: 0; }
}

/* One-of-two contact pair fields (access.html). */
.field-pair { display: grid; gap: 0.5rem; }
.field-sublabel {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--white-40);
  margin-top: 0.35rem;
}
.door-grid .door-card:nth-child(3) { --shaft: 128deg; }
/* Three doors: hold one column until there is room for all three, so a
   2-up grid never strands the third door on its own row. */
@media (min-width: 720px) and (max-width: 899px) {
  .doors-3 { grid-template-columns: 1fr; }
}

/* ========================================== proof: real client testimonials
   Lifted verbatim from swivul.com (2026-08-21). Five stars carry the go-green
   and the same glisten as the access badges, so the page keeps one visual
   language: green is what Swivul delivered. Gold stars were the obvious call
   and are not available: the brand runs three colours and the green is already
   a logged deviation (checklist row 19). One deviation, used consistently,
   beats two. */
.review-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  margin-top: clamp(2.5rem, 5vw, 3.75rem);
}
@media (min-width: 760px)  { .review-grid { grid-template-columns: 1fr 1fr; gap: 1.75rem; } }
@media (min-width: 1120px) { .review-grid { grid-template-columns: repeat(3, 1fr); } }
.review {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: clamp(1.6rem, 3vw, 2.1rem);
  transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.review:hover {
  transform: translateY(-5px);
  border-color: rgba(255, 255, 255, 0.34);
  box-shadow: inset 0 1px 0 var(--glass-topcatch), 0 30px 70px rgba(0, 0, 0, 0.7);
}
.review-quote {
  margin: 1.1rem 0 0;
  font-size: 1rem;
  line-height: 1.72;
  color: var(--white);
  quotes: none;
}
.review-by {
  margin-top: auto;
  padding-top: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.review-name {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: 0.06em;
  color: var(--white);
}
.review-role {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--white-40);
}
/* Five stars, lit and glistening. */
.stars {
  display: inline-flex;
  gap: 0.28rem;
  position: relative;
  overflow: hidden;
  padding-right: 0.2rem;
}
.star {
  font-size: 1.0625rem;
  line-height: 1;
  color: var(--go);
  text-shadow: 0 0 14px rgba(11, 218, 125, 0.55);
}
.star {
  animation: star-glisten 4.6s ease-in-out infinite;
}
@keyframes star-glisten {
  0%, 62%, 100% {
    text-shadow: 0 0 14px rgba(11, 218, 125, 0.55);
    filter: none;
  }
  74% {
    text-shadow: 0 0 10px rgba(11, 218, 125, 0.7),
                 0 0 26px rgba(255, 255, 255, 0.85);
    filter: brightness(1.65);
  }
}
/* The bloom runs left to right along the row, so it reads as one light
   travelling across five stars rather than five stars blinking. */
.star:nth-child(2) { animation-delay: 0.1s; }
.star:nth-child(3) { animation-delay: 0.2s; }
.star:nth-child(4) { animation-delay: 0.3s; }
.star:nth-child(5) { animation-delay: 0.4s; }
/* Stagger so six cards never sweep in lockstep. */
.review-grid .review:nth-child(2) .stars { animation-delay: 0.45s; }
.review-grid .review:nth-child(3) .stars { animation-delay: 0.9s; }
.review-grid .review:nth-child(4) .stars { animation-delay: 1.35s; }
.review-grid .review:nth-child(5) .stars { animation-delay: 1.8s; }
.review-grid .review:nth-child(6) .stars { animation-delay: 2.25s; }
.review-grid .review:nth-child(2) .star { animation-delay: 0.45s; }
.review-grid .review:nth-child(3) .star { animation-delay: 0.9s; }
.review-grid .review:nth-child(4) .star { animation-delay: 1.35s; }
.review-grid .review:nth-child(5) .star { animation-delay: 1.8s; }
.review-grid .review:nth-child(6) .star { animation-delay: 2.25s; }
@media (prefers-reduced-motion: reduce) {
  .star { animation: none; }
  .review { transition: none; }
}

/* Proof block sits directly under the hero (2026-08-21), so its vertical
   footprint is deliberately tighter than a standard section: the reader must
   pass it, not wade through it, before reaching THE LIST. */
.section-proof { padding-block: clamp(3rem, 6.5vw, 5rem); }
.section-proof .review-grid { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.section-proof .review { padding: clamp(1.35rem, 2.4vw, 1.75rem); }
.section-proof .review-quote { font-size: 0.9375rem; line-height: 1.65; }
.section-proof .review-by { padding-top: 1.15rem; }

/* ================================ CTA availability (2026-08-21, Josh's call)
   The ask must never be more than a thumb-flick away. Three devices:
   1. the header CTA goes red, so the always-on-screen sticky header carries
      the action rather than whispering it in glass,
   2. a CTA strip between every major section, each phrased for the section it
      follows so it reads as a consequence, not a repeated banner,
   3. the venue cards themselves become the link (see .venue-card-link). */
.cta-strip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  text-align: center;
  padding-block: clamp(2.25rem, 5vw, 3.25rem);
}
.cta-strip .btn { min-width: min(100%, 22rem); }
.cta-strip-note {
  margin: 0;
  font-size: var(--fs-caption);
  color: var(--white-40);
}
/* A hairline above each strip so it reads as a turn in the page, not a floating
   button. */
.cta-strip-rule {
  width: 100%;
  max-width: 6rem;
  height: 1px;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--red) 50%, rgba(255,255,255,0) 100%);
  margin-bottom: 0.4rem;
}

/* The whole venue card is a link to the ask. A stretched overlay anchor keeps
   the card's internal markup (badges, ghost numeral, image) intact while making
   every pixel clickable, and it stays a real focusable link for keyboards. */
.venue-card { cursor: pointer; }
.venue-card-link {
  position: absolute;
  inset: 0;
  z-index: 5;
  text-indent: -9999px;
  overflow: hidden;
  white-space: nowrap;
}
.venue-card-link:focus-visible {
  outline: 2px solid var(--go);
  outline-offset: -4px;
  border-radius: var(--radius-card);
}
/* The affordance: a quiet line that lights green on hover, so the card visibly
   offers something rather than silently being clickable. */
.venue-go {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.1rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--white-40);
  transition: color 0.3s ease, gap 0.3s ease;
}
.venue-card:hover .venue-go,
.venue-card-link:focus-visible ~ .venue-beat .venue-go {
  color: var(--go);
  gap: 0.85rem;
}
@media (prefers-reduced-motion: reduce) {
  .venue-go { transition: none; }
}
/* The affordance closes the card, under the status badges. */
.venue-beat .venue-go { margin-top: 1.35rem; }
