/* ═══════════════════════════════════════════════════════════════════════
   RASTA Collective — hero banner

   Two children, one section:
     .hero__stage  the artwork, as a plate
     .hero__inner  the headline, the pull-quote, the buttons

   Below 1024 they are two rows — copy first, artwork under it, seated on
   the section's base line.

   At 1024 and up they occupy THE SAME grid cell. The artwork is not a
   column any more; it is the ground the section stands on, and the logo,
   the headline and both buttons float over it. Splitting the screen into
   picture-half and text-half meant the top band could only ever be a place
   to park the logo, and it read as dead space because it was.
   ═══════════════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;   /* iOS: 100vh is the LARGE viewport, so the CTAs would
                           sit under the URL bar on first paint. */
  display: grid;
  grid-template-columns: 100%;
  align-content: end;
  padding-block: clamp(78px, 11vh, 116px) 0;
  background: var(--ink);
  color: var(--text-on-dark);
  isolation: isolate;   /* keeps the hero's z-ladder local */
  overflow: clip;       /* not `hidden` — see body in base.css */
}

/* Explicit rows rather than source order: the stage comes FIRST in the
   markup so it paints under the copy without a z-index war, but it belongs
   BELOW the copy in the mobile reading order. */
.hero__inner { grid-row: 1; }
.hero__stage { grid-row: 2; }

.hero__inner {
  position: relative;
  z-index: var(--z-hero-copy);
  width: min(100% - var(--gutter) * 2, var(--container));
  margin-inline: auto;
  display: grid;
  align-items: end;
}

/* Faint film-grain so the flat near-black doesn't band on wide gradients.
   Pure CSS — no texture asset. */
.hero__grain {
  position: absolute;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: .035;
  background-image: repeating-conic-gradient(#fff 0% 25%, #000 0% 50%);
  background-size: 3px 3px;
}


/* ── The stage ──────────────────────────────────────────────────────────
   position: sticky, bottom-anchored. While the section is exactly one
   viewport tall this is indistinguishable from static — but the moment the
   copy makes it taller (a short window, a large text setting), the artwork
   stays sitting on the bottom of the SCREEN instead of scrolling up out of
   its own base line. Nothing above it may carry a transform, filter or
   contain:paint, or this silently degrades to static. */

.hero__stage {
  position: sticky;
  bottom: 0;
  /* align-self, NOT the default stretch. A stretched grid item fills its area
     exactly, so sticky has nowhere to travel and quietly behaves like static —
     it looks correct until the one case it exists for. Sized to the artwork,
     it can slide within the area. */
  align-self: end;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  min-width: 0;
  pointer-events: none;   /* the artwork is decoration; the copy is on top */
}

.hero__art {
  position: relative;
  width: 132%;
  /* Height cap in disguise: the copy above needs roughly 330px, so the
     artwork may only be as wide as the remaining fold can be tall. Without
     this a tablet in landscape pushes its own base line off the screen —
     and the whole point of seating it on the base line is that you see it. */
  max-width: calc((100svh - 330px) * 1.5488);
  margin-inline: -16%;
  /* The source PNG's transparent margins are cropped off in the pipeline, so
     this box IS the artwork — no dead pixels between the edge of the element
     and the edge of the collage. Locking the ratio keeps every percentage
     below stable across viewports and reserves the box before decode, so CLS
     is zero. */
  aspect-ratio: 1380 / 891;
}

/* pink_halo.png is 2.64 MB for a soft glow. This is the same read at zero
   bytes, resamples at any viewport, and can shift with scroll progress. */
.hero__halo {
  position: absolute;
  left: 50%;
  top: 54.1%;
  z-index: var(--z-halo);
  width: 121.7%;
  aspect-ratio: 1;
  transform: translate3d(-50%, -50%, 0);
  pointer-events: none;
  background: radial-gradient(closest-side,
              rgba(255, 146, 152, .34), rgba(219, 84, 106, .14) 52%, transparent 74%);
  filter: blur(56px);
  opacity: 0;                     /* revealed at ≥768 */
}

/* The paper sheet is a separate canvas from the figure, and the figure's
   canvas is now cropped to its alpha while the paper's is not. These insets
   re-create the original shared frame, so the sheet keeps exactly the
   registration behind the figure that it had before the crop. Derived from the
   banner's alpha bbox (12.22%/8.52% in, 87.84% out) — if that source artwork is
   ever re-exported, re-derive them; nothing here can detect the drift. */
.hero__paper {
  position: absolute;
  inset: -9.31% -16.08% 0 -16.16%;
  z-index: var(--z-paper);
  pointer-events: none;
}

/* All four frames occupy the identical box. The source sequence grows in
   place on a shared canvas, so stacking at inset:0 registers them exactly —
   the crossfade needs no positioning work at all. */
.hero__paper-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 1;
}

.hero__figure {
  position: relative;   /* sets the stacking order against the absolute layers */
  z-index: var(--z-figure);
  width: 100%;
  height: auto;
  filter: drop-shadow(0 24px 48px rgba(0, 0, 0, .5));
}

/* Below 1024 only the fully-unfolded frame 4 ships. Pulled back so it backs
   the figure rather than competing with it — but not so far that the pink
   greys out against the near-black and reads as a stain instead of paper. */
@media (max-width: 1023.98px) {
  .hero__paper { opacity: .72; }
}


/* ── Copy ───────────────────────────────────────────────────────────────── */

.hero__copy {
  position: relative;
  display: grid;
  gap: clamp(var(--s-4), 1.6vw, var(--s-5));
  justify-items: center;
  text-align: center;
  padding-bottom: var(--s-7);
}

/* Deliberately restrained: the long logo lockup already carries the programme
   name in display type, so a second shouting headline would just fight it.
   This line is the promise, not the title. */
.hero__title {
  font-size: var(--t-hero);
  color: var(--paper);
  max-width: 18ch;
}

.hero__cta {
  display: flex;
  gap: var(--s-3);
  justify-content: center;
  width: 100%;
  margin-top: var(--s-2);
}
/* 50/50 rather than stacked: both labels are short, and stacking costs a
   whole row of the first fold on the smallest screens. */
.hero__cta .btn { flex: 1 1 0; padding-inline: var(--s-3); }

/* Solid rather than translucent. These sit on top of a busy collage at
   ≥1024, and a see-through button over barbed wire is unreadable. */
.hero__cta .btn--ghost {
  background: rgba(11, 11, 11, .55);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}

@media (max-width: 767.98px) {
  .hero__copy { padding-bottom: 0; }
}

/* ── ≥380: the CTAs have room to breathe ────────────────────────────────── */
@media (min-width: 380px) {
  .hero__cta { gap: var(--s-4); }
  .hero__cta .btn { flex: 0 1 auto; padding-inline: clamp(20px, 2.4vw, 34px); }
}

/* ── ≥768: the artwork can carry the halo ───────────────────────────────── */
@media (min-width: 768px) {
  .hero__halo { opacity: 1; }
  .hero__copy { padding-bottom: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════
   ≥1024 — the two children collapse into one cell and start overlapping
   ═══════════════════════════════════════════════════════════════════════ */
@media (min-width: 1024px) {
  .hero {
    /* One row, one column: both children land in the same cell. */
    grid-template-rows: 1fr;
    /* Only as much top air as the logo needs. Every pixel spent here is a
       pixel the artwork cannot have, because the artwork is height-capped to
       what is left of the fold. */
    padding-block: clamp(56px, 6vh, 96px) 0;
  }
  .hero__inner,
  .hero__stage { grid-row: 1; grid-column: 1; }

  /* Anchored left, sized off the fold. The figure and its paper occupy the
     left two-thirds of the crop, so left-anchoring puts the collage where the
     eye starts and leaves its quieter right side under the copy. */
  .hero__stage { justify-content: flex-start; }

  .hero__art {
    /* Sized off what is LEFT of the fold once the top air is paid for. Take
       the padding out of this and the artwork's base line lands below the
       fold, which is the one thing this whole arrangement exists to prevent. */
    --art-h: min(calc(100svh - 100px), 1400px);
    width: calc(var(--art-h) * 1.5488);
    max-width: none;
    /* A little off the left edge so the composition reads as bigger than the
       window rather than as a picture placed inside it. */
    margin-inline: clamp(-120px, -4vw, -30px) 0;
  }

  /* A right-hand column of copy floating on the plate. Sized as a FRACTION of
     the container rather than in ch: that is what guarantees its left edge
     lands inside the artwork at every width, so the headline is on the collage
     and not merely beside it. The buttons sit directly under the text they
     belong to — pulled off into the picture, they read as part of the artwork
     rather than as the two things to do next. */
  .hero__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--copy-col, 42%));
    /* Centred, not parked on the base line. Bottom-aligned, a six-word
       headline left the whole upper half of the right side empty and the
       block itself crowded into the last third — which is what made the top
       of the section read as wasted rather than as air. */
    align-items: center;
  }
  .hero__copy {
    grid-column: 2;
    justify-items: start;
    text-align: left;
  }

  /* The headline sits on the collage now, and where it crosses the torn pink
     edge cream is only ~2.6:1. Three stacked shadows rather than one: a tight
     one to separate the letterforms from whatever is immediately behind them,
     a mid one for the pink, and a wide low-opacity one that pools the whole
     block out of the busier parts of the artwork. All of it is invisible
     against the flat black the rest of the line sits on. */
  .hero__title {
    text-shadow: 0 1px 3px rgba(11, 11, 11, .7),
                 0 4px 18px rgba(11, 11, 11, .9),
                 0 10px 54px rgba(11, 11, 11, .95);
  }

  .hero__cta {
    justify-content: flex-start;
    width: auto;
  }
  /* Scaled up here and nowhere else. The shared .btn size is right in the form
     and at the foot of the About section; sitting directly under a headline
     that reaches 120px on a wide display, the same button reads as a caption
     someone left under the artwork. */
  .hero__cta .btn {
    min-height: clamp(52px, 4.6vh, 68px);
    font-size: clamp(1.05rem, .85rem + .5vw, 1.45rem);
    padding-inline: clamp(26px, 2.6vw, 46px);
  }
}

/* On a wide display the 1320px container squeezed the whole composition into
   the middle half of the screen and left the rest black. The hero — and only
   the hero, which is one image and six words — takes as much width as it is
   given. The reading sections stay at their measure. */
@media (min-width: 1440px) {
  .hero__inner { --container: min(2080px, 90vw); }
}

/* Past this width the artwork can fill the fold outright, and the copy column
   stops growing with the screen — a headline six words long does not want a
   third of a 2560px display. */
@media (min-width: 1900px) {
  .hero__art   { --art-h: min(calc(100svh - 100px), 1520px); }
  .hero__inner { --copy-col: 38%; }
}
