/* ============================================================
   DJ WIZ HOFFA — HOME (index.html) page layout
   css/pages/index.css?v=6 — loads AFTER tokens.css + site.css.
   Layout only: never restyles the shared shell, never overrides
   tokens, never declares :root. Motion hooks (data-hero /
   data-reveal / data-reveal-group / data-parallax / data-marquee /
   data-tilt) are NOT pre-hidden here — the no-JS floor stays fully
   readable (ARCHITECTURE.md §5).

   Palette law honored: crimson is surfaces, rules and accents only.
   Every piece of running text is ivory or smoke.

   TOC:
   00 Page rhythm           06 Statement band
   01 Hero                  07 Press credibility
   02 Marquee               08 Music preview
   03 Stats rail            09 Events preview
   04 Section index mark    10 Booking process
   05 Service lanes         11 Closing CTA
   05b Event Wizard band    06 About preview
   06b Statement band
   ============================================================ */

/* ---------- 00 Page rhythm ----------
   Home breathes wider than the interior pages: the opening frame of
   a documentary, not a brochure grid. */
.hsect { padding-block: clamp(4.75rem, 9.5vw, 9rem); }

/* ---------- 01 Hero ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  padding-top: calc(var(--header-h) + var(--sp-6));
}

/* Grade: bottom lift for copy legibility, a left wall so the type has
   ground, and one controlled crimson bloom off the exit-sign side. */
.hero-grade {
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  pointer-events: none;
  background:
    linear-gradient(to top,
      rgba(10, 10, 10, 0.98) 0%,
      rgba(10, 10, 10, 0.74) 26%,
      rgba(10, 10, 10, 0.26) 58%,
      rgba(10, 10, 10, 0.55) 100%),
    linear-gradient(100deg,
      rgba(10, 10, 10, 0.92) 0%,
      rgba(10, 10, 10, 0.5) 40%,
      rgba(10, 10, 10, 0) 80%),
    radial-gradient(115% 78% at 6% 10%, rgba(158, 27, 50, 0.22), transparent 58%);
}

/* Archival texture — vinyl-fine scanline, barely there. */
.hero-grain {
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  pointer-events: none;
  opacity: 0.45;
  background-image: repeating-linear-gradient(
    0deg,
    rgba(242, 239, 228, 0.03) 0 1px,
    rgba(0, 0, 0, 0) 1px 3px
  );
}

.hero-inner {
  position: relative;
  z-index: var(--z-content);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-5);
  padding-block: var(--sp-8) clamp(1.75rem, 5vh, 3rem);
}

.hero-name {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  font-size: clamp(3.5rem, 18vw, 12rem);
  line-height: 0.88;
  letter-spacing: 0.005em;
  margin-block: var(--sp-1) var(--sp-2);
}

.hero-tag {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: clamp(1.05rem, 2.2vw, 1.45rem);
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--ivory);
}

.hero-tag::before {
  content: "";
  display: block;
  width: clamp(58px, 9vw, 112px);
  height: 3px;
  background: var(--crimson);
  margin-bottom: var(--sp-4);
}

.hero-lead {
  font-size: var(--fs-lead);
  color: var(--ivory-80);
  max-width: 46ch;
}

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-2);
}

.hero-meta {
  width: 100%;
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-strong);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-6);
}

.hero-meta li {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ivory-60);
}

/* Scroll cue — desktop only, 44px+ target, keyboard reachable. */
.hero-cue {
  display: none;
  position: absolute;
  right: var(--gutter);
  bottom: clamp(1.75rem, 5vh, 3rem);
  z-index: var(--z-content);
  width: 44px;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  padding-block: var(--sp-2);
  text-decoration: none;
  color: var(--smoke);
  transition: color var(--dur-1) var(--ease);
}

.hero-cue:hover { color: var(--ivory); }

.hero-cue-text {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  writing-mode: vertical-rl;
}

.hero-cue-line {
  position: relative;
  width: 1px;
  height: 62px;
  background: var(--line-strong);
  overflow: hidden;
}

.hero-cue-line::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 26px;
  background: var(--crimson-hot);
  animation: cue-drop 2.4s var(--ease-io) infinite;
}

@keyframes cue-drop {
  0%   { transform: translateY(-100%); }
  60%  { transform: translateY(240%); }
  100% { transform: translateY(240%); }
}

@media (min-width: 1080px) {
  .hero-cue { display: flex; }
}

/* Short desktop viewports: keep the primary CTA above the fold —
   booking is never pushed out of the opening frame. */
@media (min-width: 980px) and (max-height: 940px) {
  .hero-inner { gap: var(--sp-4); }

  .hero-name { font-size: clamp(3.5rem, 13.5vh, 9rem); }

  .hero-tag::before { margin-bottom: var(--sp-3); }

  .hero-meta {
    margin-top: var(--sp-4);
    padding-top: var(--sp-3);
  }
}

/* ---------- 02 Marquee ----------
   No-JS floor: a centered, wrapping credits wall. motion.js may
   convert [data-marquee] into a seamless horizontal loop. */
.marq {
  padding-block: clamp(2.5rem, 5vw, 4rem);
  overflow: hidden;
}

.marq-wrap { margin-inline: auto; }

.marq-label {
  text-align: center;
  color: var(--smoke);
  margin-bottom: var(--sp-5);
}

.marq-track {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.7rem 0;
}

.marq-track li {
  font-family: var(--font-logo);
  font-size: clamp(1.15rem, 2.3vw, 1.7rem);
  line-height: 1.15;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ivory-60);
  white-space: nowrap;
}

.marq-track .sep {
  /* A wall of 23 crimson diamonds spends the accent everywhere and cheapens
     the singular crimson moments. Muted to a quiet archival dot so crimson
     stays rare (decorative — no contrast concern). */
  color: var(--smoke);
  font-size: 0.45em;
  display: inline-block;
  vertical-align: 0.45em;
  margin-inline: clamp(1.1rem, 2.6vw, 2.4rem);
}

/* ---------- 03 Stats rail ----------
   The rail is one short row of numerals; on the home rhythm
   (clamp .. 9rem) it was floating in ~137px of black top and bottom
   and the band read as an orphan gap rather than a deliberate proof
   strip. Tightened to roughly 2/3 of the page rhythm — the full-height
   hairline dividers between stats now carry the band's structure. */
.stats-sect { padding-block: clamp(3.25rem, 6.25vw, 6rem); }

.stats-rail {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-7) var(--sp-6);
}

.stats-rail .stat-label { max-width: 22ch; }

/* At base (2-col until 768) the five stats fall 2/2/1 and strand S.E.A.
   alone in the bottom-left with a void beside it — reads as an accident.
   Let the final stat close the rail as a deliberate full-width line. */
@media (max-width: 767.98px) {
  .stats-rail .stat:last-child { grid-column: 1 / -1; }
}

.stats-rail .stat--award .stat-num {
  font-size: clamp(2rem, 4.2vw, 3.1rem);
  letter-spacing: 0.02em;
}

@media (min-width: 768px) {
  .stats-rail {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-7) 0;
  }

  .stats-rail .stat {
    padding-inline: clamp(1rem, 2.6vw, 2rem);
    border-left: 1px solid var(--line-strong);
  }

  .stats-rail .stat:nth-child(3n + 1) {
    padding-left: 0;
    border-left: 0;
  }
}

@media (min-width: 980px) {
  .stats-rail { grid-template-columns: repeat(5, 1fr); }

  .stats-rail .stat:nth-child(3n + 1) {
    padding-left: clamp(1rem, 2.6vw, 2rem);
    border-left: 1px solid var(--line-strong);
  }

  .stats-rail .stat:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* ---------- 04 Section index mark ----------
   Sits inside the shared .eyebrow as a flex item — the shell rule is
   never redefined, only this new child is styled. */
.s-idx {
  font-family: var(--font-logo);
  font-size: 1.05em;
  line-height: 1;
  letter-spacing: 0.1em;
  color: var(--ivory);
}

/* ---------- 05 Service lanes ---------- */
.lanes-head-main { margin-bottom: var(--sp-5); }

.lanes-title { font-size: var(--fs-display); }

.lanes-head-lead {
  font-size: var(--fs-lead);
  color: var(--ivory-60);
  max-width: 46ch;
}

/* Editorial split: the thesis carries the left, the qualifier sits
   right and bottom-aligned to the last line of the display type. */
@media (min-width: 980px) {
  .lanes-head {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    column-gap: clamp(2.5rem, 6vw, 6rem);
    align-items: end;
  }

  .lanes-head-main { margin-bottom: 0; }

  .lanes-head-lead {
    margin-bottom: 0.7rem;
    max-width: 38ch;
  }
}

.lanes {
  border-top: 1px solid var(--line);
  margin-top: clamp(2rem, 5vw, 3.5rem);
}

.lanes > li { border-bottom: 1px solid var(--line); }

.lane {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-4) var(--sp-5);
  padding: clamp(1.25rem, 3vw, 2rem) var(--sp-3);
  text-decoration: none;
  transition:
    background var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    padding-left var(--dur-2) var(--ease);
}

.lane:hover,
.lane:focus-visible {
  background: var(--panel);
  box-shadow: inset 3px 0 0 var(--crimson);
  padding-left: var(--sp-5);
}

.lane-num {
  align-self: start;
  padding-top: 0.35em;
  font-family: var(--font-logo);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1;
  color: var(--smoke);
  min-width: 2ch;
}

.lane-body { display: block; }

.lane-title { font-size: clamp(1.6rem, 3.4vw, 2.6rem); }

.lane-copy {
  margin-top: 0.45rem;
  max-width: 56ch;
  color: var(--ivory-60);
  font-size: var(--fs-small);
}

.lane-arrow {
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  line-height: 1;
  color: var(--smoke);
  transition: transform var(--dur-2) var(--ease), color var(--dur-1) var(--ease);
}

.lane:hover .lane-arrow,
.lane:focus-visible .lane-arrow {
  transform: translateX(6px);
  color: var(--ivory);
}

/* ---------- 05b Event Wizard band ----------
   The differentiator, and the biggest moment on the page after the hero.
   Deliberately NOT part of the .sect--band alternation: it carries its own
   crimson-haze ground so it reads as a feature, not as the next stripe.
   Palette law holds — the crimson is wash, rule and surface only; every
   running line here is ivory or smoke. */
.wiz-sect {
  padding-block: clamp(5.25rem, 10.5vw, 9.75rem);
  border-block: 1px solid var(--line);
}

/* Extend .haze rather than setting a background: a section background paints
   over .haze::before (z-index --z-bg) and would kill the wash — the same
   trap documented on .closing-sect below. The ivory lift is what separates
   this band from the lanes band directly above it. */
/* The ivory lift ends on a fixed length, not a percentage — same rule as
   .sect--band in site.css, so the arrival reads identically on an 800px band
   and a 1900px one. On a percentage stop it smeared across ~860px at 1440
   and never cleared before the beats. */
.wiz-sect.haze::before {
  background:
    radial-gradient(75% 60% at 18% 0%, var(--haze), transparent 68%),
    linear-gradient(to bottom,
      color-mix(in srgb, var(--ivory) 4%, transparent) 0, transparent 220px);
}

.wiz-grid {
  display: grid;
  gap: var(--sp-7);
  align-items: start;
}

@media (min-width: 980px) {
  .wiz-grid {
    grid-template-columns: 7fr 5fr;
    gap: clamp(3rem, 7vw, 6rem);
    /* Centred, not start-aligned: the copy column runs ~550px taller than the
       figure, which left the whole lower-right of the band void and pressed
       the photo against the display headline. Safe with data-parallax — this
       does not touch the transform channel the way position:sticky would. */
    align-items: center;
  }
}

/* Page-scoped step down from --fs-display: at that scale the forced couplet
   break overflowed line 2 and stranded "BEFORE" on its own line from 980 up
   (a ~1px miss at 1440). This settles the headline to the intended 2 lines at
   every breakpoint. */
.wiz-title { font-size: clamp(2.6rem, 7vw, 6rem); }

.wiz-lead { max-width: 52ch; }

/* Beats — the four things the Wizard actually does. Same crimson-tick rule
   as .step so the page has one vocabulary for numbered sequences. */
.wiz-beats {
  display: grid;
  gap: var(--sp-6) var(--sp-5);
  list-style: none;
  padding: 0;
}

@media (min-width: 620px) {
  .wiz-beats { grid-template-columns: repeat(2, 1fr); }
}

.wiz-beat {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}

.wiz-beat::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 38px;
  height: 3px;
  background: var(--crimson);
}

.wiz-beat-num {
  font-family: var(--font-logo);
  font-size: clamp(1.9rem, 3.4vw, 2.5rem);
  line-height: 1;
  color: var(--smoke);
}

.wiz-beat-title { font-size: 1.3rem; }

.wiz-beat-copy {
  color: var(--ivory-60);
  font-size: var(--fs-small);
  max-width: 36ch;
}

.wiz-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4) var(--sp-6);
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
}

/* Stays a solid crimson primary for the band, but drops to the base .btn
   scale (56px -> 48px). At --lg it measured wider than the hero's Request
   Availability, making the page's LARGEST crimson fill the one that points
   away from the booking path. The two Request Availability CTAs stay the
   tallest crimson moments on the page. */
.wiz-cta .btn--lg {
  min-height: 48px;
  padding: 1rem 1.9rem;
  font-size: 1rem;
}

/* The booking path stays one tap away and stays legible: --ivory-80 on the
   band ground, not a crimson text tone (crimson fails AA for copy). */
.wiz-cta-alt {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 44px;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ivory-80);
  text-decoration: none;
  border-bottom: 1px solid var(--line-crimson);
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}

.wiz-cta-alt:hover,
.wiz-cta-alt:focus-visible {
  color: var(--ivory);
  border-bottom-color: var(--crimson-hot);
}

.wiz-cta-alt span { transition: transform var(--dur-2) var(--ease); }
.wiz-cta-alt:hover span { transform: translateX(5px); }

.wiz-note {
  margin-top: var(--sp-5);
  max-width: 56ch;
  color: var(--ivory-60);
  font-size: var(--fs-small);
}

.wiz-figure {
  justify-self: center;
  width: min(100%, 430px);
  margin: 0;
}

.wiz-figure img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 32%;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-2);
  /* Cindy §31, same dose as .music-figure — the record-store set runs far
     brighter (meanLum 106) than the rest of the page. */
  filter: saturate(0.82) brightness(0.9);
}

.wiz-figcap {
  margin-top: var(--sp-4);
  padding-left: var(--sp-4);
  border-left: 2px solid var(--crimson);
  color: var(--smoke);
  font-family: var(--font-label);
  font-size: var(--fs-small);
  letter-spacing: 0.02em;
  max-width: 34ch;
}

@media (min-width: 980px) {
  /* No position:sticky here on purpose — the img carries data-parallax and
     the two transforms fight each other. Matches .music-figure exactly. */
  .wiz-figure {
    justify-self: end;
    width: 100%;
  }
  .wiz-figure img { aspect-ratio: 5 / 6; }
}

/* ---------- 06 About preview ---------- */

/* A real edge event at the wiz -> about seam. Without it this section, the
   Wizard band and .statement were three consecutive stretches on flat --bg —
   ~2,900px of unbroken ground at 1440 between the lanes band and the press
   band. background-image only, so no ground colour is introduced and the
   palette stays black. The eyebrow starts one --sect-pad down, where the lift
   has decayed to ~0.85% and --smoke still measures ~5.0:1. */
.about-sect {
  background-image: linear-gradient(to bottom,
    color-mix(in srgb, var(--ivory) 2.6%, transparent) 0, transparent 190px);
}

.about-prev {
  display: grid;
  gap: var(--sp-7);
  align-items: center;
}

@media (min-width: 980px) {
  .about-prev {
    grid-template-columns: 5fr 6fr;
    gap: clamp(3rem, 7vw, 6.5rem);
  }
}

.about-figure {
  position: relative;
  justify-self: center;
  width: min(100%, 480px);
  aspect-ratio: 4 / 5;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-2);
}

.about-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 16%;
  /* Cindy §31 bg-mute: the street shot is a blown-out white wall plus a
     full-saturation bomber — ~7x the luminance of every other region on
     the page, so the eye lands on the jacket instead of the headline.
     Graded to the same ~40-55% strength the hero video already gets. */
  filter: saturate(0.68) contrast(1.06) brightness(0.82);
}

/* Overlay lives on the figure, not the img, so it stays put while the
   img's data-parallax slides underneath. --z-raise clears the
   GSAP-transformed img's stacking context. */
.about-figure::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--z-raise);
  pointer-events: none;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg) 48%, transparent) 0%,
      color-mix(in srgb, var(--bg) 14%, transparent) 42%,
      color-mix(in srgb, var(--bg) 62%, transparent) 100%),
    radial-gradient(120% 85% at 50% 38%,
      transparent 38%,
      color-mix(in srgb, var(--bg) 55%, transparent) 100%);
}

@media (min-width: 980px) {
  .about-figure {
    justify-self: start;
    width: 100%;
    aspect-ratio: 5 / 6;
  }
}

.about-copy .sect-head { margin-bottom: var(--sp-5); }

.about-body {
  margin-top: var(--sp-5);
  color: var(--ivory-80);
  max-width: 58ch;
}

.about-cta { margin-top: var(--sp-6); }

/* ---------- 06b Statement band ----------
   The page's one breath: rules, huge type, and a lot of nothing. */
.statement {
  border-block: 1px solid var(--line);
  padding-block: clamp(3.5rem, 9vw, 8rem);
}

.statement-label {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
  margin-bottom: var(--sp-5);
}

.statement-text {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 1.04;
  letter-spacing: 0.01em;
  font-size: clamp(2rem, 5.6vw, 4.6rem);
  color: var(--ivory);
  max-width: 22ch;
  text-wrap: balance;
}

/* ---------- 07 Press credibility ---------- */
.press-grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
}

@media (min-width: 980px) {
  .press-grid {
    grid-template-columns: 5fr 6fr;
    gap: clamp(3rem, 7vw, 6rem);
    align-items: start;
  }
}

.press-lead-col .sect-head { margin-bottom: var(--sp-6); }

.press-proof {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--sp-5);
  padding: var(--sp-5) 0;
  border-block: 1px solid var(--line);
}

.press-proof-num {
  font-family: var(--font-logo);
  font-size: clamp(3.4rem, 8vw, 5.25rem);
  line-height: 0.85;
  color: var(--ivory);
}

.press-proof-label {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1.3;
  color: var(--ivory-80);
  max-width: 26ch;
}

.press-accolades {
  margin-top: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.press-accolades li {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ivory-80);
}

.press-accolades li::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  background: var(--crimson);
  transform: rotate(45deg);
}

.press-cta { margin-top: var(--sp-7); }

.press-wall-label {
  color: var(--smoke);
  padding-bottom: var(--sp-4);
}

.press-wall {
  display: grid;
  grid-template-columns: 1fr;
  column-gap: var(--sp-6);
}

@media (min-width: 560px) {
  .press-wall { grid-template-columns: repeat(2, 1fr); }
}

.press-wall li {
  padding-block: clamp(0.85rem, 2vw, 1.15rem);
  border-top: 1px solid var(--line);
  font-family: var(--font-logo);
  font-size: clamp(1.15rem, 2.4vw, 1.55rem);
  line-height: 1.2;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ivory-80);
}

/* ---------- 08 Music preview ---------- */
.music-grid {
  display: grid;
  gap: var(--sp-7);
  align-items: center;
}

@media (min-width: 980px) {
  .music-grid {
    grid-template-columns: 7fr 5fr;
    gap: clamp(3rem, 7vw, 6rem);
    align-items: start;
  }
}

.plat-grid { display: grid; gap: var(--sp-4); }

@media (min-width: 560px) {
  .plat-grid { grid-template-columns: repeat(2, 1fr); }
}

.plat {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--sp-2);
  min-height: 146px;
  padding: var(--sp-5);
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-decoration: none;
  transition:
    border-color var(--dur-1) var(--ease),
    background var(--dur-2) var(--ease),
    transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}

.plat::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--crimson);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-2) var(--ease);
}

.plat:hover,
.plat:focus-visible {
  border-color: var(--line-crimson);
  background: var(--panel-2);
  transform: translateY(-3px);
  box-shadow: var(--shadow-1);
}

.plat:hover::after,
.plat:focus-visible::after { transform: scaleX(1); }

.plat-label {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
}

.plat-name {
  font-family: var(--font-logo);
  font-size: clamp(1.7rem, 3vw, 2.15rem);
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--ivory);
}

.plat-arrow {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-4);
  font-size: 1.1rem;
  color: var(--smoke);
  transition: color var(--dur-1) var(--ease), transform var(--dur-2) var(--ease);
}

.plat:hover .plat-arrow,
.plat:focus-visible .plat-arrow {
  color: var(--ivory);
  transform: translate(2px, -2px);
}

.music-cta { margin-top: var(--sp-6); }

.music-figure {
  justify-self: center;
  width: min(100%, 430px);
  aspect-ratio: 4 / 5;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-2);
}

.music-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
  /* Cindy §31, lighter dose — the record-store shot is the milder
     version of the same problem (meanLum 106 vs the page's 23-48). */
  filter: saturate(0.82) brightness(0.9);
}

@media (min-width: 980px) {
  .music-figure {
    justify-self: end;
    width: 100%;
    aspect-ratio: 5 / 6;
  }
}

/* ---------- 09 Events preview ---------- */
.events-grid {
  display: grid;
  gap: var(--sp-7);
  align-items: start;
}

@media (min-width: 980px) {
  .events-grid {
    grid-template-columns: 7fr 5fr;
    gap: clamp(3rem, 7vw, 6rem);
  }
}

.events-sect .flyer-meta h3 { font-size: clamp(1.4rem, 3vw, 2rem); }

.ev-facts {
  border-top: 1px solid var(--line);
}

.ev-row {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: var(--sp-4);
  padding-block: var(--sp-4);
  border-bottom: 1px solid var(--line);
}

.ev-row dt {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
  padding-top: 0.22rem;
}

.ev-row dd {
  margin: 0;
  font-size: var(--fs-body);
  color: var(--ivory);
}

.events-note {
  margin-top: var(--sp-5);
  color: var(--ivory-60);
  font-size: var(--fs-small);
  max-width: 46ch;
}

.events-cta { margin-top: var(--sp-6); }

/* ---------- 10 Booking process ---------- */
.steps {
  display: grid;
  gap: var(--sp-6) var(--sp-5);
}

@media (min-width: 560px) {
  .steps { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 980px) {
  .steps { grid-template-columns: repeat(4, 1fr); }
}

.step {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}

.step::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 38px;
  height: 3px;
  background: var(--crimson);
}

.step-num {
  font-family: var(--font-logo);
  font-size: clamp(2.2rem, 4vw, 2.9rem);
  line-height: 1;
  color: var(--smoke);
}

.step h3 { font-size: 1.3rem; }

.step p {
  color: var(--ivory-60);
  font-size: var(--fs-small);
  max-width: 34ch;
}

/* ---------- 11 Closing CTA ---------- */
.closing-sect { padding-block: clamp(5.5rem, 11vw, 10rem); }

/* Cindy §33 gradient rhythm: --bg vs --bg-2 is a 4/255 step, so the
   whole scroll reads as one flat slab and the closing moment — the
   conversion beat — gets no lift of light at all. Extend the existing
   .haze pseudo rather than setting a background on the section: a
   section background would paint OVER .haze::before (z-index --z-bg)
   and kill the crimson wash. */
.closing-sect.haze::before {
  background:
    radial-gradient(70% 55% at 50% 45%,
      color-mix(in srgb, var(--ivory) 7%, transparent) 0%,
      transparent 70%),
    radial-gradient(60% 50% at 50% 0%, var(--haze), transparent 70%);
}

/* Make the band alternation actually visible. background-image is a
   longhand, so it layers on top of .sect--band's background shorthand
   without resetting it. Page-scoped — the other six pages are
   untouched, and --bg-2 in tokens.css is NOT moved. */
.hsect.sect--band {
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ivory) 2.2%, transparent) 0%,
    transparent 55%);
}

.closing { text-align: center; }

.closing-kicker {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--ivory-80);
  margin-bottom: var(--sp-5);
}

.closing-kicker::before {
  content: "";
  display: block;
  width: 26px;
  height: 2px;
  background: var(--crimson);
  margin: 0 auto var(--sp-4);
}

.closing-title {
  font-size: var(--fs-display);
  max-width: 16ch;
  margin-inline: auto;
}

.closing-ctas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}

.closing-area {
  margin-top: var(--sp-6);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--smoke);
}

/* ---------- Reduced motion ----------
   site.css already flattens transitions/animations globally; this
   makes the hero cue's intent explicit and keeps it readable. */
@media (prefers-reduced-motion: reduce) {
  .hero-cue-line::after {
    animation: none;
    transform: none;
    height: 100%;
    opacity: 0.55;
  }
}

/* Event Wizard product mark — sits above the band headline so the product is
   branded before it is described. Inherits ivory from the section. */
.wiz-mark {
  display: block;
  width: clamp(52px, 9vw, 76px);
  height: auto;
  color: var(--ivory);
  margin: clamp(0.9rem, 2.5vw, 1.4rem) 0 clamp(1rem, 2.8vw, 1.6rem);
}

/* ============================================================================
   HERO — PRODUCT-LED (2026-07-20, Jack's directive)
   Event Wizard takes the visual lead; DJ Wiz Hoffa presents it. The H1 carries
   both names so the page keeps its search anchor. The studio photograph stays
   behind it — the man is still the proof the product rests on.
   ========================================================================== */
.hero-name--product {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  font-size: inherit;          /* children set their own scale */
  line-height: 1;
  margin-block: var(--sp-1) var(--sp-4);
}

/* The mark, sized off the wordmark so the lockup scales as one object */
.hero-mark {
  width: clamp(46px, 8.5vw, 88px);
  height: auto;
  color: var(--ivory);
  margin-bottom: clamp(0.7rem, 2vw, 1.15rem);
  filter: drop-shadow(0 2px 14px rgba(0,0,0,.55));
}

/* Record-mark spindle pin — the crimson dot. Routed through the token
   instead of an inline SVG fill so the palette stays single-sourced. The
   spindle is the only <circle> that is a DIRECT child of each mark's <svg>
   (the groove rings all live inside <g fill="none">), so > circle targets
   it precisely and never touches the stroked rings. */
.hero-mark > circle,
.wiz-mark > circle { fill: var(--crimson); }

.hero-product {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.9rem, 11.5vw, 8.5rem);
  line-height: 0.86;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: var(--ivory);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-product {
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--ivory) 26%, white) 0%,
      var(--ivory) 46%,
      color-mix(in srgb, var(--ivory) 74%, var(--bg)) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}
.hero-tm {
  font-size: 0.24em;
  vertical-align: super;
  letter-spacing: 0;
  -webkit-text-fill-color: var(--ivory-80);
  opacity: 0.8;
}

/* Presenter credit — the line Jack asked for, sitting directly under the
   product name. His name carries the crimson so the eye lands on it. */
.hero-by {
  display: block;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: clamp(0.85rem, 2.1vw, 1.15rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--smoke);
  margin-top: clamp(0.75rem, 2vw, 1.1rem);
}
.hero-by-name {
  color: var(--ivory);
  border-bottom: 2px solid var(--crimson);
  padding-bottom: 0.14em;
}

/* The promise line loses the crimson rule here — the mark already opened the
   lockup, and a second crimson element this high crowds it. */
.hero-tag--wide {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 4.2vw, 2.6rem);
  letter-spacing: 0.01em;
  line-height: 1.02;
  text-transform: uppercase;
  max-width: 18ch;
  margin-bottom: var(--sp-3);
}
.hero-tag--wide::before { display: none; }

.hero-note {
  font-family: var(--font-label);
  font-size: clamp(0.76rem, 1.7vw, 0.9rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--smoke);
  margin-top: var(--sp-3);
}

/* The mark + wordmark are the door into the product. The presenter credit is a
   separate link to his story — two destinations, never nested anchors. */
.hero-lockup-link,
.wiz-mark-link {
  display: inline-block;
  text-decoration: none;
  color: inherit;
  transition: opacity var(--dur-1, .25s) ease;
}
.hero-lockup-link { display: block; }
.hero-lockup-link:hover,
.wiz-mark-link:hover { opacity: 0.86; }
.hero-lockup-link:focus-visible,
.wiz-mark-link:focus-visible {
  outline: 2px solid var(--ivory);
  outline-offset: 6px;
  border-radius: 4px;
}
.hero-by-name {
  color: var(--ivory);
  text-decoration: none;
  border-bottom: 2px solid var(--crimson);
  padding-bottom: 0.14em;
  transition: border-color var(--dur-1, .25s) ease;
}
.hero-by-name:hover { border-bottom-color: var(--crimson-hot); }
