/* =========================================================================
   Bühnenlayout — Übersetzung der Produktseiten-Architektur (Vorbild: ARRI
   ALEXA Mini LF) auf einen Kameramann.

   Der Unterschied zur Dokumentfassung: dort lief alles in einer Spalte mit
   Labelrand, wie ein Lebenslauf. Hier ist jede Sektion eine eigene Bühne über
   die volle Breite, mit eigenem Rhythmus. Text und Bild wechseln die Seite,
   Bewegtbild sitzt an den Bruchstellen zwischen den Kapiteln.

   Baut auf stil.css (Farben, Typografie, Schriften) und raum.css (Farbebenen,
   Aufbau aus Nebel, Poster-Laufband) auf und ersetzt nur die Geometrie.
   ========================================================================= */

/* ------------------------------------------------------------- Grundmaße */

body.buehnen {
  --rand:   clamp(20px, 5vw, 88px);   /* Seitenrand der Bühnen */
  --bahn:   1320px;                   /* maximale Satzbreite */
  --hoehe:  clamp(52px, 9vh, 88px);   /* Höhe der klebenden Leiste */
}

/* Die feste Akzentfläche und der Ebenenraum aus der Dokumentfassung stören
   hier: Bühnen laufen randlos, ein seitlicher Streifen schnitte sie an. */
body.buehnen .kante { display: none; }
body.buehnen .huelle { padding: 0; }
body.buehnen .satz { max-width: none; margin: 0; }

.bahn {
  max-width: var(--bahn);
  margin: 0 auto;
  padding-inline: var(--rand);
}

/* --------------------------------------------------- Klebende Navigation */

/* Wie bei ARRI: die Sprungmarken bleiben oben stehen, damit jemand, der nur
   die Filmografie sehen will, nicht durch die Inszenierung muss. */
/* Fest statt klebend. Sie steht im Quelltext vor der Kopfbuehne, weil die
   Ausgsting-Seite die Schlussphase dieser Buehne ist und die Leiste dort schon
   oben stehen soll. Fest, nicht klebend: als klebendes Element ganz oben im
   Fluss naehme sie eine Zeile Platz weg und schoebe die Kopfbuehne nach unten.
   Dafuer tragen die Sektionen scroll-margin-top, sonst landeten Sprungmarken
   unter ihr. */
.leiste {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  height: var(--hoehe);
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 30px);
  padding-inline: var(--rand);
  background: color-mix(in srgb, var(--papier) 86%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(16px);
          backdrop-filter: saturate(1.4) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color .3s ease, background-color .3s ease;
  /* Rechts bleibt Platz für den Tonwert-Umschalter, der als fest stehendes
     Element darüber liegt. Ohne diese Reserve läuft die letzte Sprungmarke
     unter ihn. */
  padding-right: calc(var(--rand) + clamp(94px, 8vw, 120px));
  /* Blendet zusammen mit der Ausgsting-Karte ein: 0 bis --kopf .62, voll ab
     .78. Vorher ist die Landing Page frei von Navigation, wie bisher. */
  opacity: calc(var(--kopf, 0) * 6.25 - 3.88);
}
/* Unsichtbar heisst auch unbedienbar; erst mit der Karte wird sie scharf.
   Die Phase steht am <html>, nicht an der Buehne: die Leiste liegt ausserhalb
   von ihr, ueber :has() ginge es auch, aber ein Attribut an der Wurzel ist
   billiger und aelter unterstuetzt. */
.leiste { pointer-events: none; }
html[data-kopfphase="probe"] .leiste { pointer-events: auto; }

/* Sprungmarken duerfen nicht unter der festen Leiste landen. */
[id^="s-"], #oben, #inhalt { scroll-margin-top: var(--hoehe); }

/* Die Schalterzeile sitzt in der Leistenzeile, auf dem Kopfbild schwebt sie
   frei an derselben Stelle. Die Regel aus stil.css, die sie auf schmalen
   Geräten nach unten schickt, gilt hier nicht: unten liegt keine
   Markenleiste mehr. */
body.buehnen .schalterzeile {
  top: calc((var(--hoehe) - 2.1rem) / 2);
  bottom: auto;
  right: clamp(14px, 3vw, 30px);
  z-index: 41;
}
.leiste[data-haftet="true"] { border-bottom-color: var(--linie); }

.leiste__name {
  font-size: var(--schrift-label);
  font-weight: 700;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  white-space: nowrap;
  margin-right: auto;
}
.leiste__name a { text-decoration: none; }

.leiste__marken {
  display: flex;
  gap: clamp(10px, 1.6vw, 26px);
  overflow-x: auto;
  scrollbar-width: none;
  margin-right: clamp(8px, 1.4vw, 20px);
}
.leiste__marken::-webkit-scrollbar { display: none; }

.leiste__marken a {
  flex: 0 0 auto;
  color: var(--text-3);
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  text-decoration: none;
  padding: .4em 0;
  border-bottom: 2px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.leiste__marken a:hover { color: var(--text-1); }
.leiste__marken a[aria-current="true"] {
  color: var(--akzent-1);
  border-bottom-color: var(--akzent-1);
}

/* ----------------------------------------------------------------- Knopf */

/* Orange ist die einzige Handlungsfarbe der Seite. Sonst nichts in Orange,
   sonst verliert der Knopf seine Bedeutung. Die Vorlagen bestaetigen das
   dreifach: ORYZO nennt die einzige gefuellte Flaeche "rarity is the signal",
   Dala reserviert Iris ausschliesslich fuer den gefuellten Knopf, Creative
   Giants verbietet farbige CTA-Fuellungen ganz.

   Rundung vollrund statt 2px: ORYZO 36px, Creative Giants 1440px, Dala Pille.
   Die Schriftfarbe kommt aus --knopf-schrift, nicht fest aus #fff — auf dem
   helleren Ember der dunklen Lage haette Weiss nur 2,9:1. */
.knopf {
  display: inline-flex;
  align-items: center;
  gap: .7em;
  padding: .95em 1.7em;
  background: var(--akzent-1);
  color: var(--knopf-schrift);
  border: 0;
  border-radius: var(--rund-knopf);
  font: inherit;
  font-size: var(--schrift-label);
  font-weight: 700;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: filter .2s ease, transform .2s ease;
}
.knopf:hover { filter: brightness(1.12); transform: translateY(-1px); color: var(--knopf-schrift); }
.knopf--leise {
  background: none;
  color: var(--akzent-1);
  padding-inline: 0;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
}
.knopf--leise:hover { color: var(--akzent-1); transform: none; }
.knopf__pfeil { font-size: 1.1em; line-height: 1; transform: translateY(-.04em); }

/* ------------------------------------------------------------------ Kopf */

/* Die Bühne ist höher als das Fenster, ihr Inhalt klebt darin oben. Der
   Überstand ist der Scrollweg des Effekts — dieselbe Bauart wie bei den
   Reel-Bühnen. Über diesen Weg läuft --kopf von 0 auf 1. */
.kopfbuehne {
  position: relative;
  height: var(--kopfweg, 260vh);
}

/* Wo der Satz steht, entscheidet EINE Angabe — und zwar hier, an der Buehne.
   Halt und Blendblatt tragen denselben Rasterbau; laufen sie auseinander,
   sieht man beim Scrollen die Uebergabe zwischen Blatt und Satz. Deshalb
   teilen sie sich diese beiden Werte, statt sie zweimal zu fuehren. */
.kopfbuehne {
  --satz-lage: center;                        /* seit 30.08.2026 mittig */
  --satz-fuss: clamp(38px, 7vh, 76px);
}

.kopfbuehne__halt {
  position: sticky;
  top: 0;
  height: 100svh;
  display: grid;
  align-content: var(--satz-lage);
  padding: var(--hoehe) 0 var(--satz-fuss);
  overflow: hidden;
  /* Pflicht: mix-blend-mode am Blendblatt darf nur mit den Lagen dieser Bühne
     rechnen, nicht mit der Seite dahinter. */
  isolation: isolate;
}

/* Die Lagen liegen alle randlos übereinander. Reihenfolge von unten:
   Arbeitsprobe (1) · Fluid-Loop (2) · Verlauf (3) · Blendblatt (4) · Satz (5) */
.kopfbuehne__probe,
.kopfbuehne__probe-standbild,
.kopfbuehne__film,
.kopfbuehne__standbild {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* kein filter: der Verlauf darunter erledigt die Lesbarkeit ohne Rechenlast */
}
.kopfbuehne__probe,
.kopfbuehne__probe-standbild { z-index: 1; }
.kopfbuehne__film,
.kopfbuehne__standbild { z-index: 2; }

/* Das Standbild liegt IMMER unter seinem Film, nicht nur in `ohne-film`.

   Der Grund ist Safari: es wendet `object-fit` nicht auf das `poster` eines
   <video> an, sondern passt das Bild seitenverhaeltnistreu ein. Beim
   Tonwertwechsel setzt buehne.js eine neue Quelle, `load()` stellt den Film
   auf readyState 0 — und in dieser Luecke stand das Poster als schmales Band
   mitten auf der Buehne, links und rechts davon die Lage darunter. Am
   deutlichsten in der hellen Fassung: die ist hochkant (1080x1620).

   Deshalb tragen die Filme gar kein `poster` mehr. Ein <video> ohne Poster
   und ohne Bilddaten ist durchsichtig; sichtbar ist dann das Standbild
   darunter, und ein <img> haelt sich ueberall an `object-fit: cover`.

   Das Standbild steht im Markup VOR seinem Film. Bei gleichem z-index
   entscheidet die Reihenfolge im Quelltext — stuende es dahinter, deckte es
   den Film zu. Wer die Paare umsortiert, dreht das um. */


/* Der Fluid-Loop blendet früh weg und gibt die Arbeitsprobe darunter frei.
   Bei --kopf = .15 steht er noch voll, bei .40 ist er fort. */
.kopfbuehne__film,
.kopfbuehne__standbild { opacity: calc(1.63 - var(--kopf, 0) * 6.25);   /* voll bis .10, weg ab .26 */ }

/* Wie auf den Reel- und Filmbühnen gilt hier immer helle Schrift auf dunklem
   Grund, unabhängig von der Tonwertlage. Zwei Gründe:

   1. Der Verlauf lief früher nach --papier. In der hellen Fassung wusch er das
      Bild also nach Weiß aus, statt es abzudunkeln — und weiße Schrift wäre
      dort verschwunden.
   2. Seit der Verlauf beim Scrollen wegblendet, steht der Satz am Ende auf
      rohem Bild. Dunkle Schrift auf dem Fluid-Loop ist dann unlesbar, egal
      welche Lage gewählt ist.

   Der Kopf übergibt außerdem nicht mehr an Papier, sondern an die Reel-Bühne
   darunter. Eine dunkle Unterkante ist dafür die bessere Naht. */
.kopfbuehne {
  --text-1: #F6F5F2;
  --text-2: #CBD2D8;
  --text-3: #A7AFB6;
  --akzent-1: #FF6A34;
  --knopf-schrift: #12100A;
  color: var(--text-1);
}

/* Verlauf von unten, damit die Schrift auf ruhigem Grund sitzt. Läuft nach
   oben vollständig auf null, es entsteht keine sichtbare Kante. Er reicht
   höher als der auf den Reel-Bühnen: dort trägt er eine Karte von zwei
   Zeilen, hier einen Satz, der bis zur halben Bühnenhöhe hinaufreicht.

   Er blendet mit dem Loop weg: sobald das Blendblatt übernimmt, gibt es
   nichts mehr abzudunkeln — dann trägt die Grundfarbe des Blattes. */
.kopfbuehne__halt::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  /* Der Verlauf gehoert zur Lage des Satzes und ist mit ihr umgebaut worden.

     Solange der Satz am Fuss stand, genuegte ein Verlauf, der unten kraeftig
     ist und nach oben ganz verschwindet. Seit der Satz mittig steht
     (--satz-lage), traegt genau die Mitte die Schrift — und dort dunkelte der
     alte Verlauf kaum ab. Nachgemessen mit build/kontrast.swift war der Titel
     bei 2,1:1 statt 12,6:1, die Rollenzeile bei 2,4:1. Unlesbar, ohne dass
     irgendwo etwas kaputt gewesen waere.

     Die Stuetzstellen unten halten von 35 % bis 68 % Hoehe rund 0,85 Deckung,
     genau so viel wie frueher am Fuss. Gemessen ergibt das Titel 12,4:1,
     Rollenzeile 5,1:1, Scroll 6,6:1 — auf breitem wie auf schmalem Fenster.
     Der Preis steht oben: das Bild traegt jetzt auch am oberen Rand 16 %
     Schleier statt gar keinen. **Wer den Satz wieder verschiebt, rechnet das
     hier neu nach** — die Baender in build/kontrast.swift mitziehen. */
  background: linear-gradient(
    to top,
    rgba(6,8,10,.91) 0%,
    rgba(6,8,10,.88) 20%,
    rgba(6,8,10,.87) 35%,
    rgba(6,8,10,.84) 68%,
    rgba(6,8,10,.48) 85%,
    rgba(6,8,10,.16) 100%);
  opacity: calc(1.63 - var(--kopf, 0) * 6.25);   /* voll bis .10, weg ab .26 */
  pointer-events: none;
}

/* --kopf ausdruecklich als Zahl anmelden. Ohne @property ist eine eigene
   Eigenschaft eine blosse Zeichenkette, die erst beim Einsetzen in calc()
   geprueft wird — WebKit hat damit in transform-Funktionen bekannte
   Schwaechen. Angemeldet ist der Wert getypt, der Startwert steht fest, und
   var(--kopf, 0) braucht gar nicht mehr zu greifen. Aeltere Browser
   ueberlesen die Regel; der Ruecksetzwert traegt sie dann weiter. */
@property --kopf {
  syntax: "<number>";
  /* Muss erben. Geschrieben wird der Wert an .kopfbuehne, gelesen an
     .kopfbuehne__satz — also am Kind. Nicht angemeldete eigene Eigenschaften
     erben immer; bei inherits: false saehe das Kind nur den Startwert 0 und
     der ganze Effekt stuende still. */
  inherits: true;
  initial-value: 0;
}

/* ------------------------------------------------------ Satz der Kopfbuehne

   Der Titel laeuft ueber die volle Bildbreite, deshalb sitzt der Satz nicht
   in .bahn. Beim Scrollen waechst er und verschwindet dabei; die Abdunklung
   darunter geht mit, sodass am Ende das reine Bild steht und an die
   Reel-Buehne uebergibt.

   --kopf laeuft von 0 (Seitenanfang) bis 1 (eine Fensterhoehe weiter) und
   kommt aus buehne.js. Steht das Skript nicht, greift der Ruecksetzwert 0 —
   der Kopf steht dann still und ist vollstaendig lesbar. Das ist die Regel
   aus dem README: ohne JavaScript bleibt die Seite ganz da. */
/* Ein Maßstab für beide Lagen. Satz und Blendblatt müssen währenddessen
   deckungsgleich wachsen, sonst sieht man die Übergabe.

   Quadratisch, nicht linear: die Bewegung soll anziehen, nicht gleichförmig
   laufen. Am Ende steht der Achtfache — bei 17,8vw Grundgröße füllen dann
   zwei Buchstaben das Fenster. */
/* Der Massstab reicht bis zum Achtfachen, erreicht ihn aber frueher als zuvor:
   ab --kopf .72 ist das Blendblatt weg und die Ausgsting-Seite uebernimmt. */
.kopfbuehne { --kopf-skala: calc(1 + var(--kopf, 0) * var(--kopf, 0) * 14); }

.kopfbuehne__satz {
  padding-inline: var(--rand);
  /* Waechst aus seiner Mitte. Solange der Satz am Fuss der Buehne stand, war
     die Unterkante richtig — aus der Mitte gewachsen waere er nach unten aus
     dem Bild gelaufen. Seit er mittig steht, gilt das Umgekehrte: aus der
     Unterkante gewachsen risse es ihn nach oben aus dem Bild, und die
     Buchstaben gaeben den Blick auf die Arbeitsprobe an der falschen Stelle
     frei. Der Wert gehoert zu --satz-lage; wer das eine aendert, prueft das
     andere. */
  transform-origin: 50% 50%;
  transform: scale(var(--kopf-skala));
  will-change: transform, opacity;
  z-index: 5;
  /* Haelt das erste Zehntel voll und ist bei --kopf = .30 weg — dann hat das
     Blendblatt uebernommen. Werte ueber 1 begrenzt der Browser selbst,
     deshalb braucht es hier kein clamp(). Ohne das Halten begaenne der Titel
     schon beim ersten Mausrad-Klick zu verblassen, und das liest sich wie ein
     Fehler, nicht wie eine Geste. */
  opacity: calc(1.43 - var(--kopf, 0) * 7.14);   /* voll bis .06, weg ab .20 */
}

/* --------------------------------------------------------- Das Blendblatt

   Der Kern des Effekts. Das Blatt ist flächig in der Grundfarbe und trägt die
   Schrift im Gegenextrem. Über mix-blend-mode heisst das:

     dunkle Lage   Grund fast schwarz, Schrift weiss, `multiply`
                   → schwarz × Bild = schwarz, weiss × Bild = Bild
     helle Lage    Grund fast weiss, Schrift schwarz, `screen`
                   → weiss + Bild = weiss, schwarz + Bild = Bild

   In beiden Fällen also: **die Buchstaben sind Fenster auf die Arbeitsprobe,
   alles andere bleibt Grund.** Kein Masken-Bild, kein SVG, kein Canvas — und
   deshalb funktioniert es mit laufendem Film und in beiden Tonwertlagen.

   Es liegt auf z 4, also über Loop und Verlauf und unter dem lesbaren Satz.
   Der Satz darf nicht mitblenden, sonst verschwände er im Grund. */
/* Das Blatt selbst waechst NICHT — es ist die flaechige Grundlage und muss
   randlos bleiben. Gewachsen wird darin, im Satz. Deshalb traegt es exakt die
   Polsterung der Buehne: dann deckt sich sein Inhaltskasten mit dem der
   Buehne, und der Satz darin steht wie der lesbare Satz daneben. */
.kopfbuehne__blatt {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: grid;
  align-content: var(--satz-lage);
  padding: var(--hoehe) 0 var(--satz-fuss);
  background: var(--papier);
  color: #FFFFFF;
  mix-blend-mode: multiply;
  pointer-events: none;
  /* Blendet ein, waehrend der Satz geht (.10 bis .30), steht dann, und geht
     zum Schluss selbst (.83 bis 1) — dann steht die Arbeitsprobe frei und
     uebergibt an die Reel-Buehne darunter. */
  /* ein: .06 bis .20 · steht · aus: .58 bis .72 */
  opacity: min(calc(var(--kopf, 0) * 7.14 - .43), calc(5.14 - var(--kopf, 0) * 7.14));
}
/* Der Satz im Blatt traegt dieselbe Klasse und damit dieselbe Geometrie.
   Zurueckgenommen wird nur, was das Blatt schon erledigt: das Ein- und
   Ausblenden und die Lage im Stapel. */
.kopfbuehne__satz--maske {
  z-index: auto;
  opacity: 1;
  will-change: transform;
}
/* Blindsatz: haelt den Platz, bleibt unsichtbar und untastbar. */
.kopfbuehne__satz--maske .rolle,
.kopfbuehne__satz--maske .kopfbuehne__fuss { visibility: hidden; }
.kopfbuehne__satz--maske .wink::after { animation: none; }

/* In der hellen Lage dreht das Verfahren um: heller Grund, dunkle Schrift,
   `screen` statt `multiply`. Dasselbe Ergebnis, andere Richtung. */
html[data-theme="hell"] .kopfbuehne__blatt {
  color: #000000;
  mix-blend-mode: screen;
}

/* Die Abdunklung geht erst, wenn der Satz weg ist: bis --kopf = .5 rechnet
   der Ausdruck ueber 1 und wird begrenzt, danach faellt er bis .9 auf 0. So
   bleibt die Schrift lesbar, solange sie da ist, und die letzte Zehntel
   Fensterhoehe uebergibt auf reinem Bild an die Reel-Buehne. */
.kopfbuehne::after { opacity: calc(2.25 - var(--kopf, 0) * 2.5); }

/* ------------------------------------------------- Die Ausgsting-Seite

   Schlussphase derselben Buehne. Verlauf von unten wie auf den Reel-Buehnen,
   darauf die Karte und der Zaehler. Beides blendet ein, wenn das Blendblatt
   gegangen ist (.62 bis .78), und steht dann bis zum Ende der Buehne.

   Der Verlauf traegt dieselben Werte wie `.reelbuehne__halt::after` — die
   Karte steht auf demselben Material, also gilt dieselbe Messung. */
.kopfbuehne__halt::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  background: linear-gradient(
    to top,
    rgba(6,8,10,.86) 0%,
    rgba(6,8,10,.58) 20%,
    rgba(6,8,10,.14) 44%,
    transparent 62%);
  opacity: calc(var(--kopf, 0) * 6.25 - 3.88);
  pointer-events: none;
}

.kopfbuehne__probensatz {
  position: absolute;
  inset: 0;
  z-index: 6;
  opacity: calc(var(--kopf, 0) * 6.25 - 3.88);
  /* Unsichtbar heisst unbedienbar. Ohne das laege ein Klickbereich fuer den
     Trailer-Knopf ueber dem Kopf, lange bevor die Karte zu sehen ist. */
  visibility: hidden;
  pointer-events: none;
}
html[data-kopfphase="probe"] .kopfbuehne__probensatz {
  visibility: visible;
  pointer-events: auto;
}

/* Tanker, nur hier. Der Name ist bewusst `kopfbuehne__titel` und nicht
   `titel`: die Filmografie benutzt `.titel` schon fuer die Werktitel, und
   stil.css setzt darauf ein Gewicht.

   Die Schrift hat genau einen Schnitt und ist von Haus aus
   fett — `font-weight` bleibt deshalb 400. Eine hoehere Angabe liesse den
   Browser kuenstlich fetten, und die Konturen verschmierten.

   Die Groesse steht in vw, nicht in rem: der Titel soll die Bildbreite
   fuellen, und das ist ein Verhaeltnis zur Fensterbreite, kein fester Wert.
   Nachgemessen im Browser: bei 1400 px Fenster misst der Satz „STEADI MOTION"
   942 px bei 13,4vw, zur Verfuegung stehen 1260 px — daraus 17,9vw. Gesetzt
   sind 17,8vw, ein Prozent Sicherheit, weil .kopfbuehne overflow: hidden hat
   und der Titel sonst angeschnitten wuerde.

   Der Wert traegt ueber die ganze Breite, weil --rand zwischen 400 und
   1760 px genau 5vw ist: die Satzbreite bleibt dort konstant 90 Prozent des
   Fensters. Ausserhalb weicht sie um weniger als ein Prozent ab.

   Wer den Text aendert, muss den Wert neu messen — bei anderer Zeichenzahl
   passt er nicht mehr. */
.kopfbuehne__titel {
  margin: 0;
  font-family: Tanker, Excon, system-ui, sans-serif;
  font-weight: 400;
  font-size: 17.8vw;
  line-height: .82;
  letter-spacing: -.004em;
  text-transform: uppercase;
  white-space: nowrap;
}

.kopfbuehne .rolle { margin-top: 1.15rem; }

@media (prefers-reduced-motion: reduce) {
  /* Das Wachsen faellt weg — das ist die Bewegung, die jemand abbestellt hat.
     Das Auf- und Abblenden bleibt: es ist keine Bewegung im vestibulaeren
     Sinn, und ohne es bliebe der Titel stehen und ueberlagerte die Uebergabe
     an die Reel-Buehne. will-change nennt dann nur noch, was sich wirklich
     aendert, sonst bliebe eine Zeichenebene fuer nichts offen. */
  .kopfbuehne__satz { transform: none; will-change: opacity; }
  /* Ohne Wachsen braucht die Buehne keinen Scrollweg zum Durchlaufen. */
  .kopfbuehne { height: auto; }
  .kopfbuehne__halt { position: relative; }
}

.kopfbuehne__fuss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.2rem 2rem;
  margin-top: clamp(1.8rem, 4vh, 3rem);
}

.wink {
  color: var(--text-3);
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: .6em;
}
.wink::after {
  content: "";
  width: 1px; height: 22px;
  background: currentColor;
  animation: wink 2.6s ease-in-out infinite;
  transform-origin: top;
}
@keyframes wink {
  0%, 100% { transform: scaleY(.3); opacity: .35; }
  50%      { transform: scaleY(1);  opacity: 1; }
}

/* ---------------------------------------------------------------- Bühnen */

.buehne {
  position: relative;
  padding: clamp(56px, 11vh, 132px) 0;
  border-top: 1px solid var(--linie);
}
.buehne--ohne-linie { border-top: 0; }

.kicker {
  margin: 0 0 1.15rem;
  color: var(--akzent-1);
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
}

/* Die große Aussage einer Bühne. Bewusst nur eine je Bühne. */
.ansage {
  margin: 0 0 1.4rem;
  font-size: clamp(1.75rem, 4.2vw, 3.5rem);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: var(--sperr-display);
  max-width: 20ch;
}
.ansage--breit { max-width: 26ch; }

.fliess {
  margin: 0 0 1rem;
  max-width: 56ch;
  color: var(--text-2);
  font-size: clamp(1rem, 1.35vw, 1.1rem);
  line-height: 1.5;
}
.fliess:last-child { margin-bottom: 0; }

/* --------------------------------------------------------- Filmografie */

/* ARRIs Credits-Galerie mit Aufklapper. Sichtbar bleiben die letzten Jahre,
   der Rest liegt hinter einem Klick — genau der Griff gegen die lange Liste.
   <details> statt JavaScript: funktioniert ohne Skript und ist bedienbar. */
.credits { list-style: none; margin: 0; padding: 0; }

.credits li {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr) auto;
  gap: clamp(12px, 2vw, 32px);
  align-items: baseline;
  padding: .78rem 0;
  border-bottom: 1px solid var(--linie);
}
.credits li:first-child { border-top: 1px solid var(--linie); }

.credits .jahr { color: var(--akzent-2); font-size: .78rem; font-weight: 700; letter-spacing: .05em; white-space: nowrap; }
.credits .titel { font-weight: 700; font-size: 1.02rem; }
.credits .rolle-klein {
  color: var(--text-3);
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  text-align: right;
  white-space: nowrap;
}

.mehr { margin-top: 1.6rem; }
.mehr > summary {
  display: inline-flex;
  align-items: center;
  gap: .7em;
  cursor: pointer;
  list-style: none;
  color: var(--akzent-1);
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  padding: .5em 0;
}
.mehr > summary::-webkit-details-marker { display: none; }
.mehr > summary::after {
  content: "+";
  font-size: 1.2em;
  line-height: 1;
  transition: transform .2s ease;
}
.mehr[open] > summary::after { content: "–"; }
.mehr[open] > summary .mehr__zu { display: inline; }
.mehr[open] > summary .mehr__auf { display: none; }
.mehr__zu { display: none; }
.mehr > .credits { margin-top: .4rem; }

/* ---------------------------------------------------------------- Schluss */

.schluss {
  padding: clamp(64px, 13vh, 148px) 0;
  border-top: 1px solid var(--linie);
}
.schluss__reihe {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem 2.4rem;
  align-items: center;
  margin-top: clamp(1.6rem, 3vh, 2.6rem);
}
.schluss__wege {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.8rem;
  margin: 0; padding: 0;
  list-style: none;
  color: var(--text-2);
}

/* ----------------------------------------------------------------- Schmal */

@media (max-width: 860px) {
  /* Auf schmalen Geraeten reicht die Reserve fuer den Umschalter knapper aus,
     die Markenzeile scrollt ohnehin waagerecht. */
  .leiste { padding-right: calc(var(--rand) + 86px); }
  .credits li { grid-template-columns: 4.6rem minmax(0, 1fr); }
  .credits .rolle-klein { grid-column: 2; text-align: left; }
  .leiste__name { font-size: .62rem; }
}

/* -------------------------------------------------- Rücksicht und Fallback */

@media (prefers-reduced-motion: reduce) {
  .wink::after { animation: none; opacity: .8; }
}

/* Kein Autoplay-Video, wenn jemand Bewegung abbestellt hat: das Skript
   ersetzt es dann durch das Posterbild. Hier nur der Grundzustand.

   Lage und Deckkraft der beiden Kopf-Standbilder stehen weiter oben bei den
   Lagen der Kopfbühne — hier nur, dass sie normalerweise nicht da sind. */
body.ohne-film .kopfbuehne__film,
body.ohne-film .kopfbuehne__probe { display: none; }

/* ================================================== Reel-Bühnen ===========

   Die Seite ist das Reel. Zwischen den Informationsbühnen steht jeweils eine
   Bühne, die nur aus Bildmaterial besteht: bildschirmfüllend, ohne Rand.

   Der Trick ist die Höhe. Die Bühne ist höher als das Fenster, der Film darin
   klebt. Dadurch steht das Bild, während man daran vorbeiscrollt, und der
   Scrollweg wird zur Zeitachse des Films — man scrollt durch die Aufnahme
   statt an ihr vorbei.
   ======================================================================== */

.reelbuehne {
  position: relative;
  height: var(--reelweg, 180vh);
}

.reelbuehne__halt {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  isolation: isolate;
}

.reelbuehne__film,
.reelbuehne__standbild {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
body.ohne-film .reelbuehne__film { display: none; }

/* ----------------------------------------------------------- Materialbühne

   Zwei Lagen übereinander, eine sichtbar. Welche, sagt `data-material` an der
   Sektion; daran hängen Filme, Standbilder und Angabenzeile gleichermaßen. */
.materialbuehne__lage,
.materialbuehne__angabe { display: none; }
.materialbuehne[data-material="gedreht"] [data-lage="gedreht"],
.materialbuehne[data-material="ki"]      [data-lage="ki"] { display: block; }

/* Muss NACH den Regeln oben stehen und spezifischer sein: sonst holte die
   Lagenregel den Film zurück, den `ohne-film` gerade ausgeblendet hat. */
body.ohne-film .materialbuehne .reelbuehne__film { display: none; }

/* Der Regler. Ein Zweifachschalter mit laufendem Grund — dieselbe Pillenform
   wie Tonwert- und Sprachknopf, nur gefüllt statt umrandet.

   Beide Hälften sind gleich breit (`flex: 1 1 0` plus `min-width`), und nur
   deshalb kommt der Läufer mit `translateX(100%)` aus: seine Breite ist
   genau eine Hälfte. Wer die Beschriftung ändert, prüft, ob das längere Wort
   noch in die `min-width` passt — sonst laufen Läufer und Wort auseinander. */
.regler {
  position: relative;
  display: inline-flex;
  margin: .1rem 0 1rem;
  padding: 3px;
  border: 1px solid rgba(246, 245, 242, .34);
  border-radius: var(--rund-knopf);
  background: rgba(6, 8, 10, .46);
}
.regler__laeufer {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: calc(50% - 3px);
  border-radius: var(--rund-knopf);
  background: var(--akzent-1);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.materialbuehne[data-material="ki"] .regler__laeufer { transform: translateX(100%); }

.regler__wahl {
  position: relative;   /* über dem Läufer */
  z-index: 1;
  flex: 1 1 0;
  min-width: 8.5ch;
  padding: .52em 1.1em;
  border: 0;
  background: none;
  color: var(--text-2);
  font: inherit;
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: color .2s ease;
}
.regler__wahl:hover { color: var(--text-1); }
.regler__wahl[aria-pressed="true"] {
  color: var(--knopf-schrift);
  font-weight: 700;
}

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

/* Wo Bildmaterial der Grund ist, wird IMMER dunkel abgedunkelt und hell
   geschrieben — unabhängig von der gewählten Tonwertlage. Mit --papier
   gerechnet würde der Verlauf in der hellen Fassung das Bild nach Weiß
   auswaschen, statt es abzudunkeln, und der dunkle Kartentext stünde auf
   hellem Wasser. */
.reelbuehne {
  --text-1: #F6F5F2;
  --text-2: #CBD2D8;
  --text-3: #97A0A8;
  --akzent-1: #FF6A34;
  --knopf-schrift: #12100A;
  color: var(--text-1);
}
.reelbuehne__halt::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(6,8,10,.86) 0%,
    rgba(6,8,10,.58) 20%,
    rgba(6,8,10,.14) 44%,
    transparent 62%);
}

/* Die Karte: Kicker, Titel, eine Zeile Angaben. Mehr trägt ein Reel nicht. */
.reelbuehne__karte {
  position: absolute;
  left: 0; right: 0; bottom: clamp(28px, 6vh, 72px);
  z-index: 1;
}
/* Wie die Kopfbuehne: Tanker. Die Arbeitsproben sind die zweite Ebene der
   Wortmarke — steht dort Inter, zerfaellt die Seite in zwei Handschriften.
   `font-weight` bleibt 400, die Schrift ist von Haus aus fett.

   Die Sperrung ist hier NICHT --sperr-display. Der Titel steht klein auf
   Bild, nicht gross auf Papier; Tanker laeuft eng genug, und negative
   Sperrung liesse die Buchstaben auf unruhigem Grund zusammenlaufen. */
.reelbuehne__titel {
  margin: 0 0 .5rem;
  font-family: Tanker, Excon, system-ui, sans-serif;
  font-size: clamp(1.6rem, 3.6vw, 3rem);
  font-weight: 400;
  line-height: .98;
  letter-spacing: 0;
  text-transform: uppercase;
  max-width: 20ch;
}
.reelbuehne__angabe {
  margin: 0;
  color: var(--text-2);
  font-size: .8rem;
  letter-spacing: .04em;
}

/* Zähler rechts unten, wie ein Timecode. Rein typografisch, kein Bild. */
.reelbuehne__zaehler {
  position: absolute;
  right: var(--rand); bottom: clamp(28px, 6vh, 72px);
  z-index: 1;
  color: var(--text-3);
  font-size: var(--schrift-label);
  font-weight: 500;
  letter-spacing: var(--sperr-label);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 720px) {
  .reelbuehne { height: var(--reelweg-schmal, 140vh); }
  .reelbuehne__zaehler { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  /* Ohne Bewegung braucht die Bühne keinen Scrollweg zum Durchlaufen. */
  .reelbuehne { height: auto; }
  .reelbuehne__halt { position: relative; height: clamp(300px, 62vh, 620px); }
}

/* ================================================ Filmbühnen (abspielend) ==

   Anders als die Reel-Bühnen und die Kopfbühne: hier läuft der Film wirklich,
   in Schleife, hinter dem Text. Er wird nicht gescrubbt.

   Er spielt nur, solange die Bühne im Bild ist — sonst dekodierte er auch
   dann, wenn niemand hinsieht.

   Der Film liegt fest im Sichtfenster (`position: fixed`), der Text läuft
   darüber hinweg. Dadurch wirkt er wie ein Fenster ins Wasser, an dem man
   vorbeigeht, statt wie eine mitgescrollte Tapete.
   ======================================================================== */

.filmbuehne {
  position: relative;
  isolation: isolate;
  /* Der Satz braucht mehr Luft als sonst: er steht auf Bild, nicht auf Papier. */
  padding: clamp(72px, 15vh, 172px) 0;
  border-top: 0;
}

.filmbuehne__grund {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  /* clip-path zwingt das fest positionierte Kind in die Grenzen der Bühne.
     Ohne das läge der Film über der ganzen Seite.

     **Der Schnitt geht ein Bildpunkt weit hinein, nicht auf null.** Der Grund
     ist eine Rundungsfrage, die man erst auf einem Bildschirm mit doppelter
     Punktdichte sieht: die Kanten der Bühnen liegen auf Bruchteilen
     (gemessen 2556,797 · 2878,391 · 8924,781 …), der Film darin ist aber
     `position: fixed` und damit am Fenster ausgerichtet — er hat eine ganz
     andere Teilpunktlage als der Schnitt. Trifft die Schnittkante die Mitte
     eines Geraetepunktes, faerbt der Browser diese Zeile nur zur Haelfte, und
     der Scrub-Hintergrund scheint als Haarlinie ueber und unter der Buehne
     durch. Beim Scrollen wandert die Kante staendig durch solche Lagen,
     deshalb flackert es.

     Ein Bildpunkt Einschlag (zwei Geraetepunkte bei doppelter Dichte) legt
     die Schnittkante sicher innerhalb der Buehne. Damit dort kein heller
     Spalt entsteht, traegt die Sektion selbst den Grundton — siehe unten. */
  clip-path: inset(1px 0);
}

/* Der Ton, der in dem einen Bildpunkt steht, den der Schnitt frei laesst.
   Er muss zur Kante der Buehne passen, sonst tauscht man eine Haarlinie
   gegen eine andere: dunkel in der dunklen Lage, Papier in der hellen —
   genau wie die Abdunklung darueber es auch haelt. */
.filmbuehne { background: #060810; }
.filmbuehne__film,
.filmbuehne__standbild {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
body.ohne-film .filmbuehne__film { display: none; }

/* Abdunklung für die Lesbarkeit. Zwei Lagen: eine flächige, damit die Schrift
   überall trägt, und ein Verlauf von links, wo der Satz steht. */
.filmbuehne__grund::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    /* Reicht bis 72 Prozent Breite: so weit läuft der Fließtext bei 56 Zeichen
       Zeilenlänge. Vorher endete die Abdunklung bei knapp der Hälfte, und über
       den hellen Wasserpassagen von Bajau 1 fiel der Kontrast auf 3,3 zu 1 —
       genug für die Überschrift, zu wenig für den Absatz darunter. */
    linear-gradient(to right, rgba(6,8,10,.86) 0%, rgba(6,8,10,.72) 40%,
                              rgba(6,8,10,.42) 72%, rgba(6,8,10,.14) 100%),
    rgba(6,8,10,.10);
}

/* Auf einer AUFNAHME gilt immer helle Schrift, unabhängig von der gewählten
   Tonwertlage: dunkler Text auf dunklem Wasser wäre unlesbar, und ein zweites
   Farbschema für diesen Fall wäre Willkür.

   Ausgenommen sind seit dem 22.08.2026 die Farbgründe in der hellen Lage.
   Hinter ihnen liegt keine Aufnahme, sondern abstrakte Farbe — die lässt sich
   ebenso gut nach Papier auswaschen wie abdunkeln. Profil und Kontakt fügen
   sich damit in die helle Fassung ein, statt als zwei dunkle Blöcke
   dazwischenzustehen.

   Der Selektor ist bewusst so gebaut, dass die helle Lage die Marken gar
   nicht erst setzt: dann erben sie aus :root und stehen nur an einer Stelle.
   Ein zweiter Block mit denselben Werten wäre eine Falle — beim nächsten
   Palettenwechsel liefe er auseinander. */
html:not([data-theme="hell"]) .filmbuehne,
html[data-theme="hell"] .filmbuehne:not(.filmbuehne--farbgrund) {
  --text-1: #F6F5F2;
  --text-2: #CBD2D8;
  --text-3: #8E979F;
  --linie:  rgba(255,255,255,.16);
  --akzent-1: #FF6A34;
  --akzent-2: #4FD2F5;
  --knopf-schrift: #12100A;
}
.filmbuehne { color: var(--text-1); }

@media (max-width: 720px) {
  /* position:fixed und Adressleisten-Zoom vertragen sich auf Mobilgeräten
     schlecht: der Film springt beim Ein- und Ausblenden der Leiste. Dort
     scrollt er deshalb mit. */
  .filmbuehne__film,
  .filmbuehne__standbild { position: absolute; }
  .filmbuehne__grund::after {
    background:
      linear-gradient(to bottom, rgba(6,8,10,.58) 0%, rgba(6,8,10,.74) 100%),
      rgba(6,8,10,.10);
  }
}

/* --------------------------------------------------------- Farbgrund

   Eine Filmbühne, hinter der kein Bild einer Aufnahme liegt, sondern eine
   abstrakte Farbschleife. Die braucht eine eigene, kräftigere Abdunklung: die
   Fluid-Art-Schleife ist erheblich heller als das Wassermaterial — hellstes
   Bild 0,99 relative Leuchtdichte gegen 0,73 bei Bajau 2. Mit der Abdunklung
   der Aufnahmebühnen fiel der Fließtext auf 1,7 zu 1.

   Nachgemessen, nicht geschätzt: schlechtester Bildpunkt in der Textspalte
   über vierundzwanzig Zeitpunkte des Films, Verlauf und Grundlage
   einberechnet.

     Fließtext 8,6:1 · Ansage 12,0:1 · Kicker 4,6:1

   Alle über den 4,5:1, die WCAG AA für Fließtext verlangt. Dass hier auch der
   orangene Kicker darüber liegt, ist Absicht: auf den Aufnahmebühnen tut er
   das nicht. Beim Austausch des Materials neu messen — eine hellere Schleife
   kippt das sofort.

   Dass die Abdunklung kräftig ausfällt, kostet hier nichts: das Bild trägt
   keine Information, es ist Farbe. Bei einer Aufnahme wäre derselbe Wert
   falsch, dort soll man sehen, was zu sehen ist. */
.filmbuehne--farbgrund .filmbuehne__grund::after {
  background:
    linear-gradient(to right, rgba(6,8,10,.92) 0%, rgba(6,8,10,.86) 40%,
                              rgba(6,8,10,.72) 78%, rgba(6,8,10,.50) 100%),
    rgba(6,8,10,.50);
}
@media (max-width: 720px) {
  /* Schwächster Punkt ist hier die Oberkante mit .74 über der Grundlage .34;
     gemessen ergibt das Fließtext 8,4:1 und Kicker 4,5:1. */
  .filmbuehne--farbgrund .filmbuehne__grund::after {
    background:
      linear-gradient(to bottom, rgba(6,8,10,.74) 0%, rgba(6,8,10,.84) 100%),
      rgba(6,8,10,.34);
  }
}

/* --------------------------------------------- Farbgrund in der hellen Lage

   Profil und Kontakt sollen sich in die helle Fassung einfügen, statt als zwei
   dunkle Blöcke zwischen Filmografie und Fußzeile zu stehen. Also derselbe
   Aufbau wie oben, nur andersherum: der Grund wird nach Papier ausgewaschen
   statt abgedunkelt, und die Schrift kommt aus der Grundpalette.

   Dass das hier geht und bei den Reel-Bühnen nicht, liegt am Material. Hinter
   den Farbgründen liegt keine Aufnahme, sondern abstrakte Farbe — die trägt
   keine Information, die verlorengehen könnte. Bei einer Aufnahme wäre ein
   Auswaschen auf über neunzig Prozent gerade das, was man nicht will.

   Bindend ist der orangene Kicker, nicht der Fließtext: --akzent-1 hat gegen
   Papier nur 4,9:1, ihm bleibt über dem Bild am wenigsten Luft. Aus dieser
   Bedingung stammen die Werte — an der schwärzesten Stelle des Films muss der
   ausgewaschene Grund noch über 210 von 255 liegen. */
/* Ein tieferer Ember, nur hier. Das ist keine zweite Handlungsfarbe, sondern
   dieselbe für einen anderen Grund — wie #FF6A34 auf den dunklen Filmbühnen,
   nur in die andere Richtung.

   Er ist nötig, nicht Geschmack: --akzent-1 hat auf blankem Papier 4,90:1.
   Jeder sichtbare Film darunter drückt ihn zwangsläufig darunter, egal wie
   stark man auswäscht — die Luft ist schlicht nicht da. Entweder der Film
   verschwindet fast ganz (Wasch über 96 Prozent), oder der Ember wird tiefer.
   #9C3709 hält 5,1:1 über dem Farbgrund und 6,8:1 auf Papier. */
html[data-theme="hell"] .filmbuehne--farbgrund { --akzent-1: #9C3709; }
html[data-theme="hell"] .filmbuehne--farbgrund { background: var(--papier); }

html[data-theme="hell"] .filmbuehne--farbgrund .filmbuehne__grund::after {
  background:
    linear-gradient(to right,
      color-mix(in srgb, var(--papier) 90%, transparent) 0%,
      color-mix(in srgb, var(--papier) 84%, transparent) 40%,
      color-mix(in srgb, var(--papier) 70%, transparent) 78%,
      color-mix(in srgb, var(--papier) 45%, transparent) 100%),
    color-mix(in srgb, var(--papier) 55%, transparent);
}
@media (max-width: 720px) {
  html[data-theme="hell"] .filmbuehne--farbgrund .filmbuehne__grund::after {
    background:
      linear-gradient(to bottom,
        color-mix(in srgb, var(--papier) 78%, transparent) 0%,
        color-mix(in srgb, var(--papier) 88%, transparent) 100%),
      color-mix(in srgb, var(--papier) 40%, transparent);
  }
}

/* Reel-Bühne, in der der Film wirklich abläuft statt gescrubbt zu werden.
   Ohne Scrollweg zum Durchlaufen reicht ihr weniger Höhe. */
.reelbuehne--laeuft .reelbuehne__karte { max-width: none; }
.reelbuehne--laeuft .reelbuehne__zaehler { letter-spacing: var(--sperr-label); }