/* Mentoki — Buehne: der feste Hintergrund und die Scroll-Dramaturgie.
 *
 * Der Hintergrund liegt EINMAL im Dokument und laeuft fest ueber die ganze
 * Seite. Nicht acht Effekte nacheinander, sondern ein Hintergrund, der acht
 * Zustaende durchlaeuft (sechs Streifen der Bildfolge, dazu zwei Standakte,
 * in denen die Form stehen bleibt). Welcher Zustand wann gilt, steht in
 * js/drehbuch.js — hier steht nur, wie ein Zustand aussieht.
 *
 * Die Schichten von unten nach oben:
 *   .hintergrund__verlauf   weisser Grund. Null Bytes, sofort da, funktioniert
 *                           ohne JavaScript. Das ist der erste sichtbare
 *                           Eindruck — nie ein Bild.
 *   .origami                das gefaltete Papier als SVG — Rueckfallebene
 *   .hintergrund__bild       die Bildfolge aus echtem gefilmtem Faltpapier
 *
 * ═══ Der Kniff: Weiss auf Weiss ═══════════════════════════════════════
 *
 * Die Bildfolge zeigt ein Papierobjekt auf reinweissem Grund, und die Seite
 * hat einen reinweissen Grund. Die Bildschicht liegt deshalb in
 * `mix-blend-mode: multiply`.
 *
 * Multiply laesst reines Weiss (255) spurlos verschwinden: Der Untergrund
 * bleibt unveraendert, sichtbar bleibt nur das Papier mit seinem Schatten.
 * Daraus folgt alles Weitere —
 *
 *   · kein Alphakanal noetig (das Videomodell kann keinen liefern)
 *   · kein Freistellen, kein Maskieren
 *   · keine sichtbare Kante um das Objekt, in keiner Fenstergroesse
 *
 * Die Bedingung ist, dass das Weiss wirklich 255 ist. Aus der Kamera war es
 * das nicht — der Studiohintergrund traegt eine Vignette und fiel bis auf 177
 * ab, was den Seitengrund um 30 % abgedunkelt haette. Dafuer gibt es
 * werkzeuge/weisspunkt.py; ohne diesen Schritt sitzt hier ein grauer Kasten.
 *
 * `isolation: isolate` auf .hintergrund ist dabei nicht schmueckend, sondern
 * tragend: Es haelt das Multiply in seinem eigenen Stapelkontext. Ohne das
 * wuerde die Bildschicht auch gegen den Text darueber multiplizieren.
 */

/* ═══ Der feste Schichtstapel ═══════════════════════════════════════════ */

.hintergrund {
  /* inset: -8px statt 0 — die Reserve fuer das Schweben weiter unten, damit
     beim Ausschlag am Rand kein Streifen frei wird. */
  position: fixed; inset: -8px; z-index: 0;
  pointer-events: none;
  isolation: isolate;   /* haelt das Multiply in diesem Stapelkontext */
  background: var(--grund);
  animation: schweben 11s ease-in-out infinite;
}

/* ── Das Papier atmet ───────────────────────────────────────────────────
 *
 * Die rAF-Schleife laeuft nur, solange gescrollt wird. Steht man still, steht
 * auch das Papier — und eine Seite, die ausschliesslich auf Scrollen antwortet,
 * wirkt im Stehen wie ein Bildschirmfoto.
 *
 * ── Warum die Animation ausgerechnet HIER haengt ──
 *
 * Nicht an .hintergrund__bild und .origami: Die tragen bereits eine aus
 * JavaScript gespeiste transform-Kette, und eine CSS-Animation auf derselben
 * Eigenschaft loescht sie vollstaendig aus.
 *
 * Auch nicht an einer Huelle um beide: Eine Huelle mit transform macht einen
 * eigenen Stapelkontext auf, und das mix-blend-mode: multiply der Bildschicht
 * rechnete dann gegen die Innenseite dieser Huelle statt gegen den weissen
 * Grund. Das Weiss verschwaende nicht mehr spurlos — es saesse wieder ein
 * Kasten um den Flieger, genau der Fehler, den weisspunkt.py behebt.
 *
 * .hintergrund hat seinen Stapelkontext durch isolation: isolate ohnehin. Die
 * Multiply-Gruppe aendert sich also nicht. Mitbewegt wird der Verlauf, und der
 * ist bei --farbwaesche: 0 reinweiss — seine Verschiebung ist unsichtbar.
 *
 * 8 px Weg in 11 s, und transform ist die einzige Eigenschaft, die der
 * Compositor ohne Layout und ohne Paint bewegt. */
@keyframes schweben {
  0%, 100% { transform: translateY(-4px); }
  50%      { transform: translateY(4px); }
}

/* Ueber den Hintergrund heben. Die Kopfleiste steht hier bewusst NICHT mit
   drin: Sie ist in grundlage.css `position: fixed`, und diese Datei wird
   spaeter geladen — ein `position: relative` haette das bei gleicher
   Spezifitaet still ueberschrieben. Genau das war der Fall, und die Leiste
   nahm dadurch 48 px im Fluss weg, statt zu schweben. Ihre eigene z-index: 50
   wirkt ohnehin schon, weil `fixed` einen Stapelkontext aufmacht. */
main, .fuss { position: relative; z-index: 1; }

/* Der Grund. Im Apple-Stil steht --farbwaesche auf 0, die Markenrampe ist
   damit unsichtbar und die Flaeche schlicht weiss. Der Verlauf bleibt
   trotzdem stehen: Er ist die einzige Schicht, die ohne JavaScript und ohne
   ein einziges geladenes Byte funktioniert. Wer die Seite waermer haben will,
   dreht --farbwaesche auf. */
.hintergrund__verlauf {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 92% at 12% 6%,
      rgb(178 36 75 / calc(var(--i-himbeer) * var(--farbwaesche))) 0%, transparent 62%),
    radial-gradient(115% 88% at 86% 26%,
      rgb(255 122 47 / calc(var(--i-orange) * var(--farbwaesche) * .8)) 0%, transparent 58%),
    radial-gradient(140% 105% at 46% 102%,
      rgb(255 209 82 / calc(var(--i-amber) * var(--farbwaesche) * 1.1)) 0%, transparent 64%),
    var(--grund);
  transition: background .6s linear;
}

/* ═══ Die Box, in der das Papier steht ═════════════════════════════════
   Bildfolge und Rueckfallebene teilen sie sich: gleicher Stand, gleiche
   Groesse, dieselben drei Variablen aus js/drehbuch.js. Sie koennen dadurch
   gar nicht auseinanderdriften. */

.hintergrund__bild,
.origami {
  position: absolute;
  top: 50%; left: 50%;
  aspect-ratio: 16 / 9;
  transform:
    translate(-50%, -50%)
    translate(calc(var(--papier-x, 0) * 1%), calc(var(--papier-y, -56) * 1%))
    translateY(var(--papier-hoch, 0px))
    scale(var(--papier-skala, 1));
  will-change: transform;
}

/* Der Versatz aus dem Drehbuch ist ein Prozentsatz der EIGENEN Kantenlaenge.
   Das haelt die Choreografie einfach, hat aber einen Haken: Auf einem kurzen
   Fenster schrumpft die Box mit, der Versatz schrumpft also ebenfalls — und
   das Papier rutscht dem Text entgegen, statt ihm auszuweichen. Gemessen bei
   1440 x 640: ein Pixel Abstand zwischen Schlagschatten und Vorzeile.

   Deshalb hier ein zweiter, FENSTERbezogener Anteil. Er steht vor `scale`,
   wirkt also in unskalierten Pixeln, und greift nur dort, wo es eng wird. */
@media (max-height: 50rem) {
  .hintergrund__bild, .origami { --papier-hoch: -5vh; }
}
@media (max-height: 42rem) {
  .hintergrund__bild, .origami { --papier-hoch: -8vh; }
}

.hintergrund__bild { width: min(64vmin, 760px); }

/* Das SVG steht breiter, weil sein viewBox quadratisch ist: bei 16:9 und
   `meet` begrenzt die Hoehe, die Zeichnung schrumpft also auf 9/16. Der
   Aufschlag gleicht das aus, damit der Flieger in beiden Schichten ungefaehr
   gleich gross erscheint — gemessen fuellt er in beiden rund 400 px. */
.origami { width: min(60vmin, 700px); }

/* ── Die Bildfolge ──────────────────────────────────────────────────── */

.hintergrund__bild {
  opacity: var(--bild-deckkraft, 0);
  mix-blend-mode: multiply;
  transition: opacity .45s var(--kurve);

}

/* Das Poster ist das erste Bild der Folge und steht, sobald JavaScript die
   Stufe gesetzt hat. Damit ist die Buehne nie leer, auch nicht in den zwei
   Sekunden, bis die erste Ladewelle durch ist. Es liegt UNTER der Leinwand und
   wird von ihr verdeckt, sobald sie zeichnet — ein Umschaltmoment ist deshalb
   nicht zu sehen.

   Gebunden an die Stufe, nicht unbedingt: Als unbedingter Hintergrund holte
   der Browser die 44 KB sofort beim Seitenaufbau, im kritischen Pfad neben der
   Ueberschrift — obwohl die Schicht auf opacity 0 stand. Sichtbar wird sie
   ohnehin erst, wenn die Schleife --bild-deckkraft setzt; und ohne JavaScript
   traegt das Origami den Effekt. Es geht also nichts verloren. */
html[data-stufe='klein'] .hintergrund__bild,
html[data-stufe='voll'] .hintergrund__bild {
  background: url('/medien/poster/flieger.jpg') center / contain no-repeat;
}

.hintergrund__leinwand {
  display: block;
  width: 100%; height: 100%;
  /* Der Kontext laeuft mit alpha:false, eine leere Leinwand waere also
     schwarz — unter multiply eine schwarze Flaeche. Bis das erste Bild
     gezeichnet ist, bleibt sie deshalb unsichtbar und das Poster steht. */
  opacity: 0;
  transition: opacity .5s var(--kurve);
  /* Der Backing-Store ist absichtlich kleiner als die Anzeige — nie groesser
     als die Quelle (960 px). Das Hochskalieren uebernimmt die GPU und kostet
     nichts. */
}
.hintergrund__leinwand[data-bereit] { opacity: 1; }

/* ── Die Rueckfallebene ─────────────────────────────────────────────────
   Sichtbar ist immer nur eine der beiden Schichten, und die Umschaltung
   haengt an der Leistungsstufe, nicht am Ladezustand.

   Das ist Absicht: Waeren beide gleichzeitig sichtbar, wuerde die Bildfolge
   per multiply gegen das farbige Origami rechnen und daraus eine dunkle
   Mischung machen. `data-stufe` setzt js/haupt.js sofort beim Start, also
   bevor irgendetwas geladen ist — die Umschaltung passiert nie im Betrieb.

   Ohne JavaScript ist data-stufe nicht gesetzt: Dann greift keine der beiden
   Regeln unten, das Origami bleibt sichtbar, und die Seite hat ihren Effekt. */
.origami {
  opacity: .95;
  overflow: visible;
  transition: opacity .4s var(--kurve);
}

html[data-stufe='klein'] .origami,
html[data-stufe='voll'] .origami { opacity: 0; }

.origami__facette { stroke: none; }

/* Gefaltetes Papier — die Toene sind AUS DER BILDFOLGE gemessen, nicht aus
   dem Logo abgeschrieben.

   Vorher standen hier die reinen Logofarben (#FF7A2F, #B2244B, #E01B4C,
   #FFD152). Das war richtig, solange das SVG der Effekt selbst war. Seit
   daneben echtes, belichtetes Papier liegt, sind reine Markenfarben zu satt:
   Fotografiertes Papier ist immer aufgehellt und leicht entsaettigt, und die
   flache Vektorfassung wirkte daneben grell.

   Die Werte stammen aus medien/bildfolge/gross/0000.jpg, abgetastet entlang
   des Farbverlaufs von der hellsten Amberflaeche bis zum tiefsten Faltschatten.
   Rueckfallebene und Bildfolge zeigen dadurch dasselbe Material. */
.origami__facette--a { fill: #FEA456; }   /* grosse Flaeche, Orange */
.origami__facette--b { fill: #A5333D; }   /* Faltschatten, tiefes Himbeer */
.origami__facette--c { fill: #E56F29; }   /* zweite grosse Flaeche */
.origami__facette--d { fill: #FEC56C; }   /* Lichtkante, Amber */
.origami__facette--e { fill: #C4494E; }   /* Aussenkante */
.origami__facette--f { fill: #F08B45; }   /* Faltflaeche, Orange */

/* Unter 64rem gibt es keine zweite Spalte mehr: Der Text nimmt die volle
   Breite ein, und das Papier steht zwangslaeufig dahinter. Ausweichen kann es
   nicht, also wird es blass.

   Der Wert ist nicht gegriffen. Auf dem Himbeerrot der Faltschatten liegt der
   Textkontrast bei 2,3:1 und damit weit unter dem Zulaessigen; bei 30 %
   Deckkraft auf weissem Grund steigt er auf ueber 10:1. Das Papier bleibt als
   Form erkennbar und der Text bleibt lesbar — beides geht hier nur so. */
@media (max-width: 63.99rem) {
  .hintergrund__bild { opacity: calc(var(--bild-deckkraft, 0) * .3); }

  /* Ausser im Hero. Dort steht der Text unter dem Papier, nicht dahinter —
     es gibt also nichts abzudunkeln, und der erste Eindruck darf das Papier
     in voller Staerke zeigen. Den laufenden Akt fuehrt js/hintergrund-buehne.js
     am Wurzelelement. */
  html[data-akt='hero'] .hintergrund__bild { opacity: var(--bild-deckkraft, 0); }
}

@media (max-width: 48rem) {
  /* Auf dem Telefon steht die Form kleiner und zurueckhaltender — dort ist
     der Text knapp, und ein grosses Objekt dahinter macht ihn unruhig. */
  .hintergrund__bild { width: min(88vmin, 460px); }
  .origami { width: min(105vmin, 560px); opacity: .8; }
}

/* ── Die Sprechblase am Seitenende ──────────────────────────────────────
   Im letzten Akt zieht die Sprechblase in die Mitte und stellt sich ueber
   „Sprechen wir darueber." Das ist das Schlussbild, und am Seitenende bleibt
   es stehen: `p` erreicht dort nie 1 (gemessen .62 bis .72), die Abblendung im
   Drehbuch ab .62 wird also nicht fertig — gewollt.

   Auf kurzen Fenstern ist fuer das Schlussbild kein Platz. Gemessen auf
   1440 x 687: Box bei −24 bis 129 px, Vorzeile „KONTAKT" bei 81 px — die
   Sprechblase sass auf der Vorzeile. Nur CSS kennt die Fensterhoehe, deshalb
   steht die Regel hier und nicht im Drehbuch: Unter 46 rem blendet die
   Sprechblase nach dem Ankommen ab (p .4 → .6; am Seitenende liegt p auf
   diesen Fenstern bei >= .65). Ab 46 rem hat sie Luft — auf 900 px endet die
   Box bei 214 px, die Vorzeile beginnt bei 248; auf 1024 x 768 sind es 147
   gegen 175 — und bleibt stehen.

   --akt-p schreibt js/hintergrund-buehne.js in fuehre(), wie --akt-halt. Nur
   ab 64rem: Darunter steht das Papier ohnehin auf 30 % (Regel oben), und zwei
   Deckkraftregeln auf demselben Element sollen sich nicht ueberlagern. */
@media (min-width: 64rem) and (max-height: 46rem) {
  html[data-akt='kontakt'] .hintergrund__bild {
    opacity: calc(var(--bild-deckkraft, 0) * clamp(0, (.6 - var(--akt-p, 0)) * 5, 1));
  }
}

/* Hier stand kurzzeitig eine Regel, die das Netz im Ueber-uns-Akt auf 45 %
   abblendete, damit es den Gruenderkoepfen nicht die Schau stiehlt. Sie ist
   wieder raus: Seit die Koepfe klein in ihren Rasterzellen sitzen statt als
   breites Bild ueber der Liste, stehen sie dem Netz nicht mehr im Weg — und
   eine Abblendung, die man beim Scrollen als Aufhellen des Hintergrunds
   wahrnimmt, ist auffaelliger als das Problem, das sie loesen sollte. */

/* ═══ Buehnen: lange Abschnitte, deren Inhalt stehen bleibt ═════════════ */

.buehne {
  position: relative;
  height: calc(var(--laenge, 250) * 1svh);   /* --laenge in Viewporthoehen */
}

.buehne__halt {
  position: sticky; top: 0;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-block: clamp(6rem, 14vh, 11rem) clamp(4rem, 10vh, 8rem);
}

/* Die Ueberlaenge ist die Scrollstrecke, waehrend der der Inhalt stehen bleibt
   und sich nur der Hintergrund verwandelt. `--laenge: 250` heisst: eineinhalb
   Bildschirmhoehen scrollen, ohne dass der Text sich bewegt. Das war zu viel.

   Zweimal gekuerzt: erst von 250/150/200 auf 170/130/155, dann noch einmal,
   als die Abblendung des Inhalts entfiel (Begruendung weiter unten). Seither
   traegt allein das Papier die Bewegung, und der Haftweg — --laenge minus 100 —
   ist genau die Strecke, auf der es das tun muss. */
.buehne--hero { --laenge: 145; }
.buehne--claim { --laenge: 115; }
/* „Ueber uns" ist seit dem Gruenderbild keine Haftbuehne mehr, sondern ein
   gewoehnlicher Abschnitt — Begruendung im Markup. Es bleiben zwei Buehnen. */

/* ═══ Die Drift einer Buehne ═══════════════════════════════════════════
 *
 * Der Inhalt einer Sticky-Buehne beantwortet das Scrollen selbst: Er steigt von
 * der ersten Umdrehung an langsam auf. Man sieht das nicht bewusst, man merkt
 * nur, dass die Seite antwortet.
 *
 * Der Weg ist ein fester ANTEIL der Haftstrecke, keine feste Laenge: 7 % davon.
 * Der Text steigt damit ueberall mit 7 % der Scrollgeschwindigkeit — eine echte
 * Parallaxe, in jeder Buehne dieselbe. Mit einem festen Wert waere sie es nicht:
 * Der Claim haelt nur 15 svh, der Hero 45, und dieselben 3 rem haetten den Claim
 * dreimal so schnell wandern lassen wie den Hero.
 *
 * Nebenwirkung, die erwuenscht ist: Wer --laenge aendert, muss hier nichts
 * nachziehen. Die Drift folgt.
 *
 * ── Was hier vorher stand, und warum es weg ist ──
 *
 * Bis hierher blendete der Inhalt zum Aktende zusaetzlich auf NULL ab. Das war
 * als Gegenstueck zur gekuerzten Strecke gedacht, hatte aber einen Preis, den
 * erst das Scrollen zeigt: Ueberschrift und Claim verschwanden mitten auf der
 * Seite vollstaendig und kamen danach wieder. Gemessen im Hero auf einem
 * 900er-Fenster — ab 347 px Scrollweg wurde die Ueberschrift blass, ab 609 px
 * war sie fort. Das liest sich beim Scrollen nicht als Dramaturgie, sondern
 * als Aussetzer.
 *
 * Der Text bleibt deshalb stehen, und die Bewegung traegt jetzt das Papier: Es
 * zieht hinter der Schrift vorbei, statt sie zu vertreiben. Damit das lesbar
 * bleibt, tragen die Buehnen einen weissen Texthalo (Regel weiter unten) —
 * ohne den waere diese Aenderung nicht zu haben.
 *
 * Der Stillstand, den die Abblendung kaschieren sollte, ist trotzdem kein
 * Thema mehr: Die Haftstrecken sind ein zweites Mal gekuerzt worden
 * (170/130/155 → 145/115/135 svh). Wer eine der beiden Schrauben zurueckdreht,
 * muss die andere mitdrehen.
 *
 * --akt-halt schreibt js/hintergrund-buehne.js: 0, sobald die Oberkante des
 * Abschnitts den Fensterrand erreicht, 1, wenn der Inhalt sich wieder loest.
 * Ohne JavaScript ist es nicht gesetzt, der Vorgabewert 0 laesst den Inhalt
 * schlicht stehen.
 *
 * Bewusst NICHT --akt-p: Das misst die Bildschirmmitte und steht am
 * Seitenanfang schon bei 0,29. Der „Scrollen"-Hinweis war damit beim ersten
 * Blick bereits ausgeblendet.
 *
 * Die Regeln haengen an `html[data-akt='…']` und gelten deshalb nur, solange
 * der Akt LAEUFT. Das ist kein Beiwerk: Es gibt nur EINE globale Variable, und
 * sie traegt immer den Wert des gerade aktiven Akts. Ohne die Bindung wuerde
 * der Claim-Abschnitt schon driften, waehrend man noch im Hero scrollt. */
html[data-akt='hero']  .buehne--hero  .hero,
html[data-akt='claim'] .buehne--claim .bahn {
  /* --laenge erbt von der Buehne; (--laenge - 100) ist die Haftstrecke in svh. */
  transform: translateY(
    calc(var(--akt-halt, 0) * (var(--laenge, 100) - 100) * -.07 * 1svh));
}

/* Der Flieger zieht hinter dem Text vorbei — das ist gewollt. Ein weisser
   Kasten hinter der Schrift wuerde ihn abschneiden; ein weicher Schein direkt
   um die Buchstaben laesst ihn bis an die Lettern heran sichtbar und haelt den
   Kontrast trotzdem oben. Auf dem Himbeerrot der Faltschatten liegt er sonst
   bei 2,3:1.

   Nicht seitenweit, denn text-shadow kostet Paintzeit: nur auf den zwei
   Haftbuehnen und in den zwei gewoehnlichen Abschnitten, in denen das Netz —
   die breiteste Form — mit Skala .92 bei x = 58 der Textspalte am naechsten
   kommt („Ueber uns" und „Haeufige Fragen"). In den uebrigen Abschnitten
   weicht das Papier ohnehin weit genug in die rechte Spalte aus. */
.buehne .hero,
.buehne .bahn,
#ueberuns .bahn,
#fragen .bahn {
  text-shadow: 0 0 .5rem #fff, 0 0 1.25rem #fff, 0 0 2.5rem #fff;
}

/* Der Scrollhinweis hat seine Aufgabe erfuellt, sobald gescrollt wird. */
html[data-akt='hero'] .buehne--hero .hero__hinweis {
  opacity: calc(1 - clamp(0, calc(var(--akt-halt, 0) * 6), 1));
}

/* Im Hero sitzt der Text UNTEN, nicht mittig.
   Darueber schwebt der Flieger, und beides zusammen ergibt die Aufteilung,
   mit der Apple Produktseiten baut: Gegenstand oben, Aussage darunter. Waere
   der Text mittig, liefe er mitten durch das Papier — und Text auf farbigem
   Grund verliert genau den Kontrast, den die Kontrasttabelle sichert. */
.buehne--hero .buehne__halt {
  padding-inline: var(--rand);
  max-width: var(--bahn); margin-inline: auto; width: 100%;
  justify-content: flex-end;
  /* Der untere Abstand schrumpft auf kurzen Fenstern mit — dort wird jeder
     Pixel zwischen Flieger und Ueberschrift gebraucht. */
  padding-block: 4rem clamp(3rem, 11vh, 9.5rem);
}

/* Auf kurzen oder schmalen Bildschirmen wird die Scrollstrecke gekuerzt:
   sonst scrollt man lange durch wenig Inhalt. */
@media (max-width: 48rem), (max-height: 34rem) {
  .buehne--hero { --laenge: 160; }
  /* Der Claim behaelt seine 115 von oben. */
}

/* ═══ Auftritte ════════════════════════════════════════════════════════
   Apple bewegt wenig und schnell. 28 px Hub wie im ersten Entwurf wirken
   daneben schwerfaellig; 10 px genuegen, damit die Bewegung gelesen wird. */

/* Nur wenn JavaScript laeuft: html[data-js] setzt ein Inline-Skript im Kopf
   von index.html, synchron und vor dem ersten Paint. Unbedingt gesetzt war
   das opacity: 0 ein Versprechen ohne Einloesung — ohne JavaScript setzt
   niemand data-da, und die Seite bestand aus Kopfleiste und Hintergrund,
   entgegen der Zusage in CLAUDE.md, dass sie auch ohne Skript ihren Inhalt
   zeigt. data-stufe aus js/haupt.js taugt dafuer nicht: Das Modul laeuft
   erst nach dem Parsen, bis dahin kann schon gemalt worden sein. */
html[data-js] [data-auftritt] {
  opacity: 0; transform: translateY(.625rem);
  transition: opacity .6s var(--kurve), transform .6s var(--kurve);
}
html[data-js] [data-auftritt][data-da] { opacity: 1; transform: none; }

/* Gestaffelt, damit Listen nacheinander erscheinen statt als Block. Die
   Fragen sind fuenf — kuerzer gestaffelt als die uebrigen Listen, sonst
   wartet die letzte fast 300 ms. */
.feld[data-auftritt] { transition-delay: calc(var(--rang, 0) * 60ms); }
.zielgruppe[data-auftritt] { transition-delay: calc(var(--rang, 0) * 70ms); }
.gruender__person[data-auftritt] { transition-delay: calc(var(--rang, 0) * 80ms); }
.frage[data-auftritt] { transition-delay: calc(var(--rang, 0) * 50ms); }

/* ═══ Ruhe-Stufe ═══════════════════════════════════════════════════════
   Kein rAF, keine Bildfolge, keine Bewegung — nur der ruhige Grund und das
   Origami, das ohne Scrollstrecke in seiner Ausgangsform stehen bleibt. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .12s !important;
  }
  html[data-js] [data-auftritt] { transform: none; }
  .hero__strich::after { animation: none; opacity: .6; }

  /* Die Buehnen brauchen ihre Ueberlaenge nur fuer den Scroll-Effekt. */
  .buehne { height: auto; }
  .buehne__halt { position: static; min-height: 0; padding-block: 7rem 5rem; }

  /* Ohne Haftstrecke gibt es keine Drift — aber --akt-halt behaelt den Wert,
     den die Schleife zuletzt geschrieben hat. Ohne diese Zeile stuende der
     Inhalt hier um bis zu 3 rem versetzt. */
  .buehne__halt .hero, .buehne__halt .bahn { transform: none; }
  .buehne--hero .buehne__halt {
    min-height: 100svh; justify-content: flex-end;
    padding-block: 4rem clamp(6rem, 15vh, 9.5rem);
  }
  .hintergrund {
    position: absolute; inset: 0 0 auto; height: 100svh;
    animation: none;   /* kein Atmen, wenn Bewegung reduziert werden soll */
  }
}

/* In den sparsamen Stufen faellt die LEINWAND weg, nicht die Bildschicht —
   und das Origami uebernimmt (siehe die Regel weiter oben). */
html[data-stufe='ruhe'] .hintergrund__bild,
html[data-stufe='sparsam'] .hintergrund__bild { display: none; }

/* In der Ruhe-Stufe laeuft keine rAF-Schleife, das Papier bewegt sich also
   nicht mit. Ein feststehender Hintergrund wuerde dann ueber jedem Abschnitt
   kleben, den man gerade liest — genau die Form von Stoerung, die „Bewegung
   reduzieren" vermeiden soll. Deshalb steht der ganze Stapel hier nicht fest,
   sondern einmal oben und scrollt mit dem Hero davon. */
html[data-stufe='ruhe'] .hintergrund {
  position: absolute; inset: 0 0 auto; height: 100svh;
}

/* Das Atmen faellt in beiden sparsamen Stufen weg. Bei 'sparsam' ist das kein
   Schoenheitsgriff: In diese Stufe schaltet auch die Notbremse aus
   js/hintergrund-buehne.js, wenn die Bilder dauerhaft zu lange brauchen — dann
   ist das Geraet am Anschlag und bekommt keine Dauerschleife mehr dazu. */
html[data-stufe='ruhe'] .hintergrund,
html[data-stufe='sparsam'] .hintergrund { animation: none; }

html[data-stufe='ruhe'] .buehne { height: auto; }
html[data-stufe='ruhe'] .buehne__halt { position: static; min-height: 0; }
/* Siehe oben: ohne Haftstrecke keine Drift, --akt-halt bleibt aber stehen. */
html[data-stufe='ruhe'] .buehne__halt .hero,
html[data-stufe='ruhe'] .buehne__halt .bahn { transform: none; }

/* Der Hero behaelt seine Aufteilung — Papier oben, Aussage darunter.
   „Bewegung reduzieren" heisst weniger Bewegung, nicht weniger Gestaltung.
   Ohne diese Regel rutscht der Text nach oben unter das Papier, und beide
   liegen uebereinander. Beide Schreibweisen sind noetig: Die Ruhe-Stufe
   kommt aus JavaScript, die Medienabfrage greift auch ohne. */
html[data-stufe='ruhe'] .buehne--hero .buehne__halt {
  min-height: 100svh; justify-content: flex-end;
  padding-block: 4rem clamp(6rem, 15vh, 9.5rem);
}
html[data-stufe='ruhe'] .hero__strich::after { animation: none; opacity: .6; }
