/* ==========================================================================
   CHIMAERA — Homepage
   ========================================================================== */

/* ==========================================================================
   LANDING / OPENING FRAME
   ==========================================================================

   .first-screen holds the landing and the next-event strip: together they
   fill the viewport, so the strip is visible on arrival. The landing takes
   whatever height the strip leaves; if the strip hides (no event), the
   landing fills the screen on its own.
   ========================================================================== */

.first-screen {
  display: flex;
  flex-direction: column;

  min-height: 100svh;
}

.landing {
  position: relative;
  flex: 1 0 auto;
  min-height: var(--landing-min-height);
  display: grid;
  place-items: center;
  overflow: hidden;
}

/* ==========================================================================
   INTRO WEBM / GIF — FULL SCREEN
   ========================================================================== */

/* Fixed, not absolute: the intro still covers the whole screen,
   including the next-event strip below the landing. */
.landing__gif {
  position: fixed;
  inset: 0;

  width: 100%;
  height: 100%;

  object-fit: cover;
  object-position: center;

  z-index: 2;

  display: block;

  opacity: 1;
  visibility: visible;

  pointer-events: none;

  transition:
    opacity 700ms var(--ease-editorial),
    visibility 0s linear 700ms;
}

/*
 * JavaScript adds .landing--revealed when the opening animation
 * has reached the landing state.
 */
.landing--revealed .landing__gif {
  opacity: 0;
  visibility: hidden;
}

/* Narrow screens skip the intro (js/homepage.js); hide it before JS runs. */
@media (max-width: 63.99rem) {
  .landing__gif {
    display: none;
  }
}

/* ==========================================================================
   LANDING VHS VIDEO
   ========================================================================== */

.landing__video {
  position: absolute;

  left: 50%;
  top: 50%;

  transform: translate(-50%, -50%);

  /* Matches the video file (490×360). A 16:9 box left empty transparent
     strips either side of the picture, outlined by the glow below. */
  width: min(490px, 74vw);
  height: auto;

  aspect-ratio: 490 / 360;

  z-index: 1;

  display: block;

  opacity: 0;

  box-shadow: 0 0 9rem 1rem rgba(227, 80, 57, 0.22);

  transition: opacity 1400ms var(--ease-editorial);
}

/*
 * The landing video appears when the opening animation finishes.
 */
.landing--revealed .landing__video {
  opacity: 1;
}

/*
 * Opening the navigation removes the landing video.
 */
body.nav-open .landing__video {
  opacity: 0;
}

/* The strip shares the first screen, so keep it out of the intro:
   it fades in with the landing video. Without JS it shows at once. */
@media (scripting: enabled) {
  .landing:not(.landing--revealed) + .next-event {
    opacity: 0;
  }
}

/* ==========================================================================
   NEXT EVENT — variant: Line
   ==========================================================================

   A ruled caption band sitting directly on the atmosphere — no background
   fill of its own, just the top/bottom rule and ink text. js/next-event.js
   fills .next-event__row from data/events.json and reveals it, hiding
   .next-event__fallback; see docs/HOMEPAGE-SPEC.md §3/§7.

   Text is --color-ink throughout (not white — white-on-coral fails
   contrast at these sizes per spec §8). min-height on the inner wrapper
   reserves space for the row before JS fills it, so there's no layout
   shift either way the fetch resolves.
   ========================================================================== */

.next-event {
  position: relative;
  z-index: 1;

  transition: opacity 1400ms var(--ease-editorial);

  border-top: var(--rule-width) solid var(--color-ink-30);
  border-bottom: var(--rule-width) solid var(--color-ink-30);

  color: var(--color-ink);
}

.next-event__inner {
  max-width: var(--content-max-width);
  margin-inline: auto;

  min-height: var(--space-xl);

  padding-block: var(--space-m);
}

.next-event__label {
  margin: 0 0 var(--space-xs);

  font-family: var(--font-micro);
  font-size: var(--text-small);

  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.next-event__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;

  gap: var(--space-xs) var(--space-l);

  margin-top: var(--space-xs);
}

.next-event__row[hidden] {
  display: none;
}

.next-event__info {
  flex: 999 1 260px;
}

.next-event__action {
  flex: 1 1 160px;
}

.next-event__date {
  margin: 0;

  font-family: var(--font-text);
  font-size: var(--text-small);

  font-variant-numeric: tabular-nums;
}

.next-event__title-venue {
  margin: var(--space-3xs) 0 0;
}

.next-event__title {
  font-family: var(--font-display);
  font-weight: 700;

  font-size: 1.875rem;
  line-height: 1.1;
}

.next-event__venue {
  font-family: var(--font-text);
  font-size: var(--text-small);
}

.next-event__venue::before {
  content: " — ";
}

/*
 * Rendered by js/next-event.js — .next-event__ticket-link for the
 * upcoming-event action, .stamp.next-event__stamp +
 * .next-event__waitlist-link for the sold-out state.
 */

.next-event__ticket-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);

  min-height: var(--tap-target-min);
  padding-inline: var(--space-m);

  background: var(--color-ink);
  color: var(--color-pale-warm);

  border-radius: 0;

  font-family: var(--font-text);
  font-weight: 700;

  text-decoration: none;
}

.next-event__title a {
  color: inherit;
}

.next-event__title a:focus-visible,
.next-event__ticket-link:focus-visible,
.next-event__waitlist-link:focus-visible,
.next-event__fallback a:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
}

.next-event__waitlist-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;

  min-height: var(--tap-target-min);
  padding-inline: var(--space-m);

  border: var(--rule-width-strong) solid var(--color-ink);

  color: var(--color-ink);

  font-family: var(--font-text);
  font-weight: 700;

  text-decoration: none;
}

.next-event__stamp {
  margin-right: var(--space-s);
}

.next-event__fallback {
  margin: var(--space-xs) 0 0;

  font-family: var(--font-text);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  max-width: var(--measure);
}

.next-event__fallback a {
  color: var(--color-ink);
}

/* ==========================================================================
   01 — THE IDEA (#idea, .homepage-hero)
   ==========================================================================

   No background: the persistent atmosphere shows through.
   Copy left, one 4:5 image right (≥64rem); stacked below, text first.
   Spec: docs/HOMEPAGE-SPEC.md §3 section 1.
   ========================================================================== */

.homepage-hero {
  position: relative;
  z-index: 1;

  min-height: 100svh;

  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xl);

  padding-block: var(--space-2xl);
  padding-inline: max(var(--page-margin), (100% - var(--section-max-width)) / 2);
}

.homepage-hero__copy {
  flex: 1 1 26rem;

  max-width: 40rem;
}

.homepage-hero__copy .eyebrow {
  margin: 0 0 var(--space-s);
}

.homepage-hero__phonetic {
  margin: 0 0 var(--space-s);

  font-family: var(--font-serif);
  font-style: italic;

  font-size: var(--step-2);
}

.homepage-hero__copy h2 {
  margin: 0 0 var(--space-m);

  max-width: 13ch;

  font-family: var(--font-banner);
  font-weight: 400;

  font-size: var(--step-4);

  line-height: 0.96;

  letter-spacing: -0.035em;

  text-transform: uppercase;

  overflow-wrap: break-word;
}

.homepage-hero__body {
  opacity: 0.85;
}

.homepage-hero__figure {
  flex: 0 1 25rem;

  margin: 0;

  aspect-ratio: 4 / 5;

  overflow: hidden;
}

.homepage-hero__figure img {
  display: block;

  width: 100%;
  height: 100%;

  object-fit: cover;
}

/* ==========================================================================
   EDITORIAL SECTIONS
   ========================================================================== */

.editorial {
  position: relative;
}

.editorial__text {
  gap: var(--space-l);
}

.editorial__image img {
  object-position: center 30%;
}

.editorial__caption {
  position: absolute;

  bottom: var(--space-m);
  left: var(--space-m);

  z-index: 1;

  color: var(--color-white);

  font-family: var(--font-serif);
  font-style: italic;

  font-size: var(--text-small);

  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
}

/* ==========================================================================
   SECOND EDITORIAL SECTION — PAIRED IMAGE
   ========================================================================== */

.editorial__image--pair {
  display: flex;

  flex-direction: column;
}

.editorial__image--pair picture {
  display: block;

  width: 100%;
}

.editorial__image--pair .editorial__image-primary,
.editorial__image--pair .editorial__image-secondary {
  width: 100%;
  height: 100%;

  object-fit: cover;

  min-height: 0;
}

.editorial__picture--primary {
  flex: 1 1 63%;

  min-height: 0;
}

.editorial__picture--secondary {
  flex: 1 1 37%;

  min-height: 0;

  border-top: var(--rule-width) solid var(--color-pale);
}

.editorial__image-primary {
  object-position: center 45%;
}

.editorial__image-secondary {
  object-position: center 30%;
}

/* ==========================================================================
   02 — THE ARTIST / 03 — THE PEOPLE (#artist, #people)
   ==========================================================================

   Mobile: stacked, text first (source order). ≥64rem: two columns.
   02 = text left, image right, inset from the right edge.
   03 = image left (order: -1), text right.
   Photos are portrait 4:5 (real photography is portrait); no rotation —
   rotation is reserved for the 04 collage (spec §1).
   Spec: docs/HOMEPAGE-SPEC.md §3 sections 2–3.
   ========================================================================== */

.homepage-artist,
.homepage-people {
  position: relative;
  z-index: 1;

  display: flex;
  flex-direction: column;
  gap: var(--space-l);

  padding-block: var(--space-2xl);
  padding-inline: max(var(--page-margin), (100% - var(--section-max-width)) / 2);
}

.homepage-artist .eyebrow,
.homepage-people .eyebrow {
  margin: 0 0 var(--space-s);
}

.homepage-artist h2,
.homepage-people h2,
.homepage-practice h2 {
  font-family: var(--font-display);
  font-weight: 700;

  font-size: var(--step-3);

  line-height: 1.05;

  letter-spacing: -0.01em;

  margin: 0 0 var(--space-m);
}

.homepage-artist .body-copy,
.homepage-people .body-copy,
.homepage-practice .body-copy {
  opacity: 0.9;

  max-width: 46ch;
}

/* --------------------------------------------------------------------------
   PHOTOGRAPHS
   -------------------------------------------------------------------------- */

.encounter__photo {
  margin: 0;

  width: 100%;
  max-width: 27.5rem;

  aspect-ratio: 4 / 5;

  overflow: hidden;
}

.encounter__photo--participant {
  max-width: 30rem;
}

.encounter__photo img {
  display: block;

  width: 100%;
  height: 100%;

  object-fit: cover;
}

@media (min-width: 64rem) {
  .homepage-artist,
  .homepage-people {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    column-gap: var(--space-xl);

    min-height: 100svh;
  }

  .encounter__photo--artist {
    justify-self: end;

    margin-right: var(--space-xl);
  }

  .encounter__photo--participant {
    order: -1;

    justify-self: start;
  }
}

/* ==========================================================================
   04 — THE PRACTICE (#practice)
   ==========================================================================

   Copy + "Get in touch" link, and a static 4-image collage with fixed
   rotations. The collage reveal interaction comes later (spec §7) and
   will reuse .homepage-practice__link as its revealed button.
   Spec: docs/HOMEPAGE-SPEC.md §3 section 4.
   ========================================================================== */

.homepage-practice {
  position: relative;
  z-index: 1;

  display: flex;
  flex-direction: column;
  gap: var(--space-xl);

  padding-block: var(--space-2xl);
  padding-inline: max(var(--page-margin), (100% - var(--section-max-width)) / 2);
}

.homepage-practice .eyebrow {
  margin: 0 0 var(--space-s);
}

.homepage-practice__link {
  display: inline-flex;
  align-items: center;

  min-height: 2.75rem;
  margin-top: var(--space-m);

  font-family: var(--font-text);
  font-weight: 700;

  color: var(--color-ink);
}

.homepage-practice__link:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
}

.practice-collage {
  position: relative;

  width: 100%;
  max-width: 33.75rem;

  aspect-ratio: 27 / 23;
}

.practice-collage__item {
  position: absolute;

  margin: 0;

  overflow: hidden;

  box-shadow: var(--shadow-soft);
}

.practice-collage__item img {
  display: block;

  width: 100%;
  height: 100%;

  object-fit: cover;
}

.practice-collage__item--1 {
  left: 0;
  top: 14%;

  width: 44%;
  aspect-ratio: 4 / 5;

  transform: rotate(-5deg);
}

.practice-collage__item--2 {
  left: 34%;
  top: 0;

  width: 40%;
  aspect-ratio: 3 / 4;

  transform: rotate(3deg);
}

.practice-collage__item--3 {
  right: 0;
  top: 46%;

  width: 50%;
  aspect-ratio: 4 / 3;

  transform: rotate(-2deg);
}

.practice-collage__item--4 {
  left: 22%;
  bottom: 0;

  width: 38%;
  aspect-ratio: 1 / 1;

  transform: rotate(6deg);
}

@media (min-width: 64rem) {
  .homepage-practice {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    column-gap: var(--space-xl);

    min-height: 100svh;
  }

  .homepage-practice__copy {
    padding-left: var(--space-xl);
  }

  .practice-collage {
    justify-self: end;
  }
}

/* ==========================================================================
   EVENTS (05 — join us)
   ==========================================================================

   Built per docs/HOMEPAGE-SPEC.md §3 section 5 / §5. The upcoming
   grid and past strip are both rendered by js/events.js from
   data/events.json — the markup in index.html only has the static
   header plus three empty containers
   ([data-events-grid]/[data-events-empty]/[data-events-past]).

   [data-events-empty] defaults to VISIBLE in the markup (not the
   grid's no-JS fallback exactly, but the same idea as next-event's
   static fallback link) — if JS never runs or the fetch fails, the
   visitor sees "New events soon" rather than a blank section. JS
   hides it the moment it appends real cards. .homepage-events__past
   defaults to [hidden] instead, since an empty "Past events" label
   over nothing looks broken in a way an empty-state message doesn't.
   ========================================================================== */

.homepage-events {
  position: relative;
  z-index: 1;

  padding-block: var(--space-2xl);
  padding-inline: var(--page-margin);
}

.homepage-events .eyebrow {
  margin: 0 0 var(--space-s);
}

.homepage-events__header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-s) var(--space-l);

  margin-bottom: var(--space-l);
}

.homepage-events__header h2 {
  font-family: var(--font-display);
  font-weight: 700;

  font-size: var(--step-3);

  line-height: 1.05;

  letter-spacing: -0.01em;

  margin: var(--space-3xs) 0 0;
}

.homepage-events__artist-link,
.homepage-events__archive-link {
  display: inline-flex;
  align-items: center;

  min-height: 2.75rem;

  font-family: var(--font-text);
  font-weight: 700;

  color: var(--color-ink);

  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   UPCOMING GRID
   -------------------------------------------------------------------------- */

.homepage-events__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-l);

  /*
   * Reserves roughly one card's height so there's no layout shift
   * while js/events.js's fetch is in flight — not a reusable token,
   * just this grid's own expected content height.
   */
  min-height: 34rem;
}

/* .event-card lives in public/css/event-card.css (shared with /events/). */

/* --------------------------------------------------------------------------
   NEXT DATES PANEL — shown after 1–2 upcoming cards (js/events.js).
   Same width as a card; transparent so it reads as an empty slot.
   -------------------------------------------------------------------------- */

.event-next-dates {
  flex: 0 1 22.5rem;

  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-s);

  padding: var(--space-m) var(--space-m) var(--space-m);

  border: 2px dashed var(--color-ink-45);
}

.event-next-dates__label {
  margin: 0;

  font-family: var(--font-micro);
  font-size: var(--text-small);

  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.event-next-dates__text {
  margin: 0;

  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.25;
}

.event-card__link:focus-visible,
.past-poster:focus-visible,
.event-card__ticket-link:focus-visible,
.event-card__waitlist-link:focus-visible,
.homepage-events__artist-link:focus-visible,
.homepage-events__archive-link:focus-visible,
.homepage-events__empty a:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   EMPTY STATE

   .homepage-events__empty also carries .body-copy in the markup —
   that already supplies font-family/size/line-height/max-width.
   -------------------------------------------------------------------------- */

.homepage-events__empty a {
  color: var(--color-ink);
}

/* --------------------------------------------------------------------------
   PAST STRIP
   -------------------------------------------------------------------------- */

.homepage-events__past {
  margin-top: var(--space-2xl);
}

.homepage-events__past-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);

  margin: 0 0 var(--space-s);
}

.homepage-events__past .eyebrow {
  margin: 0;
}

.homepage-events__past-strip {
  display: flex;
  gap: var(--space-m);

  overflow-x: auto;
  scroll-snap-type: x proximity;

  padding-bottom: var(--space-xs);
}

.past-poster {
  position: relative;

  display: block;

  flex: 0 0 150px;

  width: 150px;
  margin: 0;

  aspect-ratio: var(--poster-ratio);

  overflow: hidden;

  scroll-snap-align: start;
}

.past-poster img,
.past-poster__placeholder {
  display: block;

  width: 100%;
  height: 100%;

  object-fit: cover;
}

.past-poster__placeholder {
  background: var(--color-pale-warm);

  border: var(--rule-width) solid var(--color-ink-25);
}

.past-poster .stamp {
  position: absolute;
  top: var(--space-2xs);
  left: var(--space-2xs);
}

.past-poster__date {
  position: absolute;
  bottom: var(--space-2xs);
  left: var(--space-2xs);

  color: var(--color-white);

  font-family: var(--font-micro);
  font-size: var(--text-small);

  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* --------------------------------------------------------------------------
   MOBILE — upcoming grid becomes a horizontal scroll-snap row
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
  .homepage-events__grid {
    flex-wrap: nowrap;

    overflow-x: auto;
    scroll-snap-type: x mandatory;

    min-height: 0;
  }

  .event-card,
  .event-next-dates {
    flex: 0 0 78vw;

    scroll-snap-align: start;
  }
}

/* ==========================================================================
   THREAD — dashed line through 02–04 (≥64rem only)
   ==========================================================================

   SVG behind the section content: atmosphere < thread < images/text.
   .thread-wrap has no z-index, so the sections (z-index: 1) sit above
   the SVG (z-index: 0). Path and draw-on: js/homepage.js. Spec §6.
   ========================================================================== */

.thread-wrap {
  position: relative;
}

.thread {
  position: absolute;
  inset: 0;

  z-index: 0;

  display: none;

  width: 100%;
  height: 100%;

  overflow: visible;

  pointer-events: none;
}

@media (min-width: 64rem) {
  .thread {
    display: block;
  }
}

.thread__line {
  fill: none;

  stroke: var(--thread-color);
  stroke-width: var(--thread-width);
  stroke-dasharray: var(--thread-dash);
  stroke-linecap: round;
}

/* Solid copy inside the <mask>; its dash offset reveals the line. */
.thread__reveal {
  fill: none;

  stroke: var(--color-white);
  stroke-width: calc(var(--thread-width) * 4);
}

/* ==========================================================================
   REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .landing__gif,
  .landing__video {
    transition: none;
  }

  .next-event {
    transition: none;
  }
}
