/* =============================================================
   HelloBoss — Investoren-Pitch, Parallax-Kamerafahrt
   Schwarz-weiss Noir. Gelb #FFD400 ausschliesslich fuer
   Logo und die eine Leitzahl je Szene.
   Systemschriften, keine Fremdserver.

   BEWEGUNG: Perspektiv-Parallax nach Keith Clark (2014), reines CSS.
   Der Scroll-Behaelter traegt perspective:1px. Jede Ebene sitzt auf
   einer eigenen Z-Tiefe; der Browser rechnet die Parallaxe selbst
   im Compositor. Kein Scroll-Handler, kein rAF-Loop.

   Die Rechnung (nicht geraten):
       scale = 1 + (translateZ * -1) / perspective
       Tempo = perspective / (perspective - translateZ)

       Ebene        translateZ    scale    Tempo
       bg              -3px         4      0.250x
       mid             -2px         3      0.333x
       fg              -1px         2      0.500x
       Text/Leitzahl  -0.25px       —      0.800x
       Randebenen     +0.5px        —      2.000x

   Die Randebenen liegen VOR der Kamera-Ebene (positives Z). Deshalb
   laufen sie doppelt so schnell wie der Text und rauschen beim
   Hineinfliegen seitlich aus dem Bild — das ist das Korridor-Gefuehl.

   Text- und Randebenen tragen bewusst KEIN scale(): dort wird der
   Ausgleich ueber die Layout-Breite gemacht, damit die Schriftgroesse
   unangetastet bleibt. Begruendung jeweils an der Regel selbst.
   ============================================================= */

:root{
  --gold:#FFD400;
  --ink:#000;
  --paper:#f4f4f4;
  --grey-1:#c9c9c9;
  --grey-2:#8c8c8c;
  --grey-3:#4a4a4a;
  --grey-4:#232323;

  /* Verdichtete Grotesk aus Systembestand, mit Fallback-Kette */
  --face-cond:"Haettenschweiler","Arial Narrow","Helvetica Neue Condensed",
              "Roboto Condensed","Liberation Sans Narrow",
              -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --face-ui:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",
            Arial,sans-serif;

  /* Scroll-Laenge je Szene = Kamerafahrt.
     Bei echter Perspektiv-Parallaxe laeuft die Textebene mit Tempo
     1.0x — sie ist nach genau einem Bildschirm durchs Bild gezogen.
     Die alten 340vh stammen aus der JS-Fassung, in der die Ebenen
     gebremst wurden; hier entstuende daraus eine lange tote Strecke
     ohne Text (gemessen: ab ~1200px war die Szene leer).
     190vh geben der Kamera Weg, ohne den Text zu verlieren. */
  --scene-vh:190vh;
  --pad:clamp(20px,4.4vw,88px);

  /* --- Perspektiv-Parallax: die Kamera --- */
  --persp:1px;           /* Brennweite des Scroll-Behaelters */
  --z-bg:-3px;   --s-bg:4;      /* 1 + 3/1 = 4   -> Tempo 0.250x */
  --z-mid:-2px;  --s-mid:3;     /* 1 + 2/1 = 3   -> Tempo 0.333x */
  --z-fg:-1px;   --s-fg:2;      /* 1 + 1/1 = 2   -> Tempo 0.500x */
  --z-edge:0.5px; --s-edge:.5;  /* 1 - 0.5/1 = 0.5 -> Tempo 2.000x */
}

*,*::before,*::after{box-sizing:border-box}

html{
  background:#000;
  scroll-behavior:auto;
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:#000;
  color:var(--paper);
  font-family:var(--face-ui);
  /* Kein blur() auf grossen Flaechen — M2/8GB soll tragen */
}

/* =============================================================
   DER SCROLL-BEHAELTER = DIE KAMERA
   perspective + eigener Scroll erzeugen einen festen 3D-Blickpunkt.
   Alles darin wird relativ zu diesem Punkt gerechnet — das ist
   der ganze Trick. overflow-y muss hier liegen, nicht am <html>.
   ============================================================= */
#film{
  position:fixed;
  inset:0;
  overflow-y:scroll;
  perspective:var(--persp);
  /* Mittiger Blickpunkt. Keith Clarks Webkit-Nachtrag ankert rechts,
     das taugt aber nur fuer eine einseitige Seite: hier wuerde der
     ganze Korridor nach links kippen und die linke Randebene landete
     bei left:-1440px. Gemessen und verworfen. Symmetrischer Korridor
     braucht mittigen Ursprung; der Ueberlauf wird unten geklemmt. */
  perspective-origin:50% 50%;
  /* Der Behaelter selbst ist der Ursprung des 3D-Raums */
  transform-style:preserve-3d;
  /* Weiches Ausrollen auf dem Trackpad, ohne JS */
  -webkit-overflow-scrolling:touch;
}

img,svg{display:block;max-width:100%}

/* ---------- Fortschrittsleiste ---------- */
.progress{
  position:fixed;top:0;left:0;right:0;height:3px;z-index:90;
  background:rgba(255,255,255,.07);
}
.progress i{
  display:block;height:100%;width:0;background:var(--gold);
  transform-origin:0 50%;
  will-change:width;
}

/* ---------- Scroll-Hinweis ---------- */
.scroll-cue{
  position:fixed;left:50%;bottom:26px;z-index:80;
  transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:10px;
  transition:opacity .5s ease;
  pointer-events:none;
}
.scroll-cue.is-gone{opacity:0}
.scroll-cue__txt{
  font-family:var(--face-cond);
  font-size:11px;letter-spacing:.42em;text-transform:uppercase;
  color:var(--grey-2);
}
.scroll-cue__bar{
  width:2px;height:46px;background:rgba(255,255,255,.16);
  position:relative;overflow:hidden;
}
.scroll-cue__bar i{
  position:absolute;left:0;top:0;width:100%;height:16px;
  background:var(--gold);
  animation:cueRun 1.9s cubic-bezier(.5,0,.5,1) infinite;
}
@keyframes cueRun{
  0%{transform:translateY(-18px)}
  100%{transform:translateY(48px)}
}

/* =============================================================
   SZENEN-GERUEST
   Jede Szene ist eine Gruppe im 3D-Raum. WICHTIG: eine Gruppe
   darf NICHT overflow:hidden bekommen — das flacht den 3D-Raum
   ab und die Tiefe ist weg (Keith Clark). Statt zu beschneiden
   wird ueber z-index gestapelt.
   ============================================================= */
.scene{
  position:relative;
  height:var(--scene-vh);
  transform-style:preserve-3d;
  /* Spaetere Szenen liegen ueber frueheren, damit die vorherige
     Szene beim Durchfliegen sauber verdeckt wird. Ohne Clipping
     ist das die einzige Handhabe. */
  z-index:1;
  /* Die hochskalierten Ebenen ragen rechnerisch ueber die Szene
     hinaus und blaehen scrollWidth des Behaelters auf. Sichtbar
     ist davon nichts (die Vignette deckt ab), aber der Behaelter
     liesse sich seitlich schieben. Gemessen: 576px bei 1440.
     contain:paint klemmt die Ausdehnung, ohne — anders als
     overflow:hidden — den 3D-Raum flachzulegen. */
  contain:paint;
}
/* Der Track spannt die ganze Szene auf.

   Kein sticky: sticky heftet die Ebenen ans Fenster und hebt damit
   genau die Verschiebung auf, aus der die Parallaxe entsteht —
   gemessen sank das Tempo aller Ebenen auf 0.000x.

   Stattdessen der Weg von Keith Clark: die Gruppe ist so hoch wie
   ihre Szene, die Ebenen darin sind bildschirmhoch und werden im
   Raum verteilt (siehe .layer). Die Kamera faehrt hindurch, weil
   das Dokument scrollt — nicht, weil etwas festgehalten wird. */
.scene__track{
  position:absolute;
  inset:0;
  transform-style:preserve-3d;
  /* KEIN overflow:hidden — siehe oben */
}
.scene__stage{
  position:absolute;
  inset:0;
  transform-style:preserve-3d;
}

/* Vignette. Liegt auf der Kamera-Ebene (Z=0) und deckt die Szene ab,
   damit die hochskalierten Ebenen zum Rand hin ins Schwarz laufen.
   Verlauf statt blur() — der M2 mit 8 GB soll das tragen. */
.scene__track::after{
  content:"";
  position:absolute;
  left:0;right:0;
  top:50%;height:100vh;margin-top:-50vh;
  pointer-events:none;
  z-index:60;
  transform:translateZ(0);
  background:
    radial-gradient(120% 92% at 50% 46%,transparent 42%,rgba(0,0,0,.72) 100%);
}

/* ---------- Ebenen ----------
   Jede Ebene wird EINMAL im Raum platziert und danach nie wieder
   angefasst. Die Bewegung entsteht allein aus der Z-Tiefe.        */
.layer{
  position:absolute;
  left:0;right:0;
  /* Bildschirmhoch und in der Szene zentriert. Bei top:0 saesse der
     Inhalt am Kopf der 340vh hohen Szene und der Rest liefe leer
     durch — im Bildschirmfoto war das der grosse schwarze Bereich. */
  top:50%;
  height:100vh;
  margin-top:-50vh;
  transform-origin:50% 50%;   /* mittig, passend zum perspective-origin */
  backface-visibility:hidden;
  /* KEIN will-change:transform — die Transforms sind statisch.
     will-change wuerde nur unnoetig Speicher belegen. */
}

/* Die vier Tiefen. Reihenfolge hinten -> vorn. */
.layer--bg{
  z-index:1;
  transform:translateZ(var(--z-bg)) scale(var(--s-bg));
}
.layer--mid{
  z-index:2;
  transform:translateZ(var(--z-mid)) scale(var(--s-mid));
}
.layer--fg{
  z-index:3;
  transform:translateZ(var(--z-fg)) scale(var(--s-fg));
}
/* Text und Leitzahl liegen leicht hinter der Kamera-Ebene, damit sie
   langsamer als 1.0x laufen und laenger lesbar bleiben:
       translateZ(-0.25px) -> Tempo = 1/1.25 = 0.800x

   Die zugehoerige Ausgleichs-Skalierung waere scale(1.25). Die wird
   hier bewusst NICHT auf die Ebene gelegt: sie vergroessert die
   Schrift mit und schob Ueberschrift und Leitzahl ueber den linken
   Bildrand (im Bildschirmfoto stand nur noch "ET / CHEF." und ",9%").

   Stattdessen wird die Ebene im Layout aufgeblasen, nicht per scale:
   sie ragt um 12.5% je Seite ueber das Fenster hinaus. Nach der
   perspektivischen Verkleinerung (Faktor 0.8) deckt sie dann wieder
   exakt die Fensterbreite ab — die Schriftgroesse selbst bleibt
   unangetastet, weil kein scale() im Spiel ist.
       Fensterbreite  = 1.0
       Layout-Breite  = 1 / 0.8 = 1.25  -> je Seite 12.5% Ueberstand */
.layer--text,
.layer--strip,
.layer--outro,
.layer--hero{
  left:-12.5%;
  right:-12.5%;
  top:50%;
  height:125vh;
  margin-top:-62.5vh;
}
.layer--text,
.layer--strip,
.layer--outro{
  z-index:4;
  transform:translateZ(-.25px);
}
.layer--hero{
  z-index:5;
  transform:translateZ(-.25px);
}

.art,.art__svg{position:absolute;inset:0;width:100%;height:100%}
.art__svg{object-fit:cover}

/* =============================================================
   KORRIDOR — Randebenen links und rechts
   Positives Z: naeher als die Kamera-Ebene, also doppeltes Tempo.
   Beim Hineinfliegen rauschen sie seitlich aus dem Bild. Genau
   das trennt "Kamerafahrt" von "Zoom".
   ============================================================= */
/* WICHTIG — die Vorverzerrung:
   Der Blickpunkt liegt in der Bildmitte. Eine Ebene bei translateZ(+0.5px)
   wird vom Browser um den Faktor 2 UM DIESE MITTE vergroessert. Ein
   Streifen, der im Layout am linken Rand klebt, landet dadurch komplett
   ausserhalb des Bildes (gemessen: rechte Kante bei -345px).

   Deshalb wird der Streifen vorverzerrt platziert: er sitzt im Layout
   auf halbem Weg zur Mitte und ist halb so breit wie die Zielbreite.
   Erst die perspektivische Vergroesserung um Faktor 2 schiebt ihn auf
   seinen Platz am Bildrand und auf seine volle Breite.

       Zielbreite am Schirm    9vw   (schmal: nur Rahmen, kein Vorhang)
       Layout-Breite          4.5vw  (9 / 2)
       links : Ziel  0vw     -> Layout-left 25vw
       rechts: Ziel 91vw     -> Layout-left 70.5vw

   Die scale(0.5) faellt damit weg: die Verkleinerung im Layout leistet
   dasselbe, ohne den Streifen aus dem Bild zu werfen. */
.layer--edge{
  /* Zwischen fg (3) und Text (4). NICHT darueber: mit z-index:6 lagen
     die Randebenen vor der Schrift und deckten Ueberschrift und
     Leitzahl ab — im Bildschirmfoto blieb von "ALLES LANDET BEIM
     CHEF." nur ein "F." stehen. Der Korridor rahmt das Bild, er
     verdeckt es nicht. */
  z-index:3;
  pointer-events:none;
  right:auto;left:auto;
  width:4.5vw;                /* halbe Zielbreite, s.o. */
  /* mittig in der Szene, dann halbe Bildhoehe um den Blickpunkt */
  top:50%;
  height:50vh;
  margin-top:-25vh;
  transform-origin:50% 50%;
}
.layer--edge-l{
  left:25vw;                  /* nach der 2x-Vergroesserung: linke Kante 0 */
  transform:translateZ(var(--z-edge));
}
.layer--edge-r{
  left:70.5vw;                /* nach der 2x-Vergroesserung: rechte Kante 100vw */
  transform:translateZ(var(--z-edge));
}

/* --- Das seitliche Ausrauschen ---------------------------------
   Die Perspektiv-Parallaxe allein erzeugt NUR senkrechte Bewegung:
   die Randebenen ziehen doppelt so schnell nach oben vorbei, aber
   sie wandern nicht zur Seite. Gemessen — die waagerechte Kante
   stand ueber die ganze Fahrt bei konstant 374px.

   Fuer das Korridor-Gefuehl fehlt genau diese Querbewegung. Sie
   kommt hier aus einer scrollgetriebenen CSS-Animation: keine
   Zeitachse, sondern die Scrollposition der eigenen Szene treibt
   sie. Das laeuft weiterhin im Compositor, ohne Skript und ohne
   requestAnimationFrame.

   Browser ohne animation-timeline ignorieren den Block. Dann bleibt
   die senkrechte Tiefenwirkung erhalten — die Seite bricht nicht. */
@supports (animation-timeline: view()){
  .layer--edge-l,
  .layer--edge-r{
    animation-timeline:view();
    animation-range:entry 0% exit 100%;
    animation-fill-mode:both;
    animation-timing-function:linear;
  }
  .layer--edge-l{animation-name:edgeOutL}
  .layer--edge-r{animation-name:edgeOutR}
}
/* Die Kante startet buendig am Bildrand und wandert von dort NUR
   nach aussen. Ein Startwert nach innen (fruehere Fassung: +6vw)
   schob den Streifen mitten in die Textspalte — gemessen lag die
   linke Kante dann bei x=57..288, die Ueberschrift bei x=50..397,
   und die Schrift verschwand hinter dem schwarzen Verlauf. */
@keyframes edgeOutL{
  from{transform:translateZ(var(--z-edge)) translateX(0)}
  to  {transform:translateZ(var(--z-edge)) translateX(-9vw)}
}
@keyframes edgeOutR{
  from{transform:translateZ(var(--z-edge)) translateX(0)}
  to  {transform:translateZ(var(--z-edge)) translateX(9vw)}
}
.edge-art{
  position:absolute;
  inset:0;
  width:100%;height:100%;
}
.edge-art svg{
  position:absolute;
  inset:0;
  width:100%;height:100%;
}
/* Die Kante saeuft zum Bildinneren hin ins Schwarz ab — dadurch
   sitzt sie im Dunst statt als harte Schablone im Bild. */
.layer--edge-l .edge-art::after,
.layer--edge-r .edge-art::after{
  content:"";
  position:absolute;inset:0;
  pointer-events:none;
}
/* Zum Bildinneren hin AUSBLENDEN, nicht abdunkeln. Ein Verlauf, der
   innen nach #000 laeuft, legt sich als schwarzer Balken ueber die
   Textspalte. Die Kante ist aussen dicht und wird nach innen
   durchsichtig — sie rahmt, sie deckt nicht. */
.layer--edge-l .edge-art::after{
  background:linear-gradient(to right,rgba(0,0,0,.55) 0%,rgba(0,0,0,.25) 55%,transparent 100%);
}
.layer--edge-r .edge-art::after{
  background:linear-gradient(to left,rgba(0,0,0,.55) 0%,rgba(0,0,0,.25) 55%,transparent 100%);
}

/* =============================================================
   LESE-ABDUNKLUNG ueber dem echten Bild
   Die Bilder in assets/ sind dunkel, aber detailreich: Regen,
   Geruest und Fensterraster laufen quer durch die Textspalte und
   fressen den Kontrast. Die Loesung ist KEIN Kasten hinter dem
   Text — der Text soll im Raum liegen. Stattdessen ein weicher
   Verlauf, der genau von der Seite kommt, auf der die Schrift
   steht, und zur Gegenseite hin ganz verschwindet.

   Verlauf statt blur(): ein backdrop-filter ueber halber
   Bildschirmflaeche kostet auf dem M2 mit 8 GB jedes Bild pro
   Sekunde. Ein linear-gradient ist eine reine Compositor-Flaeche.

   WO die Schicht liegen muss — teuer gelernt am 27.08.2026:
   Der erste Versuch legte je einen Verlauf auf .layer--text UND
   .layer--hero. Beide Ebenen tragen ein transform und bilden damit
   einen eigenen Stapelkontext; ein z-index:-1 im ::before kommt
   aus diesem Kontext NICHT heraus. Ergebnis: die hero-Ebene (z=5)
   legte ihren Verlauf ueber die Ueberschrift der text-Ebene (z=4).
   In Szene 4 sank die Ueberschrift dadurch auf 3.7:1 und hatte
   keinen einzigen weissen Bildpunkt mehr — gemessen, nicht geraten.

   Deshalb: EINE eigene Abdunkel-Ebene je Szene mit einem eigenen
   z-index zwischen Bild und Schrift.

   Zweite gemessene Falle: die fg-Ebene traegt in Szene 1 das
   Telefon und in Szene 5 die Preistabelle — echten Inhalt, keine
   Kulisse. Mit z-index:3 (gleich wie fg) legte sich der Verlauf
   allein wegen der spaeteren Quellreihenfolge ueber die Preise:
   alle drei Preiswerte sackten auf Spitzenhelligkeit 125 statt
   255, gemessen 3.9:1 statt 20:1. Gold und Weiss gleichermassen
   halbiert — das verraet eine deckende Schicht, keine Farbwahl.

   Die Ordnung ist deshalb ausdruecklich:
       bg 1 · mid 2 · Kulissen-fg 3 · SCRIM 4 ·
       Inhalts-fg 5 · text 6 · hero 7
   Sie traegt dieselbe Z-Tiefe wie die Textebene, damit der Verlauf
   beim Durchfliegen deckungsgleich mit der Schrift bleibt.
   ============================================================= */
.scrim{
  position:absolute;
  left:-12.5%;right:-12.5%;
  top:50%;height:125vh;margin-top:-62.5vh;
  z-index:4;                       /* ueber Kulissen-fg(3) */
  pointer-events:none;
  transform:translateZ(-.25px);    /* gleiches Tempo wie die Schrift */
  transform-origin:50% 50%;
  backface-visibility:hidden;
}
/* Text und Leitzahl ueber den Verlauf heben */
.layer--text,.layer--strip,.layer--outro{z-index:6}
.layer--hero{z-index:7}
/* Die fg-Ebenen mit echtem Inhalt (Telefon in Szene 1, Preise in
   Szene 5) gehoeren VOR den Verlauf — sonst dunkelt er sie ab. */
#s1 .layer--fg,
#s5 .layer--fg{z-index:5}
/* Szene 1: Ueberschrift oben links, Leitzahl unten links.
   Ein Verlauf von links deckt beide ab; nach rechts gibt er das
   Bild vollstaendig frei, damit der Kran sichtbar bleibt. */
#s1 .scrim{
  background:linear-gradient(to right,
    rgba(0,0,0,.78) 0%,rgba(0,0,0,.58) 30%,rgba(0,0,0,.20) 60%,transparent 86%);
}
/* Szene 2: Ueberschrift oben links, Leitzahl mittig, drei
   Bildunterschriften unten. Oben und unten abdunkeln, die Mitte
   bleibt offen — dort traegt die Panel-Vignette schon. */
#s2 .scrim{
  background:
    linear-gradient(to bottom,
      rgba(0,0,0,.80) 0%,rgba(0,0,0,.34) 26%,transparent 46%),
    radial-gradient(46% 26% at 50% 45%,
      rgba(0,0,0,.62) 0%,rgba(0,0,0,.30) 60%,transparent 100%);
}
/* Szene 3: Textspalte links, die 20 rechts oben, Satz rechts unten */
#s3 .scrim{
  background:
    linear-gradient(to right,
      rgba(0,0,0,.80) 0%,rgba(0,0,0,.52) 34%,transparent 70%),
    linear-gradient(to left,
      rgba(0,0,0,.52) 0%,rgba(0,0,0,.20) 34%,transparent 62%);
}
/* Szene 4: Ueberschrift und Jahreszahl rechts.
   NUR von rechts abdunkeln. Ein zusaetzlicher Verlauf von unten
   deckte die Bildunterschrift ab, die auf der mid-Ebene liegt und
   damit TIEFER im Raum sitzt als der scrim — im preserve-3d-Raum
   gewinnt die Z-Position, nicht der z-index. Gemessen: Spitze der
   Unterschrift 109 mit, 155 ohne diesen Verlauf. Die Unterschrift
   bringt ihren eigenen Verlauf mit (.split__cap), sie braucht ihn
   hier nicht doppelt. */
#s4 .scrim{
  background:linear-gradient(to left,
    rgba(0,0,0,.78) 0%,rgba(0,0,0,.48) 34%,transparent 72%);
}
/* Szene 5: Ueberschrift oben, Preise in der Mitte, Ask und
   Schlusszeile unten — hier traegt die ganze Hoehe Schrift. */
#s5 .layer--text::before{
  content:"";
  position:absolute;left:0;right:0;top:0;height:62vh;
  z-index:-1;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(0,0,0,.80) 0%,rgba(0,0,0,.42) 40%,transparent 100%);
}
/* Ask und Schlusszeile liegen auf ZWEI verschiedenen Ebenen
   (hero z=7, outro z=6) auf derselben Z-Tiefe. Ein Verlauf ueber
   die ganze hero-Ebene deckte deshalb die Schlusszeile der
   outro-Ebene ab — gemessen: Spitze rgb(108,108,108) statt
   rgb(247,247,247). Die Abdunklung haengt darum am jeweiligen
   Textblock selbst, nicht an der Ebene. */
#s5 .ask::before,
#s5 .outro::before{
  content:"";
  position:absolute;
  left:-4vw;right:-4vw;top:-6vh;bottom:-6vh;
  z-index:-1;pointer-events:none;
  background:radial-gradient(72% 100% at 30% 50%,
    rgba(0,0,0,.78) 0%,rgba(0,0,0,.46) 58%,transparent 100%);
}
/* KEIN isolation:isolate hier — das wuerde einen Stapelkontext
   aufmachen und das z-index:-1 des ::before darin einsperren. */
/* WARUM Szene 5 KEINEN eigenen scrim traegt — gemessen 27.08.2026:
   Im preserve-3d-Raum entscheidet nicht der z-index, sondern die
   tatsaechliche Z-Position, welche Ebene vorne liegt. Der scrim
   sitzt auf translateZ(-0.25px), die fg-Ebene mit den Preisen auf
   translateZ(-1px) — der scrim ist also PHYSISCH naeher an der
   Kamera und deckt die Preise ab, ganz gleich welchen z-index man
   ihm gibt. Beleg: scrim ausgeblendet -> Gold springt von
   rgb(125,104,0) zurueck auf rgb(255,212,0).
   Deshalb traegt Szene 5 die Abdunklung nicht flaechig, sondern
   direkt an den Textbloecken, die sie braucht. */
#s5 .scrim{display:none}

/* Rueckhalt direkt an der Preistabelle. Kein Kasten: der Verlauf
   endet nach oben und unten im Nichts. */
#s5 .prices::before{
  content:"";
  position:absolute;
  left:calc(var(--pad) * -1);right:calc(var(--pad) * -1);
  top:-8vh;bottom:-6vh;
  z-index:-1;
  pointer-events:none;
  background:linear-gradient(to bottom,
    transparent 0%,rgba(0,0,0,.62) 26%,rgba(0,0,0,.66) 70%,transparent 100%);
}

/* =============================================================
   DUNST zwischen den Ebenen
   Ohne Dunst liest das Auge die Tiefe nicht. Zwei sehr schwache,
   fast schwarze Schichten: eine zwischen bg und mid, eine
   zwischen mid und fg. Reine Verlaeufe, kein blur().
   ============================================================= */
.haze{
  position:absolute;
  left:0;right:0;
  top:50%;height:100vh;margin-top:-50vh;
  pointer-events:none;
}
/* Dunst 1 — liegt hinter mid, vor bg. Traegt die groesste Tiefe,
   sitzt also fast so weit hinten wie bg. */
.haze--far{
  z-index:1;
  transform:translateZ(-2.5px) scale(3.5);   /* 1 + 2.5/1 = 3.5 */
  transform-origin:50% 50%;
  background:
    linear-gradient(to top,rgba(8,8,8,.85) 0%,rgba(6,6,6,.35) 38%,transparent 72%);
}
/* Dunst 2 — zwischen mid und fg, deutlich schwaecher. */
.haze--near{
  z-index:2;
  transform:translateZ(-1.5px) scale(2.5);   /* 1 + 1.5/1 = 2.5 */
  transform-origin:50% 50%;
  background:
    linear-gradient(to top,rgba(10,10,10,.62) 0%,rgba(8,8,8,.22) 44%,transparent 76%);
}

/* =============================================================
   REGEN — reine CSS-Streifen, kein Bild, kein Video
   ============================================================= */
.rain{
  position:absolute;inset:-10% -10% -10% -10%;
  pointer-events:none;
  background-repeat:repeat;
}
.rain--far{
  opacity:.16;
  background-image:repeating-linear-gradient(
    102deg,
    transparent 0 7px,
    rgba(255,255,255,.55) 7px 8px,
    transparent 8px 22px);
  background-size:auto;
  animation:rainFall 1.35s linear infinite;
}
.rain--mid{
  opacity:.26;
  background-image:repeating-linear-gradient(
    98deg,
    transparent 0 9px,
    rgba(255,255,255,.7) 9px 10.5px,
    transparent 10.5px 30px);
  animation:rainFall .78s linear infinite;
}
@keyframes rainFall{
  0%{background-position:0 0}
  100%{background-position:-120px 340px}
}

/* =============================================================
   TYPOGRAFIE — Industrie-Plakat
   ============================================================= */
.copy{
  position:absolute;
  padding:0 var(--pad);
}
.copy--left{left:0;top:8vh;width:min(560px,46vw)}
/* top:6vh reichte nicht: die Textebene sitzt perspektivisch etwas
   hoeher, und die Oberlaenge der ersten Zeile lief oben aus dem Bild
   ("DIE BAUSTELLE HAT" fehlte, es blieb "SICH GEAENDERT."). */
.copy--right{right:0;top:20vh;width:min(560px,46vw);text-align:right;margin-left:auto}
/* Wie bei .copy--right: die Textebene sitzt perspektivisch hoeher,
   deshalb braucht die erste Zeile Luft nach oben. Mit top:var(--pad)
   stand in Szene 5 nur noch "SUCHEN." im Bild. */
.copy--top{left:0;top:20vh;width:min(700px,60vw)}
/* Szene 5: dreizeilige Überschrift reicht von 20vh bis 41vh und lag damit
   über der ersten Preisspalte (.prices beginnt bei 34vh). Gemessen am
   Bildschirmfoto: "99 €" halb verdeckt, Symbol und "BASIS" ganz weg.
   Höher gesetzt statt Preise tiefer — oben war die Fläche leer. */
#s5 .copy--top{width:min(600px,52vw);top:3vh}
#s5 .copy--top .hl{font-size:clamp(30px,4.4vw,62px)}
#s4 .copy--right .hl{font-size:clamp(30px,4.4vw,66px)}

.hl{
  margin:0 0 .5em;
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(34px,5.6vw,86px);
  line-height:.90;
  letter-spacing:-.005em;
  text-transform:uppercase;
  color:#fff;
  text-shadow:0 2px 0 rgba(0,0,0,.9),0 0 28px rgba(0,0,0,.85);
  /* Verdichtung ueber die Schrift selbst, nicht ueber scaleX —
     scaleX schiebt den Text sonst ueber die Polsterung hinaus. */
  font-stretch:condensed;
}
.copy--right .hl{transform-origin:right center}
.copy--top .hl{transform-origin:left center}

.sub{
  margin:0;
  max-width:44ch;
  font-size:clamp(13px,1.32vw,19px);
  line-height:1.62;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--grey-1);
  font-weight:500;
  text-shadow:0 1px 6px rgba(0,0,0,.95);
}

.quote{
  margin:1.6em 0 0;
  max-width:40ch;
  padding-left:18px;
  border-left:3px solid var(--gold);
  font-family:var(--face-cond);
  font-size:clamp(17px,2.05vw,30px);
  line-height:1.18;
  text-transform:uppercase;
  color:#fff;
  letter-spacing:.01em;
}
.quote cite{
  display:block;margin-top:.6em;
  font-family:var(--face-ui);
  font-size:clamp(11px,1.06vw,14px);
  font-style:normal;font-weight:500;
  letter-spacing:.12em;
  color:var(--grey-2);
}

/* ---------- Logo als Stempelkasten ---------- */
.logo{
  display:inline-block;
  margin-bottom:1.1em;
  padding:.30em .46em .22em;
  border:4px solid var(--gold);
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(19px,2.2vw,34px);
  line-height:.90;
  letter-spacing:.02em;
  text-transform:uppercase;
  color:var(--gold);
  font-stretch:condensed;
  transform:rotate(-1.4deg);
}
.logo--big{
  font-size:clamp(28px,3.6vw,60px);
  border-width:5px;
  margin-bottom:0;
}

/* =============================================================
   LEITZAHL — eigene, schnellste Ebene
   ============================================================= */
.bignum{
  position:absolute;
  display:flex;flex-direction:column;
  gap:.34em;
  padding:0 var(--pad);
  pointer-events:none;
}
.bignum__v{
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(76px,15.5vw,264px);
  line-height:.80;
  letter-spacing:-.02em;
  color:var(--gold);
  text-shadow:0 6px 0 rgba(0,0,0,.55),0 0 60px rgba(255,212,0,.16);
  font-stretch:condensed;
}
.bignum__v i{
  font-style:normal;
  font-size:.44em;
  margin-left:.10em;
  vertical-align:.34em;
}
.bignum__v--date{
  font-size:clamp(40px,7.6vw,132px);
  letter-spacing:-.012em;
}
.bignum__k{
  font-family:var(--face-ui);
  font-size:clamp(11px,1.18vw,17px);
  font-weight:600;
  line-height:1.5;
  letter-spacing:.15em;
  text-transform:uppercase;
  color:#fff;
  text-shadow:0 1px 8px rgba(0,0,0,.95);
}
.bignum__k em{
  display:inline-block;margin-top:.28em;
  font-style:normal;font-weight:500;
  letter-spacing:.1em;
  color:var(--grey-2);
  text-transform:none;
}

/* Positionen je Szene.
   Jede Leitzahl bekommt ein eigenes Feld, das sich mit der
   Textspalte derselben Szene nicht schneidet. Ohne Breitenbegrenzung
   spannt der Block sonst ueber die ganze Buehne und laeuft in den Text. */

/* Szene 1: Zahl unten links, Text darueber, Telefon rechts.
   Die Zahl ist kleiner als in Szene 2/3, weil hier eine
   Textspalte darueber steht. */
.bignum--s1{
  left:var(--pad);bottom:7vh;
  width:min(620px,52vw);
  text-align:left;align-items:flex-start;
  padding-right:0;
}
.bignum--s1 .bignum__v{font-size:clamp(64px,10.5vw,180px)}
.bignum--s1 .bignum__v,.bignum--s1 .bignum__k{text-align:left}

/* Szene 2: Zahl mittig im mittleren Panel */
.bignum--s2{
  left:50%;top:46%;
  width:min(34ch,32vw);
  transform:translate(-50%,-50%);
  text-align:center;align-items:center;
  padding:0;
}
.bignum--s2 .bignum__k{text-align:center}

/* Szene 3: die 20 rechts oben, Textspalte links bleibt frei */
.bignum--s3{
  right:var(--pad);top:8vh;
  width:min(30ch,34vw);
  text-align:right;align-items:flex-end;
  padding-left:0;
}
.bignum--s3 .bignum__v{font-size:clamp(96px,17vw,240px)}
.bignum--s3 .bignum__k{text-align:right}

/* Szene 4: Jahreszahl rechts unterhalb der Ueberschrift */
.bignum--s4{
  right:var(--pad);top:52vh;
  width:min(560px,46vw);
  text-align:right;align-items:flex-end;
  padding-left:0;
}
.bignum--s4 .bignum__k{text-align:right}
.bignum--s4 .bignum__v{font-size:clamp(34px,5.6vw,96px)}

/* =============================================================
   SZENE 1 — Telefon
   ============================================================= */
.phone-wrap{
  position:absolute;
  right:calc(var(--pad) + 1vw);
  top:6vh;
  width:clamp(186px,17vw,268px);
  text-align:center;
}
.phone{
  position:relative;
  border:3px solid var(--grey-2);
  border-radius:26px;
  background:#000;
  padding:9px 7px 13px;
  box-shadow:0 0 0 1px rgba(0,0,0,1),0 24px 50px rgba(0,0,0,.9);
}
.phone__notch{
  width:38%;height:15px;margin:0 auto 8px;
  background:#000;border:2px solid var(--grey-3);
  border-top:0;border-radius:0 0 12px 12px;
}
.phone__screen{
  border:1px solid var(--grey-4);
  background:#0a0a0a;
  border-radius:14px;
  overflow:hidden;
}
.phone__hdr{
  display:flex;align-items:center;gap:8px;
  padding:8px 10px;
  border-bottom:1px solid var(--grey-4);
  background:#131313;
}
.phone__avatar{
  width:26px;height:26px;flex:0 0 26px;
  display:grid;place-items:center;
  border-radius:50%;
  background:var(--gold);color:#000;
  font-family:var(--face-cond);font-weight:700;font-size:11px;
  letter-spacing:.02em;
}
.phone__meta{display:flex;flex-direction:column;line-height:1.15;text-align:left}
.phone__meta b{font-size:11.5px;color:#fff;letter-spacing:.03em}
.phone__meta i{font-size:9px;font-style:normal;color:var(--grey-2);letter-spacing:.06em}

.phone__body{
  padding:10px 9px 14px;
  display:flex;flex-direction:column;gap:9px;
  background:
    repeating-linear-gradient(45deg,#0a0a0a 0 12px,#0d0d0d 12px 24px);
}
.bub{
  max-width:88%;
  padding:8px 10px;
  border-radius:9px;
  font-size:10.5px;
  line-height:1.42;
  color:#e8e8e8;
  text-align:left;
  border:1px solid var(--grey-4);
}
.bub--in{align-self:flex-start;background:#1a1a1a;border-top-left-radius:2px}
.bub--out{align-self:flex-end;background:#232323;border-top-right-radius:2px}
.bub b{display:block;margin-bottom:2px;font-size:11px;color:#fff;letter-spacing:.03em}
.bub__t{
  display:block;margin-top:5px;
  font-size:8.5px;letter-spacing:.05em;color:var(--grey-2);
}
.wave{display:flex;align-items:center;gap:2px;height:24px}
.wave i{
  display:block;width:2px;background:var(--grey-1);border-radius:1px;
}
.wave i:nth-child(3n){height:70%}
.wave i:nth-child(3n+1){height:38%}
.wave i:nth-child(3n+2){height:100%}
.wave i:nth-child(4n){height:52%}

.phone-cap{
  margin:12px 0 0;
  max-width:24ch;
  margin-left:auto;margin-right:auto;
  text-wrap:balance;
  font-size:clamp(10px,.94vw,13px);
  font-weight:600;
  letter-spacing:.15em;
  line-height:1.65;
  text-transform:uppercase;
  color:var(--grey-1);
  text-shadow:0 1px 6px rgba(0,0,0,.95);
}

/* =============================================================
   SZENE 2 — Triptychon
   ============================================================= */
.triptych{
  position:absolute;inset:0;
  display:grid;
  grid-template-columns:1fr 1fr 1fr;
}
/* Die Ebene skaliert beim Durchfliegen um bis zu 7 %. Dadurch wandern
   die aeusseren Panels ueber den Bildrand hinaus. Die Bildunterschriften
   bekommen deshalb einen Sicherheitsabstand nach aussen, damit der Satz
   auch im groessten Dolly-Moment vollstaendig im Bild bleibt. */
.panel:first-child .panel__cap{padding-left:clamp(46px,5.2vw,86px)}
.panel:last-child  .panel__cap{padding-right:clamp(46px,5.2vw,86px)}
.panel:first-child .panel__no{left:clamp(46px,5.2vw,86px)}
.panel{
  position:relative;
  margin:0;
  overflow:hidden;
  /* schraege weisse Schnittkante wie im Entwurfsbild */
  border-right:2px solid rgba(255,255,255,.14);
}
.panel:last-child{border-right:0}
.panel::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,rgba(0,0,0,.94) 0%,rgba(0,0,0,.25) 42%,transparent 62%);
}
.panel__no{
  position:absolute;left:clamp(14px,1.7vw,28px);top:24vh;
  z-index:3;
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(30px,3.6vw,62px);
  line-height:1;
  color:rgba(255,255,255,.34);
}
.panel__cap{
  /* Polsterung panel-relativ, nicht --pad: die Spalte ist nur ein
     Drittel breit, --pad wuerde den Satz nach aussen druecken. */
  position:absolute;left:0;right:0;bottom:7vh;
  z-index:3;
  padding:0 clamp(14px,1.7vw,28px);
  font-size:clamp(10px,.98vw,14px);
  line-height:1.6;
  letter-spacing:.11em;
  text-transform:uppercase;
  color:var(--grey-1);
}
.panel__cap b{
  display:block;margin-bottom:.6em;
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(19px,2.3vw,36px);
  letter-spacing:.02em;
  color:#fff;
}
.langs{display:inline-block;margin-top:.5em;color:var(--grey-2);letter-spacing:.2em}

/* =============================================================
   SZENE 3 — Warteschlange
   ============================================================= */
.queue{
  position:absolute;
  right:var(--pad);
  bottom:5vh;
  width:clamp(210px,25vw,380px);
}
.queue .art__svg{position:relative;inset:auto;height:auto}
.queue__cap{
  margin:14px 0 0;
  font-family:var(--face-cond);
  font-size:clamp(16px,1.9vw,28px);
  line-height:1.16;
  letter-spacing:.03em;
  text-transform:uppercase;
  color:#fff;
  text-align:right;
  text-shadow:0 1px 8px rgba(0,0,0,.95);
}

/* =============================================================
   SZENE 4 — Diagonale Teilung
   ============================================================= */
.split{position:absolute;inset:0}
.split__a{
  position:absolute;
  left:0;bottom:0;
  width:64%;height:78%;
  overflow:hidden;
  /* schwere linke untere Flaeche */
  clip-path:polygon(0 12%,100% 0,100% 100%,0 100%);
}
.split__b{
  position:absolute;
  right:0;top:0;
  width:56%;height:62%;
  overflow:hidden;
  clip-path:polygon(14% 0,100% 0,100% 100%,0 100%);
  opacity:.95;
}
.split__a .art__svg,.split__b .art__svg{position:absolute;inset:0}
.split__cap{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  margin:0;
  /* Der Streifen am unteren Rand ist rund 100px hoch —
     die Bildunterschrift endet darueber, nicht darunter. */
  padding:var(--pad) var(--pad) calc(var(--pad) + 110px);
  font-size:clamp(10px,1.06vw,15px);
  line-height:1.66;
  letter-spacing:.11em;
  text-transform:uppercase;
  /* Diese Unterschrift liegt auf der mid-Ebene, also tief im Raum
     und hinter Regen und Dunst. Mit --grey-1 kam sie nur auf eine
     Spitzenhelligkeit von 155. Reines Weiss plus ein dichterer
     Verlauf darunter heben sie auf Lesbarkeit. */
  color:#fff;
  text-shadow:0 1px 8px rgba(0,0,0,.95);
  background:linear-gradient(to top,
    rgba(0,0,0,.96) 0%,rgba(0,0,0,.82) 46%,rgba(0,0,0,.30) 78%,transparent 100%);
}
.split__cap b{
  display:block;margin-top:.5em;
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(17px,2.1vw,32px);
  letter-spacing:.02em;
  color:#fff;
}

.strip{
  position:absolute;
  left:0;right:0;bottom:0;
  margin:0;
  padding:calc(var(--pad) * .55) var(--pad);
  border-top:2px solid rgba(255,255,255,.2);
  background:rgba(0,0,0,.72);
  font-family:var(--face-cond);
  font-size:clamp(13px,1.66vw,26px);
  letter-spacing:.07em;
  text-transform:uppercase;
  color:#fff;
  text-align:center;
}

/* =============================================================
   SZENE 5 — Preise, Ask, Schlusszeile
   ============================================================= */
.prices{
  position:absolute;
  left:var(--pad);right:var(--pad);
  top:30vh;
  display:grid;
  grid-template-columns:1fr 1fr 1fr;
}
/* Die Figur mit der Laterne steht im rechten Viertel des Bildes (ab etwa
   x=1050 von 1440). Lief die Preiszeile ueber die volle Breite, stand die
   dritte Spalte auf dem Mantel der Figur — genau das, was BILDER-BRIEF.md
   fuer diese Szene ausschliesst ("die Preise brauchen Luft").
   Deshalb endet die Zeile hier vor der Figur. */
#s5 .prices,#s5 .prices__foot{right:31%}

.price{
  padding:0 clamp(14px,2vw,40px);
  border-right:1px solid rgba(255,255,255,.2);
  text-align:left;
}
.price:last-child{border-right:0}
.price__ico{
  display:block;width:clamp(38px,4vw,64px);margin-bottom:1.1em;
  color:var(--grey-2);
}
.price__name{
  display:block;margin-bottom:.34em;
  font-size:clamp(10px,1.02vw,14px);
  font-weight:700;letter-spacing:.28em;text-transform:uppercase;
  color:var(--grey-2);
}
.price__val{
  display:block;margin-bottom:.5em;
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(28px,4.2vw,72px);
  line-height:.94;
  letter-spacing:-.01em;
  text-transform:uppercase;
  color:#fff;
  font-stretch:condensed;
}
.price__val--gold{color:var(--gold)}
.price__val i{
  font-style:normal;
  font-size:.32em;
  letter-spacing:.14em;
  margin-left:.4em;
  color:var(--grey-2);
  vertical-align:.42em;
}
.price__meta{
  display:block;
  font-size:clamp(10px,.96vw,13px);
  line-height:1.6;letter-spacing:.13em;text-transform:uppercase;
  color:var(--grey-1);
}
.prices__foot{
  position:absolute;
  left:var(--pad);right:var(--pad);
  top:calc(30vh + clamp(146px,15vw,208px));
  margin:0;
  padding-top:1.2em;
  border-top:1px solid rgba(255,255,255,.14);
  font-size:clamp(10px,1vw,14px);
  font-weight:600;letter-spacing:.24em;text-transform:uppercase;
  color:var(--grey-2);
}

/* Der Ask liegt auf der hero-Ebene, die Preise auf fg — zwei
   verschiedene Tiefen, die gegeneinander wandern. Mit dem alten
   Wert (34vh + 244px) schob sich der Ask in die Preisspalten
   (gemessen: Ask 440..543, Preise 306..509). Er steht jetzt
   deutlich tiefer, unterhalb der Fusszeile der Preistabelle. */
/* Der Ask-Block lag ueber den Kleinzeilen der Preisspalten und ueber der
   Fusszeile — gemessen 28.08.2026: Ask 238-383, Preis-Kleinzeile 264-306,
   Fusszeile 312-346. Tiefer gesetzt, damit er unter der Fusszeile beginnt
   und vor dem Abbinder endet. */
.ask{
  position:absolute;
  left:var(--pad);right:var(--pad);
  top:90vh;
  /* 50ch brach die Ask-Zeile nach "300 IN" um und liess "12." allein
     stehen. Breiter, damit jede Zeile ganz bleibt. */
  max-width:min(68ch,48vw);
  text-align:left;
  padding-left:18px;
  border-left:4px solid var(--gold);
}
.ask__lbl{
  display:block;margin-bottom:.6em;
  font-size:clamp(10px,1vw,13px);
  font-weight:700;letter-spacing:.42em;text-transform:uppercase;
  color:var(--gold);
}
.ask__txt{
  margin:0;
  font-family:var(--face-cond);
  font-size:clamp(14px,1.6vw,25px);
  line-height:1.14;
  letter-spacing:.02em;
  text-transform:uppercase;
  color:#fff;
}

.outro{
  position:absolute;
  left:var(--pad);
  bottom:4vh;
  display:flex;align-items:flex-end;gap:clamp(18px,3vw,54px);
}
.claim{
  margin:0;
  font-family:var(--face-cond);
  font-weight:700;
  font-size:clamp(26px,4.6vw,80px);
  line-height:.92;
  letter-spacing:-.005em;
  text-transform:uppercase;
  color:#fff;
  font-stretch:condensed;
}

/* Abbinder-Szene: kuerzer als die Vollszenen, nur Logo + Claim.
   Der Abbinder braucht keine lange Kamerafahrt — er soll stehen, nicht
   durchgefahren werden. 120vh reichen, damit der Inhalt mittig im Bild
   liegt und kein leerer Nachlauf entsteht. */
.scene--abbinder{
  height:120vh;
}
/* Auf Mobil etwas mehr Luft, damit der Claim nicht abgeschnitten wird */
@media (max-width:880px){
  .scene--abbinder{height:160vh}
}

/* ---------- Abspann ----------
   #film ist position:fixed und deckt die ganze Flaeche. Ein Abspann im
   normalen Fluss beginnt deshalb bei y=0 und legte eine 140 px hohe
   schwarze Flaeche UEBER den Kopf jeder Szene — in Szene 3 schnitt sie
   die erste Zeile der Ueberschrift ab. Gemessen 27.08.2026:
   elementsFromPoint(150,130) meldete FOOTER.fin als oberstes Element.
   Er gehoert nach unten, schmal, ohne eigene Flaeche. */
.fin{
  position:fixed;
  left:0;right:0;bottom:0;
  z-index:10;
  padding:14px var(--pad) 10px;
  background:linear-gradient(to top,rgba(0,0,0,.8),rgba(0,0,0,0));
  text-align:center;
  pointer-events:none;
}
.fin p{
  margin:0;
  font-size:10px;letter-spacing:.22em;text-transform:uppercase;
  color:rgba(255,255,255,.32);
}

/* =============================================================
   MOBIL — weniger Ebenen, kleinere Spruenge, Wirkung bleibt
   ============================================================= */
@media (max-width:880px){
  :root{--scene-vh:280vh}

  .copy{max-width:none;width:100%}
  .copy--left,.copy--right{top:auto;bottom:auto;transform:none}
  .copy--left{top:12vh}
  .copy--right{top:10vh;text-align:left}
  .copy--right .hl{transform-origin:left center}

  .hl{font-size:clamp(34px,10.4vw,62px)}
  .sub{font-size:12.5px;letter-spacing:.07em}

  /* Szene 1: Telefon kleiner, unten rechts, Text darueber */
  .phone-wrap{
    right:auto;left:50%;top:auto;bottom:20vh;
    transform:translateX(-50%);
    width:min(52vw,220px);
  }
  .phone-cap{display:none}
  .bignum--s1{left:var(--pad);right:var(--pad);bottom:5vh;text-align:left;align-items:flex-start}
  .bignum--s1 .bignum__v,.bignum--s1 .bignum__k{text-align:left}
  .bignum__v{font-size:clamp(64px,23vw,130px)}
  .bignum__k{font-size:10.5px;letter-spacing:.1em}
  .bignum--s3 .bignum__v{font-size:clamp(78px,26vw,150px)}
  .bignum__v--date{font-size:clamp(34px,12vw,70px)}

  /* Szene 2 (Triptychon): Panels untereinander statt drei nebeneinander */
  .triptych{grid-template-columns:1fr;grid-template-rows:1fr 1fr 1fr}
  .panel{border-right:0;border-bottom:2px solid rgba(255,255,255,.14)}
  .panel:last-child{border-bottom:0}
  .panel__no{top:10px;left:14px;font-size:24px}
  .panel__cap{padding:14px;font-size:10px;letter-spacing:.07em}
  .panel__cap b{font-size:17px;margin-bottom:.35em}
  .bignum--s2{
    width:100%;padding:0 var(--pad);
    left:0;right:0;top:40%;
    transform:translateY(-50%);
    text-align:left;align-items:flex-start;
  }
  .bignum--s2 .bignum__k{text-align:left}
  /* gestapelte Panels: Satz oben, damit die Zahl darunter frei steht */
  .panel:first-child .panel__cap,
  .panel:last-child .panel__cap{padding-left:var(--pad);padding-right:var(--pad)}
  .panel:first-child .panel__no{left:var(--pad)}
  #s2 .panel:nth-child(2) .panel__cap{bottom:3vh}

  /* Szene 3 (Was 20 Chefs) */
  .queue{left:var(--pad);right:var(--pad);width:auto;bottom:5vh}
  .queue__cap{text-align:left;font-size:16px}
  .copy--left .quote{font-size:16px;margin-top:1.2em}

  /* Szene 4 */
  .split__a{width:100%;height:62%;clip-path:polygon(0 8%,100% 0,100% 100%,0 100%)}
  .split__b{width:88%;height:44%;opacity:.8}
  .split__cap{font-size:10px;letter-spacing:.07em;padding:14px var(--pad) 20px}
  .split__cap b{font-size:15px}
  .bignum--s4{left:var(--pad);right:var(--pad);top:auto;bottom:16vh;text-align:left;align-items:flex-start}
  .bignum--s4 .bignum__v{transform-origin:left center}
  .bignum--s4 .bignum__k{text-align:left;max-width:none}
  .strip{font-size:12px;padding:12px var(--pad)}

  /* Szene 5: Preise untereinander */
  .prices{top:20vh;grid-template-columns:1fr;gap:20px;right:var(--pad)}
  .prices__foot{right:var(--pad)}
  .price{
    border-right:0;padding:0 0 18px;
    border-bottom:1px solid rgba(255,255,255,.16);
  }
  .price:last-child{border-bottom:0}
  .price__ico{width:34px;margin-bottom:.5em}
  .price__val{font-size:34px}
  .prices__foot{top:auto;bottom:32vh;border-top:0;padding-top:0}
  .ask{
    left:var(--pad);right:var(--pad);max-width:none;bottom:20vh;
    text-align:left;padding-right:0;padding-left:16px;
    border-right:0;border-left:4px solid var(--gold);
  }
  .ask__txt{font-size:18px}
  .outro{gap:16px;bottom:4vh;align-items:center}
  .claim{font-size:28px}
  .logo--big{font-size:24px;border-width:4px}

  /* --- Mobil: jede Szene bekommt feste, getrennte Zonen --- */
  .copy--left,.copy--right,.copy--top{width:auto;left:0;right:0;max-width:none}
  .copy--left{top:7vh}
  .copy--right{top:6vh;text-align:left}
  #s5 .copy--top,#s4 .copy--right .hl{width:auto}

  /* --- HANDY-REPARATUR 28.08.2026 --- */

  /* Lese-Abdunklung: auf schmalen Schirmen kräftiger, damit weisser
     Text auf hellem Bildbereich erkennbar bleibt. */
  #s1 .scrim{
    background:linear-gradient(to right,
      rgba(0,0,0,.92) 0%,rgba(0,0,0,.78) 40%,rgba(0,0,0,.38) 72%,transparent 92%);
  }
  #s3 .scrim{
    background:
      linear-gradient(to bottom,
        rgba(0,0,0,.90) 0%,rgba(0,0,0,.60) 30%,transparent 54%),
      radial-gradient(46% 26% at 50% 45%,
        rgba(0,0,0,.70) 0%,rgba(0,0,0,.40) 60%,transparent 100%);
  }

  /* Szene 1: Titel oben, Telefon Mitte, Zahl unten.
     Leitzahl (24,9 %) auf dem Handy ausblenden — sie waere zu
     gross und schiebt sich in den Telefonbereich. */
  #s1 .layer--hero{display:none}
  .copy--left{top:7vh}
  .phone-wrap{bottom:26vh;width:min(46vw,190px)}

  /* Scroll-Hinweis: auf dem Handy kleiner, damit er nicht in
     die Ueberschrift hineinragt. */
  .scroll-cue__bar{height:28px}
  .scroll-cue{bottom:16px}

  /* Szene 2 ("Was 20 Chefs"): Überschrift oben, Zahl "20" in der
     Mitte, kein Zitat (zu beengt). Zahl kleiner damit kein Clash. */
  #s3 .copy--left{top:5vh}
  #s3 .quote{display:none}
  .bignum--s3{
    width:auto;left:0;right:0;top:auto !important;bottom:8vh;
    text-align:left;align-items:flex-start;
    padding:0 var(--pad);
  }
  .bignum--s3 .bignum__v{font-size:clamp(58px,19vw,110px)}
  .bignum--s3 .bignum__k{text-align:left}
  .queue{bottom:3vh;width:auto;left:var(--pad);right:var(--pad)}
  .queue .art__svg{max-height:22vh}
  .queue__cap{font-size:14px}

  /* Szene 3 ("Reinschicken. Verstehen. Sehen."):
     Die Ueberschrift copy--top sitzt auf derselben Ebene wie das
     Triptychon-Gitter. Auf dem Handy wird die Ueberschrift
     ausgeblendet — die drei Panel-Titel (Reinschicken / Verstehen /
     Sehen) sagen exakt dasselbe und sind direkt im Bild lesbar.
     Die Leitzahl (100 %) entfällt ebenfalls, weil kein Platz bleibt. */
  #s2 .layer--text{display:none}
  #s2 .layer--hero{display:none}

  /* Szene 4 (Abbinder): Logo und Claim in der Mitte des Schirms
     platzieren. Die Layer-Geometrie setzt bottom:4vh, aber die
     160vh-Szene ist zu kurz für die 125vh-Layer-Höhe — der Block
     läuft unten aus dem Sichtfenster. Lösung: outro oben verankern. */
  #s-abbinder .outro{
    bottom:auto;
    top:50%;
    transform:translateY(-50%);
    left:var(--pad);right:var(--pad);
    flex-direction:column;
    align-items:flex-start;
    gap:20px;
  }
  #s-abbinder .claim{font-size:clamp(28px,9vw,48px)}
  #s-abbinder .logo--big{font-size:clamp(22px,6vw,38px)}

  /* Weniger Regen-Ebenen auf schmalen Schirmen */
  .rain--far{display:none}
  .rain--mid{opacity:.2}
}

@media (max-width:520px){
  .quote cite{font-size:10px}
  .prices{top:16vh}
}

/* Kurze Schirme (Telefon quer) */
@media (max-height:560px) and (min-width:881px){
  .hl{font-size:clamp(30px,4.4vw,54px)}
  .bignum__v{font-size:clamp(60px,10vw,140px)}
}

/* =============================================================
   REDUZIERTE BEWEGUNG — saubere gestapelte Seite, kein Parallax
   ============================================================= */
@media (prefers-reduced-motion:reduce){
  /* Die Perspektive wird abgeschaltet: ohne perspective gibt es
     keine Parallaxe mehr, die Ebenen stapeln sich flach. */
  #film{
    position:static;
    inset:auto;
    overflow:visible;
    perspective:none;
    transform-style:flat;
  }
  .scene{height:auto !important;transform-style:flat}
  .scene__track{
    position:relative;
    inset:auto;
    height:auto;
    min-height:100vh;
    transform-style:flat;
    border-bottom:1px solid rgba(255,255,255,.12);
  }
  .scene__track::after{display:none}
  .scene__stage{
    position:relative;
    inset:auto;
    min-height:100vh;
    transform-style:flat;
  }
  .layer{
    transform:none !important;
    position:absolute;
    left:0;right:0;top:0;
    height:100%;
  }
  /* Randebenen und Dunst tragen ohne Bewegung nichts bei */
  .layer--edge,.haze{display:none !important}
  /* Auch die scrollgetriebene Querbewegung faellt weg */
  .layer--edge-l,.layer--edge-r{animation:none !important}
  .rain{animation:none;opacity:.12}
  .scroll-cue{display:none}
  .scroll-cue__bar i{animation:none}
}

/* Zusatzklasse, die app.js setzt, wenn Bewegung aus ist
   (deckt Browser ohne Media-Query-Unterstuetzung mit ab) */
body.no-motion #film{
  position:static;inset:auto;overflow:visible;
  perspective:none;transform-style:flat;
}
body.no-motion .scene{height:auto !important;transform-style:flat}
body.no-motion .scene__track{
  position:relative;inset:auto;height:auto;min-height:100vh;
  transform-style:flat;
  border-bottom:1px solid rgba(255,255,255,.12);
}
body.no-motion .scene__track::after{display:none}
body.no-motion .scene__stage{position:relative;inset:auto;min-height:100vh;transform-style:flat}
body.no-motion .layer{transform:none !important;position:absolute;left:0;right:0;top:0;height:100%}
body.no-motion .layer--edge,
body.no-motion .haze{display:none !important}
body.no-motion .layer--edge-l,
body.no-motion .layer--edge-r{animation:none !important}
body.no-motion .rain{animation:none;opacity:.12}
body.no-motion .scroll-cue{display:none}

/* =============================================================
   BILD-SLOTS
   Sobald echte Bilder unter assets/ liegen, greift die
   Hintergrundangabe und die CSS-Zeichnung tritt zurueck.
   Dateinamen exakt wie in BILDER-BRIEF.md.
   ============================================================= */
.layer[data-img]{
  background-position:center center;
  background-size:cover;
  background-repeat:no-repeat;
}
.layer.has-img > .art > .art__svg,
.layer.has-img > .art > .rain{opacity:0}
.layer.has-img{
  background-position:center center;
  background-size:cover;
  background-repeat:no-repeat;
}
/* Randebenen: liegt ein echtes Bild vor, tritt die SVG-Zeichnung
   zurueck, der Abdunkel-Verlauf bleibt aber stehen. */
.layer--edge.has-img > .edge-art > svg{opacity:0}
.layer--edge.has-img{background-size:cover;background-position:center center}

/* ------------------------------------------------------------------
   LESBARKEIT UEBER DEM BILD — Nachtrag 28.08.2026
   Seit die echten Noir-Bilder unter den Textspalten liegen, verlor der
   Fliesstext in Szene 4 den Kontrast: dunkelgrauer Text auf dunklem
   Bild. Die Ueberschriften hatten laengst einen Schatten, der
   Fliesstext nicht genug. Zwei Massnahmen, beide zurueckhaltend:
   1. Der Fliesstext wird eine Stufe heller und bekommt denselben
      harten Schatten wie die Ueberschrift.
   2. Hinter der Textspalte liegt ein weicher Verlauf, der nur dort
      abdunkelt, wo Text steht — das Bild daneben bleibt unberuehrt.
   ------------------------------------------------------------------ */
.sub{
  color:#d7d4cd;
  text-shadow:0 1px 0 rgba(0,0,0,.95), 0 0 14px rgba(0,0,0,.9);
}
.copy--left::before,
.copy--right::before,
.copy--top::before{
  content:'';
  position:absolute;
  inset:-3vh -2vw -4vh -2vw;
  z-index:-1;
  pointer-events:none;
  background:radial-gradient(120% 90% at 20% 40%, rgba(0,0,0,.72) 0%, rgba(0,0,0,.45) 45%, rgba(0,0,0,0) 78%);
}
.copy--right::before{
  background:radial-gradient(120% 90% at 80% 40%, rgba(0,0,0,.72) 0%, rgba(0,0,0,.45) 45%, rgba(0,0,0,0) 78%);
}
.copy{ isolation:isolate; }

/* =============================================================
   HANDY — GEOMETRIE GERADERUECKEN (28.08.2026)
   Befund, gemessen bei 390x844: Die Textebenen liegen in einem
   125vh hohen Koordinatensystem (top:50%, margin-top:-62.5vh),
   das fuer die Perspektiv-Parallaxe gebaut ist. Dadurch landete
   `top:7vh` nicht oben, sondern bei 655px — mitten im Telefonbild.
   Die Ueberschrift stand dadurch weiter unten am Rand, obwohl die
   Regel "oben" sagte.

   Auf schmalen Schirmen wird die Parallaxe deshalb abgeschaltet und
   die Ebenen werden gewoehnliche bildschirmhohe Kaesten. Lesbarkeit
   schlaegt Effekt — so vom Eigner entschieden.
   Am Laptop aendert sich nichts: die Regel greift erst unter 560px.
   ============================================================= */
@media (max-width:560px){
  #film{perspective:none}

  /* ALLE Ebenen zurueck auf gewoehnliche bildschirmhohe Kaesten.
     Die scale()-Vergroesserungen der Bildebenen (bis 4x) sind an die
     Perspektive gekoppelt — ohne sie zeigen sie nur einen Ausschnitt
     der Bildmitte. Deshalb hier ebenfalls neutralisiert. */
  .layer,
  .layer--bg,
  .layer--mid,
  .layer--fg,
  .layer--text,
  .layer--strip,
  .layer--outro,
  .layer--hero{
    left:0;
    right:0;
    top:0;
    height:100vh;
    margin-top:0;
    transform:none;
  }

  /* Die Korridor-Raender leben von der doppelten Geschwindigkeit.
     Ohne Parallaxe sind sie nur zwei Streifen, die Platz fressen. */
  .layer--edge{display:none}

  /* Bildmitte zeigen statt eines zufaelligen Streifens. */
  .art__svg,
  .art img{object-fit:cover;object-position:50% 50%}

  /* Die Panel-Beschriftung stand grau auf weissem Bildgrund und war
     nicht zu lesen. Auf dem Handy bekommt sie einen dunklen Grund. */
  .panel__cap{
    background:linear-gradient(to top,rgba(0,0,0,.94) 0%,rgba(0,0,0,.86) 62%,transparent 100%);
    padding-top:26px;
  }
  .panel__cap b{color:#fff}
  .panel__no{
    background:rgba(0,0,0,.8);
    padding:2px 8px;
  }
}
