/* artist-intro-carousel — the homepage hero (SPEC §4.16).

   Live reference: Content/modules/landing/_intro.scss (.intro / .intro__slider), the
   inline .wave rules in Home.cshtml, and Content/settings/_text.scss for the h1 ramp.

   Layer order (live's, exactly):
     z1 background photo · z2 animated waves · z3 overlay cut-out · z4 headline + CTAs

   Breakpoints follow the Wave 7 convention: TYPE steps at live's own type breakpoints
   (668 / 1220 / 1600), GEOMETRY at live's grid breakpoints (480 / 980), and the fixed-rail
   offset at the theme's own 1025. */

/* Template-provided wrapper (homepage.html), styled here rather than in css/layout.css
   because it is a single-page concern and the shared bundle should not carry it. It is the
   POSITIONED ANCESTOR the player chip is absolutely placed against — see
   artist-player-row/module.html. Note this carousel is position:relative with NO z-index,
   so it does not create a stacking context: the chip's z-index 5 therefore competes in the
   same context as the carousel's own layers and correctly sits above the overlay at z3. */
.gmr-home-hero {
  position: relative;
}

.gmr-artist-intro-carousel {
  position: relative;
  width: 100%;                    /* live uses 100vw; 100% avoids a horizontal scrollbar
                                     when a vertical scrollbar is present */
  min-height: 100vh;              /* live .intro height: 100vh */
  overflow: hidden;
  background-color: var(--gmr-dark);   /* never a white flash while the photo loads */

  /* live .intro padding-top: 178px. Since 2026-10-28 the announcement banner is FIXED
     and overlays this hero exactly like live's .disclaimer, so the hero starts at the top
     of the page and live's literal 178px applies. (The old 137px only made sense while
     the banner was in flow and pushed the hero down 46px — measured heading y −41.)
     ⚠️ Do NOT add var(--gmr-announcement-h) here: live doesn't either. */
  padding-top: 178px;
  box-sizing: border-box;
}

/* Small-viewport units where supported: 100vh is wrong on mobile browsers, where the
   URL bar is counted in and the hero overflows. The banner overlays the hero (fixed,
   like live), so the hero fills one full viewport with no subtraction. */
@supports (min-height: 100svh) {
  .gmr-artist-intro-carousel {
    min-height: 100svh;
  }
}

/* ── z1 / z3 — slide layers ─────────────────────────────────────────────────── */

.gmr-artist-intro-carousel__backgrounds,
.gmr-artist-intro-carousel__overlays {
  position: absolute;
  inset: 0;
}

.gmr-artist-intro-carousel__backgrounds { z-index: 1; }
.gmr-artist-intro-carousel__overlays    { z-index: 3; }

.gmr-artist-intro-carousel__slide,
.gmr-artist-intro-carousel__slide-over {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition-property: opacity;
  transition-duration: 0.8s;      /* live $duration-slow */
  transition-timing-function: ease;
}

.gmr-artist-intro-carousel__slide--active,
.gmr-artist-intro-carousel__slide-over--active {
  opacity: 1;
  z-index: 1;                     /* live: .is-active raises the layer */
}

.gmr-artist-intro-carousel__bg-image,
.gmr-artist-intro-carousel__over-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;       /* live @include object-fit(cover, 50% 50%) */
}

/* ── z2 — the waves ─────────────────────────────────────────────────────────── */

/* Verbatim port of live's inline .wave rules. The paths are drawn by js/hero-wave.js
   (jQuery + GSAP, homepage-only — see module.html for the approved exception). With no JS,
   or under prefers-reduced-motion where hero-wave.js never initialises, `d` stays empty
   and nothing paints.

   NOT ported: live's `canvas { mix-blend-mode: screen }`. There is no <canvas> element on
   live (the container is a <div class="content--canvas">), so that rule matches nothing
   and live's waves do not blend. Adding it here would be a visual change, not parity. */
.gmr-artist-intro-carousel__wave {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.gmr-artist-intro-carousel__wave-svg {
  position: absolute;             /* live .wave */
  inset: 0;
  width: 100%;
  height: 100%;
}

/* ── z4 — headline + primary CTA ────────────────────────────────────────────── */

.gmr-artist-intro-carousel__content {
  position: relative;
  z-index: 4;
  padding: 0 20px;
}
/* live .container--content: 30px sides from 668 when not short (h1 at x 30, 800 wide,
   2026-11-02); the ≥1280 block below takes over with 25% / 50px. */
@media (min-width: 668px) and (min-height: 416px) {
  .gmr-artist-intro-carousel__content { padding: 0 30px; }
}

/* Composes the shared .gmr-heading and overrides only what the hero needs — the same
   pattern hero-background uses. */
.gmr-artist-intro-carousel__heading {
  font-size: 36px;                         /* live .h1 xs */
  line-height: var(--gmr-heading-stack-lh);  /* 0.77 — five stacked lines, exactly this
                                                token's purpose. Live's own per-breakpoint
                                                values run 0.778 / 0.75 / 0.73 / 0.74.
                                                Never re-hardcode (CLAUDE.md). */
  letter-spacing: -0.03em;
  text-shadow: var(--gmr-text-shadow);     /* white type over photography */
  margin: 0 0 24px;
}

.gmr-artist-intro-carousel__word {
  display: block;                          /* live uses literal <br> tags */
}

.gmr-artist-intro-carousel__word--white { color: var(--gmr-white); }
.gmr-artist-intro-carousel__word--blue  { color: var(--gmr-blue); }   /* live #50ccff */

.gmr-artist-intro-carousel__cta {
  margin-top: 8px;
}

/* Live's dark pill (.btn--lg.btn--secondary): 50 tall, 0 30 padding, 12px/700/1px →
   188 wide for "Obtain a license". Local, like artist-bio's license button; the hover
   fill comes from the shared .gmr-btn-fill. */
.gmr-artist-intro-carousel__cta-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  padding: 0 30px;
  border-radius: 50px;
  background-color: var(--gmr-dark);
  color: var(--gmr-white);
  font-family: var(--gmr-font-primary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}
.gmr-artist-intro-carousel__cta-btn:hover,
.gmr-artist-intro-carousel__cta-btn:focus { color: var(--gmr-white); text-decoration: none; }

/* ── z4 — secondary CTA (live's .intro__group-link) ─────────────────────────── */

/* Rail-relative placement. Live patches this element's position with a stack of inline
   !important breakpoint rules in Home.cshtml (left: 35px/top: 490px ≤1279, left: 230px/
   bottom: 145px in the 668–979 band, and more); those patch live's OWN header offsets and
   are deliberately not ported, since our fixed-rail layout differs. Exact placement is on
   the visual-parity checklist. */
.gmr-artist-intro-carousel__secondary {
  position: absolute;
  left: 20px;
  bottom: 120px;                  /* live .intro__group-link bottom: 120px */
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 20px;                      /* live .group gutter (.group > * margin-left: 20px) */
  text-decoration: none;          /* never underline (locked hover rule) */
  color: var(--gmr-white);
}

.gmr-artist-intro-carousel__secondary-icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 50px;                    /* live .btn--lg.btn--square */
  height: 50px;                   /* live .btn--lg */
  border-radius: 50%;             /* ⚠️ live's .btn--lg carries border-radius: 50px on a
                                     50×50 box — a CIRCLE. `btn--square` sets the square
                                     ASPECT (width = height), NOT square corners; omitting
                                     this is what rendered ours as a box. */
  border: 1px solid var(--gmr-white);   /* live .btn--hollow is `border: 1px solid` on
                                           currentColor — full white, not 0.6 alpha */
  color: var(--gmr-white);
  transition: background-color 0.4s ease;   /* live %transition ($duration-normal .4s) */
}
/* Live: hovering the link fills the circle blue, border stays white (.group--link:hover
   .btn--hollow, global.css:4853-4856). Brand blue, not live's #50ccff (locked). Focus
   gets the same fill for keyboard users. */
.gmr-artist-intro-carousel__secondary:hover .gmr-artist-intro-carousel__secondary-icon,
.gmr-artist-intro-carousel__secondary:focus-visible .gmr-artist-intro-carousel__secondary-icon {
  background-color: var(--gmr-blue);
  border-color: var(--gmr-white);
}

.gmr-artist-intro-carousel__secondary-label {
  font-family: var(--gmr-font-primary);
  font-size: 12px;                /* live %text--size-extra-small — 12px at every width */
  line-height: 1.5;
  font-weight: 400;               /* live 400 (measured 2026-10-29; was 700) */
  letter-spacing: 1px;            /* live .text--capitalize */
  text-transform: uppercase;      /* ⚠️ CORRECTION: live's class is NAMED
                                     `.text--capitalize` but is `text-transform:
                                     uppercase !important` (Content/global.css:1541).
                                     The previous comment here claimed it forced title
                                     case ("How Does A Blanket License Work?") — wrong;
                                     it forces ALL CAPS. Parity item 10 rested on that
                                     misreading and is closed by matching live. */
  color: var(--gmr-white);
  text-shadow: var(--gmr-text-shadow);
  max-width: 300px;               /* live sets NO width limit and fits one line. Uppercase
                                     + 1px tracking widens the shipped string ~234px →
                                     ~288px, so 200px wrapped it. 300px clears with
                                     headroom, and a cap is kept (where live has none)
                                     because our column is narrower after the rail fix and
                                     an over-long authored label would otherwise run toward
                                     the player chip. ⚠️ ESTIMATED from Mulish metrics, not
                                     measured — confirm one line in preview; a longer
                                     authored label will still wrap. */
}

/* ── ≥481px — secondary-CTA clearance (SPEC parity item 9) ──────────────────── */

/* OPPOSITE ANCHORS ARE THE BUG. __secondary is `position: absolute` against the
   SECTION (not against __content — they are siblings) and anchored `bottom: 120px`,
   while __content flows from the top. Their positions are therefore computed from
   opposite ends of a section whose height can shrink to the viewport, so on a short
   window the bottom-anchored link rises into the primary CTA. Worst case is ≥1600px,
   where the 100px type step puts __content's bottom at ~626px and the overlap starts
   below ~835px of viewport height. Per-band thresholds (549 / 641 / 665 / never / 758
   / 835px) are in the SPEC discussion; note 981–1219px never collides because
   min-height's 690px floor already exceeds what it needs.

   Live solves the same problem on .intro__group-link with a `max-height: 760px`
   override that moves the link `left: calc(25% + 220px)` and swaps `bottom` for
   `top: 518px`. ⚠️ THE BEHAVIOUR IS PORTED, THE VALUES ARE NOT: 518px is tuned to
   live's own h1 sizes and header offsets, and a +220px rightward shift in our layout
   would run at the player chip (`right: 50px`). Five of live's other six overrides on
   that element fix live-specific horizontal placement our base/≥1025 rules already
   handle differently — see SPEC §4.16 notes; they are deliberately not ported.

   Reserving the band is equivalent and threshold-free: the section's content-driven
   height now always includes the secondary's strip, so `bottom: 120px` can never rise
   into the CTA, at any width or height, and the rule is inert wherever there was
   already room (1920×1080 clearance stays ~245px).
     120px  __secondary bottom offset
   +  50px  __secondary height (the 50×50 icon governs; the label is 1 line × 18px and
            was 2 × 18px = 36px before — either way well under the icon, so the label's
            wrap count has never driven this number)
   +  24px  clearance — also absorbs the ±6px uncertainty in .gmr-button's line box
   = 194px
   ⚠️ RECOMPUTE if __secondary's `bottom` changes or if __secondary-icon's size changes
   — the ICON governs, so only those two move it. Was 192px while the icon was 48px;
   raised to 194px on 2026-09-10 when the icon went to live's 50px. A label would only
   take over if it ever exceeded the icon height (4+ lines at 18px).

   Checked against live at two short window heights on 2026-09-10: live's hero does
   NOT stay one viewport tall either — its stat tiles are pushed below the fold and the
   page scrolls — so growing the section here does not diverge from live's behaviour.
   That was the only objection to this approach over a max-height reposition. Live was
   also confirmed to relocate its secondary link entirely at those heights, consistent
   with the max-height override above.

   Scoped ≥481px on purpose: at ≤480px __secondary is already `position: static` and in
   flow (see the ≤480 block below), where no overlap is possible and this padding would
   only push the link 194px down. */
@media (min-width: 481px) {
  .gmr-artist-intro-carousel__content {
    padding-bottom: 194px;
  }
}

/* ── ≥668px — live's md type step ───────────────────────────────────────────── */

@media (min-width: 668px) {
  .gmr-artist-intro-carousel__heading { font-size: 60px; }   /* live .h1 md */
}

/* ── ≥981px — live's desktop floor ──────────────────────────────────────────── */

@media (min-width: 981px) {
  .gmr-artist-intro-carousel {
    /* live: height 100vh + min-height 690px. No banner subtraction — the banner overlays
       (fixed, like live). Plain vh is correct here: the svh/vh distinction only matters on
       mobile browsers with a collapsing URL bar. */
    min-height: max(100vh, 690px);
  }
}

/* ── ≥1280px — the theme's fixed-rail offset ────────────────────────────────── */

/* Live's container--content is `0 50px 0 25%` at lgl (global.css:3108-3109). A bare 25%
   since 2026-10-28: the old max(340px rail, 25%) floor dates from the fixed 340px rail box;
   the rail is now content-width (~150–220px, header module.css "Desktop (≥1280px)"), so
   25% (320px at 1280) clears it. Parity measured live's heading AND button at exactly 25%
   (360 @1440, 320 @1280) — the former +40px gutter is dropped to match live.
   🔒 Hannah 2026-10-28: keep the heading flush at 25% (do not re-add the gutter).

   ⚠️ KEEP IN STEP WITH stat-counter-row AND songwriter-card-grid-static, which use the
   same 25% on their own padding-left (-dynamic still has the old max(); update it when it
   replaces -static) (live sets 25% on both .container--content and
   .container--grid, so all left edges track together). */
@media (min-width: 1280px) {
  .gmr-artist-intro-carousel__content {
    padding-left: 25%;
    padding-right: 50px;               /* live */
  }
  .gmr-artist-intro-carousel__secondary {
    left: 25%;
  }
}

/* ── ≥1220px — live's lgl type step ─────────────────────────────────────────── */

@media (min-width: 1220px) {
  .gmr-artist-intro-carousel__heading {
    font-size: 80px;                   /* live .h1 lgl */
    line-height: 0.73;                 /* live 58.4/80 — measured 2026-10-29; the shared
                                          0.77 token made the stack 16px taller than live */
    margin-bottom: 50px;               /* live $spacing-heading lgl → CTA at y 520, as live */
  }
}

/* ── ≥1600px — live's xl type step ──────────────────────────────────────────── */

@media (min-width: 1600px) {
  .gmr-artist-intro-carousel__heading { font-size: 100px; line-height: 0.74; }   /* live .h1 xl */
}

/* ── ≤980px — live's lg-down ────────────────────────────────────────────────── */

@media (max-width: 980px) {
  .gmr-artist-intro-carousel__bg-image,
  .gmr-artist-intro-carousel__over-image {
    object-position: 50% 0%;           /* live: top-anchored so faces are not cropped */
  }
}

/* ── ≤767px — tighter top clearance ────────────────────────────────────────── */

@media (max-width: 767px) {
  .gmr-artist-intro-carousel {
    padding-top: calc(var(--gmr-announcement-h, 41px) + 72px);
  }
}

/* ── ≤480px — live's sm-down: centre the content, secondary CTA into the flow ── */

@media (max-width: 480px) {
  .gmr-artist-intro-carousel {
    display: flex;
    flex-direction: column;
    justify-content: center;           /* live sm-down: align-items center, padding-top 0 */
    padding-top: var(--gmr-announcement-h, 41px);
    padding-bottom: 66px;              /* with the link below taking no height, this
                                          centres the h1 at live's y 286 (375×812,
                                          2026-11-02; was 30 and 267) */
  }
  /* Absolute placement has nowhere to go at this width — the chip is hidden below 480px
     and the headline fills the screen — so the link joins the flow instead. Live
     centres only the h1 + button and tucks this row 16px up under the button, so its
     margins cancel its 50px height: it takes no space in the centring. */
  .gmr-artist-intro-carousel__secondary {
    position: static;
    margin: -16px 20px -34px;
  }
}

/* ── Reduced motion ─────────────────────────────────────────────────────────── */

/* module.js honours the reduced_motion_fallback field (static_first_slide → no timer at
   all and the chip's ring hidden; fade_only → keep rotating, crossfade only, ring parked
   at stroke-dashoffset 0 = a COMPLETE static ring, never 182 which would read as broken).
   hero-wave.js does not initialise at all, so the waves never draw. */
@media (prefers-reduced-motion: reduce) {
  .gmr-artist-intro-carousel__slide,
  .gmr-artist-intro-carousel__slide-over {
    transition: none;
  }
}
