/* =========================================================================
   hero.css — Hero-Sektion: Video-Bühne, Overlay und schwebende Noten
   ========================================================================= */

.hero {
  padding-block: 0;
  /* Waagerecht muss geschnitten werden: die Bühne bricht mit 100vw aus dem
     Track aus und die Noten wippen über den Rand. Senkrecht darf nichts
     geschnitten werden — bei vergrößertem Textabstand (WCAG 1.4.12) wächst
     das Overlay über die Bühne hinaus und verlor mit `hidden` die Oberkante
     des Claims. `clip` statt `hidden`, weil hidden+visible auf auto
     zurückfiele und einen Scroll-Container aufmachte (dieselbe Paarung wie
     bei .clouds in characters.css). */
  overflow-x: clip;
  overflow-y: visible;
  text-align: center;
}

.hero__text { max-width: 46rem; }
.hero__text .eyebrow,
.hero__lead { margin-inline: auto; }

/* The bleed wrapper breaks out to the full viewport width via margins (not
   transform — a transform here would collide with the .reveal scroll-fade,
   which sets transform:none once an element becomes visible). The stage
   inside is capped and centered normally, independent of the 46rem text
   column it structurally sits in.                                        */
.hero__stage-bleed {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

.hero__stage {
  position: relative;
  max-width: 1400px;
  margin: 0 auto clamp(1rem, 3vw, 1.75rem);
  aspect-ratio: 16 / 9;
  /* .hero__text (.track) creates its own stacking context (position +
     z-index), which would otherwise trap mix-blend-mode so it can't reach
     the page's cream background. Painting that same color here gives the
     blend something correct to compute against regardless of nesting.    */
  background: var(--bg);
}

.hero__stage video,
.hero__stage img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  margin: 0;
}

/* The 3D render comes out of the renderer on a white background; multiply
   blends white away against the section's cream backdrop for free. Two
   masks (intersected) fade all four edges so the video doesn't end in a
   hard rectangle.                                                        */
.hero__video,
.hero__fallback {
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
    linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
    linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
          mask-composite: intersect;
}
.hero__video { mix-blend-mode: multiply; opacity: .9; filter: saturate(.8); }

/* Das Video ist aria-hidden — ohne Standbild bliebe die Maupe für
   Screenreader unbeschrieben. Deshalb nicht display:none, sondern nur
   visuell versteckt: der alt-Text bleibt so erreichbar. */
.hero__stage .hero__fallback {
  width: 1px; height: 1px;
  inset: auto auto 0 0;
  clip-path: inset(50%);
  overflow: hidden;
}

.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 5vw, 3.5rem);
  text-align: center;
}

.hero__overlay .hero__claim {
  margin: 0;
  font-size: clamp(3.25rem, 1.5rem + 9vw, 7.5rem);
  letter-spacing: -.02em;
  color: var(--ink);
  text-shadow: 0 0 .6em var(--bg), 0 0 1.2em var(--bg), 0 0 2.2em var(--bg);
}

/* Diese Zeile liegt als einziger Fließtext über dem Motiv. Gemessen gegen
   das Standbild lag der Grund dahinter im Median bei 3.81:1 — unter den
   4.5:1, die für normalen Text gelten, auf ganzer Fläche. Ab 18.66px in
   Fettschrift zählt Text als groß, dann sind es 3:1; zusammen mit dem
   cremefarbenen Textschatten hält auch die dunkelste Stelle das.
   Beides ist nötig: die Größe allein reichte erst ab 24px.
   Nur hier, nicht auf .eyebrow allgemein — auf accessibility.html
   steht dieselbe Klasse auf ruhigem Grund und soll zurückhaltend bleiben. */
.hero__overlay .eyebrow {
  margin: 0;
  font-size: clamp(1.2rem, 1.1rem + .3vw, 1.4rem);
  font-weight: 700;
  color: var(--ink);
  text-shadow: 0 0 .5em var(--bg), 0 0 1em var(--bg);
}

.hero__overlay .button { margin-top: 0; }

.hero__lead {
  font-size: clamp(1.1rem, 1rem + .5vw, 1.4rem);
  line-height: 1.55;
  max-width: 42ch;
  margin-top: clamp(4rem, 10vw, 7rem);
}

@media (prefers-reduced-motion: reduce) {
  .hero__video { display: none; }
  .hero__stage .hero__fallback {
    width: 100%; height: 100%;
    inset: 0;
    clip-path: none;
  }
}

/* ---------- Floating notes ------------------------------------------------- */
/* Above .hero__text (.track, z-index:2) so the notes clear the video
   stage's opaque backdrop instead of being painted over by it.           */
.notes { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.note  {
  position: absolute;
  width: clamp(20px, 2.6vw, 36px);
  opacity: .95;
  animation: note-float 5s ease-in-out infinite;
  transition: opacity .35s ease;
}

/* Gesetzt von note-fade.js, sobald eine Note unter die Header-Leiste
   gerät — sonst schiene sie durch deren transluzenten Hintergrund. */
.note--muted { opacity: 0; }

@keyframes note-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-16px) rotate(4deg); }
}

.note--1 { top: 11%;  left: 18%; width: clamp(24px, 3.2vw, 44px); animation-duration: 4.6s; animation-delay: 0s; }
.note--2 { top: 23%;  left: 26%; animation-duration: 5.3s; animation-delay: .6s; }
.note--3 { top: 51%;  left: 20%; width: clamp(26px, 3.4vw, 46px); animation-duration: 4.9s; animation-delay: 1.1s; }
.note--4 { top: 8%;   right: 20%; width: clamp(30px, 3.8vw, 52px); animation-duration: 5.6s; animation-delay: .3s; }
.note--5 { top: 29%;  right: 17%; width: clamp(26px, 3.4vw, 46px); animation-duration: 4.3s; animation-delay: .9s; }
.note--6 { top: 53%;  right: 25%; animation-duration: 5s; animation-delay: 1.4s; }

@media (max-width: 48rem) {
  .note--2, .note--3, .note--6 { display: none; }
  .note--1 { left: 8%; }
  .note--4, .note--5 { right: 8%; }
}

@media (prefers-reduced-motion: reduce) {
  .note { animation: none; }
}

/* WCAG 2.2.2 verlangt für Bewegung, die von selbst startet und länger als
   fünf Sekunden läuft, eine Möglichkeit zum Anhalten — die Systemeinstellung
   allein zählt nicht als Bedienelement. Der Pausier-Schalter der Bühne hält
   deshalb beides an: hero-video.js setzt data-motion auf die Sektion. */
.hero[data-motion="paused"] .note { animation-play-state: paused; }

/* ---------- Schmale Fenster ------------------------------------------------ */

/* Die 16/9-Bühne ist bei 375px nur ~210px hoch. Claim, Zeile und Button
   brauchten dort zusammen ~240px — der Claim lief oben aus der Sektion
   heraus und wurde vom overflow:hidden abgeschnitten. Ohne den Button
   bleiben ~135px, das Overlay passt wieder über das Video.               */
@media (max-width: 48rem) {
  .hero__overlay .button { display: none; }

  /* Abstand und Claim sind hier enger als zuvor. Der Vorspann steht seit
     der Kontrastkorrektur in Großtext und braucht eine Zeile mehr Höhe;
     zusammen mit dem auf 1.5 erhöhten Zeilenabstand aus dem Textabstand-Test
     (WCAG 1.4.12) sprengte das Overlay bei 320px die Bühne, und der Claim
     verlor oben eine Kante. Die 16/9-Bühne misst dort nur 180px. */
  .hero__overlay { gap: clamp(.4rem, 2.5vw, 1rem); }

  /* Der Claim darf hier nicht mehr ganz so weit aufdrehen — sonst frisst
     er die Zeile darunter wieder auf. */
  .hero__overlay .hero__claim { font-size: clamp(2.25rem, 1.2rem + 6.5vw, 4.25rem); }

  /* Unten rechts in der Ecke der Animation. */
  .hero__stage .media-toggle { top: auto; bottom: .6rem; right: .6rem; }
}
