/* ═══ 00-tokens.css ═════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN TOKENS
   Der einzige Block, den ein Re-Skin wirklich anfassen muss, ist BRAND.
   Alles darunter ist die Buehne, auf der jeder Pitch spielt.
   Client-Overrides kommen aus 99-client.css (generiert aus pitch.config.mjs).
   ═══════════════════════════════════════════════════════════════════════════ */

:root{

  /* ── Brand ────────────────────────────────────────────────────────────────
     --accent-rgb existiert, weil sich ein Hex-Token nicht alphaen laesst:
     rgba(var(--accent-rgb),.4) geht, rgba(var(--accent),.4) nicht.
     REGEL: Der Akzent ist nie eine Flaeche groesser als 16px. Nur color,
     stroke, border-color, Haarlinie oder Punkt. tools/lint-accent.mjs prueft das. */
  --accent:#E1051C;
  --accent-rgb:225,5,28;
  --accent-ink:#FFFFFF;

  /* ── Flaechen ─────────────────────────────────────────────────────────── */
  --bg:#07090B;                /* Seitengrund */
  --bg-2:#0C1116;              /* vertiefte Flaeche */
  --panel:#151A20;             /* Karten, Rahmen */
  --surface-deep:#04070A;      /* FPV-Buehne, Panel-Grund */
  --chrome:#10151A;            /* Browser-Titelleiste */
  --chrome-2:#0B0F13;          /* URL-Pille */
  --chrome-dot:#242C34;        /* Ampelpunkte */
  --device:#0A0D10;            /* Geraetekoerper */
  --device-ring:#0C1015;       /* Geraeterahmen */
  --device-screen:#0B0E12;     /* Geraetedisplay */
  --tile:#0F0F0F;              /* Video-Plattform-Grund */
  --tile-rgb:15,15,15;

  /* ── Schriftfarben ────────────────────────────────────────────────────── */
  --ink:#E8EDF2;
  --ink-rgb:232,237,242;
  --ink-2:#7C8B99;
  --ink-3:#4E5C69;
  --ink-screen:#F2F5F8;        /* Text auf einem Geraetedisplay */
  --ink-screen-2:#C3CCD5;
  --ink-screen-3:#8A97A4;
  --ink-screen-4:#6C7986;
  --line:rgba(var(--ink-rgb),.10);
  --line-strong:rgba(255,255,255,.14);

  /* ── Raster ───────────────────────────────────────────────────────────── */
  --pad:clamp(24px,5vw,90px);
  --wrap:1240px;

  /* ── Radien ───────────────────────────────────────────────────────────── */
  --r-1:3px;                   /* Bildrahmen, Tags */
  --r-2:4px;                   /* FPV-Panel */
  --r-3:10px;                  /* Fenster */
  --r-4:38px;                  /* Telefon */
  --r-pill:100px;

  /* ── Schatten ─────────────────────────────────────────────────────────── */
  --sh-lift:0 50px 90px -30px rgba(0,0,0,.95);
  --sh-panel:0 50px 110px -40px rgba(0,0,0,.95);
  --sh-wide:0 60px 120px -50px rgba(0,0,0,.9);
  --sh-tall:0 50px 100px -50px rgba(0,0,0,.95);

  /* ── Bewegung ─────────────────────────────────────────────────────────── */
  --ease:cubic-bezier(.16,1,.3,1);
  --t-1:.12s;                  /* Fortschrittsbalken */
  --t-2:.4s;                   /* Hover */
  --t-3:.6s;                   /* Zustandswechsel */
  --t-4:.7s;
  --t-5:1s;                    /* Linien, die aufziehen */
  --t-6:2.2s;                  /* Schleier, der zur Seite zieht */
  --t-7:2.4s;                  /* langsamster Zug: Bild faehrt aus dem Rahmen */

  /* ── Ebenen ───────────────────────────────────────────────────────────── */
  --z-below:-1;
  --z-base:1;
  --z-cap:2;
  --z-progress:90;

  /* ── Die Storytelling-Uhr ─────────────────────────────────────────────────
     Scrollweg je Kapitel. Ein Kapitel ist so hoch, wie seine Geschichte
     dauert — die sticky Buehne darin bleibt immer 100vh. Wer das Tempo eines
     Pitches aendern will, aendert diese sieben Zeilen und sonst nichts. */
  --h-hero:170vh;
  --h-shots:230vh;             /* laengstes Kapitel: zwei Entwuerfe teilen sich den Weg */
  --h-devices:160vh;
  --h-rail:170vh;
  --h-voice:108vh;
  --h-layers:108vh;
  --h-close:118vh;

  /* ── Typografie ───────────────────────────────────────────────────────── */
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --font-display:var(--font);  /* ein Client darf hier auf einen Webfont zeigen */

  /* ── Client-abhaengig ─────────────────────────────────────────────────────
     Werte, die frueher als Asset-Pfad im CSS standen. Sie werden pro Client
     gesetzt — im generierten 99-client.css oder inline am Element. */
  --tex-image:none;            /* Hintergrundtextur in freien Zonen */
  --tex-opacity:.035;
  --shot-ratio:16/9;           /* Seitenverhaeltnis der Website-Screenshots */
  --shot-ratio-w:16;
  --shot-ratio-h:9;
  --screen-ref:224px;          /* Bezugsbreite der cqw-Werte im Geraetedisplay */
}

/* ═══ 01-base.css ═══════════════════════════════════════════════ */
/* ═══ Reset + Grundlagen ═══════════════════════════════════════════════════ */

*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,video{display:block;max-width:100%;}
ul,ol{margin:0;padding:0;list-style:none;}
h1,h2{margin:0;font-family:var(--font-display);font-weight:650;letter-spacing:-.03em;line-height:1.02;}
p{margin:0;}
a{color:inherit;text-decoration:none;}
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ═══ 02-chrome.css ═════════════════════════════════════════════ */
/* ═══ Seiten-Chrome: Fortschrittsbalken + Wellen-Canvas ════════════════════ */

.progress{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:var(--z-progress);
  background:rgba(255,255,255,.05);
}
.progress i{display:block;height:100%;width:0;background:var(--accent);transition:width var(--t-1) linear;}

/* Ein einziges Fullscreen-Canvas hinter allem. Die Deckkraft steuert die
   Engine aus den data-waves-Werten der Sektionen. */
.waves{
  position:fixed;inset:0;width:100%;height:100%;
  z-index:0;pointer-events:none;opacity:0;
  /* Textschutz: die Mitte wird gedaempft, nicht ausgeraeumt — sonst fehlt der
     Effekt genau dort, wo hingeschaut wird. */
  -webkit-mask-image:radial-gradient(ellipse 62% 52% at 50% 50%,
    rgba(0,0,0,.42) 0%,rgba(0,0,0,.72) 56%,rgba(0,0,0,1) 100%);
  mask-image:radial-gradient(ellipse 62% 52% at 50% 50%,
    rgba(0,0,0,.42) 0%,rgba(0,0,0,.72) 56%,rgba(0,0,0,1) 100%);
}

/* ═══ 03-layout.css ═════════════════════════════════════════════ */
/* ═══ Layout-Grundbausteine ════════════════════════════════════════════════
   Zwei Sorten Sektion:
   .chapter — hoher Block mit sticky .stage darin. Der Scrollweg IST die Zeit.
   .section — normaler Fluss, Inhalt kommt beim Eintreten hoch (.reveal).
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter{position:relative;z-index:var(--z-base);}
.stage{position:sticky;top:0;height:100vh;overflow:hidden;}
/* safe center: laeuft der Inhalt einmal ueber, wird unten beschnitten statt
   oben — die Ueberschrift bleibt damit in jedem Fall lesbar. */
.stage--pad{
  display:flex;flex-direction:column;justify-content:safe center;
  gap:clamp(20px,3vh,42px);padding:calc(var(--pad) * .8) var(--pad);
}

.section{padding:clamp(90px,14vh,190px) var(--pad);position:relative;z-index:var(--z-base);}
.section--tight{padding:clamp(58px,8.5vh,120px) var(--pad);}
.section--flat{padding:clamp(40px,5.5vh,72px) var(--pad);}
.section--statement{min-height:80vh;display:flex;align-items:center;}
.wrap{max-width:var(--wrap);margin:0 auto;width:100%;}

/* Sehr schwache Textur in freien Zonen — bricht das flache Schwarz.
   Das Bild kommt aus --tex-image, nicht mehr aus einem festen Pfad. */
.section--tex::before{
  content:"";position:absolute;inset:0;z-index:var(--z-below);pointer-events:none;
  background-image:var(--tex-image);
  background-position:center;background-size:cover;background-repeat:no-repeat;
  opacity:var(--tex-opacity);
}
/* Duenne, auslaufende Trennlinie an der Sektionsnaht */
.section--seam::after{
  content:"";position:absolute;left:var(--pad);right:var(--pad);bottom:0;height:1px;
  background:linear-gradient(90deg,
    rgba(var(--ink-rgb),0),rgba(var(--ink-rgb),.14) 30%,
    rgba(var(--ink-rgb),.14) 70%,rgba(var(--ink-rgb),0));
}

.foot{
  position:relative;z-index:var(--z-base);
  display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  padding:34px var(--pad);border-top:1px solid var(--line);
  font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);
  background:var(--bg);
}

/* ═══ 04-type.css ═══════════════════════════════════════════════ */
/* ═══ Typografie ═══════════════════════════════════════════════════════════
   Zwei gegenlaeufige Familien, konsequent angewandt:
   Ueberschriften ziehen zusammen (-.03em bis -.01em),
   Labels ziehen auseinander (.04em bis .5em).
   ═══════════════════════════════════════════════════════════════════════════ */

.eyebrow{
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-2);font-weight:600;margin-bottom:18px;
}
.eyebrow::before{
  content:"";display:inline-block;width:16px;height:1px;
  background:var(--accent);vertical-align:middle;margin-right:12px;
}
/* Eyebrow ohne Strich — auf zentrierten Buehnen sitzt er sonst schief */
.eyebrow--bare::before{display:none;}

.h-xl{font-size:clamp(34px,6.4vw,94px);}
.h-lg{font-size:clamp(30px,5.2vw,70px);}
.h-md{font-size:clamp(22px,3.2vw,40px);line-height:1.1;}

.lead{
  font-size:clamp(22px,3.3vw,46px);line-height:1.14;letter-spacing:-.025em;
  font-weight:600;margin-bottom:18px;
}
.statement{font-size:clamp(26px,4.4vw,60px);line-height:1.12;}
.statement .line{display:block;}
.statement .l2{transition-delay:.18s !important;}
.statement .l3{transition-delay:.34s !important;}

.muted{color:var(--ink-2);}
.body{color:var(--ink-2);font-size:clamp(15px,1.25vw,18px);line-height:1.6;max-width:46ch;margin-top:20px;}
.body--wide{max-width:60ch;}
.body--wide{margin-top:36px;}

/* Konzept-Hinweise. In einem Pitch werden fremde Marken dargestellt —
   diese beiden Bausteine sagen sichtbar, dass es Entwuerfe sind. */
.concept-tag{
  margin-left:auto;font-size:9px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3);border:1px solid var(--line);padding:4px 9px;border-radius:var(--r-1);
}
.concept-note{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);}

/* ═══ 05-motion.css ═════════════════════════════════════════════ */
/* ═══ Bewegung ═════════════════════════════════════════════════════════════
   Zwei Mechaniken, mehr braucht das System nicht:
   1 .reveal    — Sektion tritt ein, Kinder kommen gestaffelt hoch (IO)
   2 .on        — Engine schaltet ein Element scharf (Scroll oder Stagger)
   Die komplette Choreografie liegt in CSS. JS setzt nur Klassen.
   ═══════════════════════════════════════════════════════════════════════════ */

.reveal [class*="eyebrow"],
.reveal h2,.reveal .body,.reveal li,
.reveal .media-frame,.reveal .close-text,.reveal .cta-row,
.reveal .about-role,.reveal .basis-text,.reveal .close-tags,.reveal .copy-line{
  opacity:0;transform:translateY(20px);
  transition:opacity var(--t-3) var(--ease),transform .75s var(--ease);
}
.reveal.is-in [class*="eyebrow"],
.reveal.is-in h2,.reveal.is-in .body,.reveal.is-in li,
.reveal.is-in .media-frame,
.reveal.is-in .close-text,.reveal.is-in .cta-row,
.reveal.is-in .about-role,.reveal.is-in .basis-text,
.reveal.is-in .close-tags,.reveal.is-in .copy-line{
  opacity:1;transform:none;
}
.reveal.is-in h2{transition-delay:.04s;}
.reveal.is-in .about-role{transition-delay:.06s;}
.reveal.is-in .body{transition-delay:.08s;}

/* Auftakt-Staffel fuer den Hero-Copy-Block */
.d1,.d2,.d3,.d4{opacity:0;transform:translateY(18px);animation:fadeUp 1.2s var(--ease) forwards;}
.d1{animation-delay:.25s;} .d2{animation-delay:.6s;}
.d3{animation-delay:.95s;} .d4{animation-delay:1.3s;}
@keyframes fadeUp{to{opacity:1;transform:none;}}

/* ═══ 10-fx-hero.css ════════════════════════════════════════════ */
/* ═══ FX · HERO ════════════════════════════════════════════════════════════
   Kamera faehrt in ein Bild hinein, die Wortmarke steht als Partikelfeld im
   Fluchtpunkt, am Ende loest sich alles auf und gibt die dunkle Flaeche frei.
   Das Bild kommt inline vom Element (style="background-image:url(...)"),
   nicht aus dieser Datei — es ist Inhalt, kein Theme.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--hero{height:var(--h-hero);}

.hero-bg{
  position:absolute;inset:0;
  background-position:center;background-size:cover;background-repeat:no-repeat;
  transform-origin:50% 46%;will-change:transform,opacity;
  filter:blur(9px) brightness(.72);
}
/* Zweite, scharfe Ebene: die Schaerfe wird eingeblendet statt pro Frame neu
   berechnet — reiner Compositor-Job statt Repaint. */
.hero-bg--sharp{filter:brightness(.92);opacity:0;will-change:transform,opacity;}

.hero-vig{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 62% 62% at 50% 46%,
    rgba(6,10,14,0) 0%,rgba(5,8,11,.58) 60%,rgba(3,5,7,.96) 100%);
}
.hero-canvas{position:absolute;inset:0;width:100%;height:100%;}
.hero-canvas--calm{opacity:.85;}

.hero-copy{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(34px,7.5vh,92px);
  text-align:center;pointer-events:none;
}
.hero-copy .lead{margin-bottom:18px;}
.hero-copy .eyebrow{margin-bottom:24px;}
.hero-sub{
  font-size:clamp(9px,.92vw,12px);letter-spacing:.3em;text-transform:uppercase;
  color:var(--ink-2);margin-bottom:30px;
}

/* Steht mittig auf halber Hoehe, waehrend der Dive laeuft — die Zeile, die
   die Marke in drei Worten setzt. */
.brand-label{
  position:absolute;left:0;right:0;top:50%;text-align:center;
  font-size:clamp(10px,.95vw,13px);letter-spacing:.5em;text-transform:uppercase;
  color:var(--ink-2);opacity:0;transition:opacity .8s var(--ease);pointer-events:none;
}

/* ═══ 11-fx-shots.css ═══════════════════════════════════════════ */
/* ═══ FX · SHOTS ═══════════════════════════════════════════════════════════
   N Website-Entwuerfe im selben Fenster. Der Scroll blendet sie ineinander,
   nicht eine Laufzeit — deshalb kann man anhalten und vergleichen.
   Traegt zwei Sections: WEB-SHOWROOM (2 Entwuerfe) und WEB-STORY (5 Screens).
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--shots{height:var(--h-shots);}

/* Zwei Gattungen nebeneinander, nicht zwei Urteile. Aktiv ist immer die
   Spalte, deren Entwurf gerade im Fenster steht. */
.compare{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:clamp(12px,2.2vw,32px);margin-top:clamp(18px,2.6vh,32px);
}
.compare-col{flex:1;min-width:210px;}
.compare-label{
  display:block;font-size:9px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:7px;
}
.compare-col b{
  display:block;font-size:clamp(11px,1vw,14px);font-weight:500;
  letter-spacing:.02em;line-height:1.5;color:var(--ink-3);
}
.compare-label,.compare-col b{transition:color var(--t-3) var(--ease);}
.compare-col.is-on .compare-label{color:var(--accent);}
.compare-col.is-on b{color:var(--ink);}
.compare-arrow{color:var(--accent);font-size:17px;line-height:1;}

/* Fensterbreite folgt der zulaessigen Hoehe, damit der Entwurf im Seiten-
   verhaeltnis der Vorlage sitzt und nichts beschnitten wird. */
.browser-scene{--shot-h:min(48vh,460px);}
.browser{
  width:min(1080px,100%,calc(var(--shot-h) * var(--shot-ratio-w) / var(--shot-ratio-h)));
  margin:0 auto;
  border:1px solid var(--line);border-radius:var(--r-3);overflow:hidden;
  background:var(--panel);
  box-shadow:var(--sh-wide);
  transform-origin:50% 40%;will-change:transform;
}
.browser-bar{
  display:flex;align-items:center;gap:7px;padding:11px 14px;
  background:var(--chrome);border-bottom:1px solid var(--line);
}
.browser-bar i{width:9px;height:9px;border-radius:50%;background:var(--chrome-dot);}
.browser-bar .url{
  margin-left:14px;font-size:11px;color:var(--ink-3);letter-spacing:.06em;
  background:var(--chrome-2);padding:5px 14px;border-radius:var(--r-pill);
}
.browser-view{position:relative;aspect-ratio:var(--shot-ratio);overflow:hidden;background:var(--bg-2);}

/* Die Entwuerfe liegen deckungsgleich uebereinander; der Scroll blendet sie
   ineinander und schiebt sie leicht gegeneinander. */
.shot{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.08);will-change:opacity,transform;
}
/* Der erste Entwurf steht, bevor die Engine den ersten Frame schreibt —
   sonst blitzt beim Laden ein leeres Fenster auf. */
.shot:first-of-type{opacity:1;transform:scale(1.02);}
/* Ein Entwurf darf einen eigenen Grade tragen, wenn er aus einer helleren
   Vorlage kommt — inline per style="--grade:..." am Element. */
.shot--graded{filter:var(--grade,none);}

/* Statisch weichgezeichnete Kopie des aktiven Entwurfs: nur die Deckkraft
   wird animiert, der Blur selbst wird einmal gerastert. Das Bild setzt die
   Engine zur Laufzeit aus dem currentSrc des ersten Shots. */
.shot-blur{
  position:absolute;inset:-4%;pointer-events:none;opacity:0;
  background-position:center;background-size:cover;background-repeat:no-repeat;
  filter:blur(18px) brightness(.9);will-change:opacity;
}
.shot-vig{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 82% 82% at 50% 45%,
    rgba(4,6,9,0) 42%,rgba(4,6,9,.36) 100%);
}
.shot-label{
  margin-top:14px;text-align:center;
  font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3);
}

/* ═══ 12-fx-devices.css ═════════════════════════════════════════ */
/* ═══ FX · DEVICES ═════════════════════════════════════════════════════════
   Zwei Geraete, eine Kamerafahrt. Das zweite wird gespiegelt gefahren, damit
   sich beide zur Mitte hin oeffnen. Die Oberflaechen darin sind live gebaut —
   keine Screenshots mit erfundenen Kennzahlen.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--devices{height:var(--h-devices);}

.phone-scene{
  flex:1;display:grid;grid-template-columns:auto auto;
  gap:clamp(24px,4.5vw,72px);align-items:center;justify-content:center;
  perspective:1500px;perspective-origin:50% 45%;min-height:0;
}

/* ── Geraet 1 · Telefon ──────────────────────────────────────────────────
   Hoehe fuehrt, Breite folgt — so passt das Geraet auch auf kurze Viewports,
   ohne dass die Buehne den Fuss abschneidet. */
.phone{
  position:relative;height:min(46vh,460px);width:auto;aspect-ratio:9/19.5;
  max-width:40vw;transform-style:preserve-3d;will-change:transform;
}
.phone-body{
  position:absolute;inset:0;border-radius:var(--r-4);overflow:hidden;
  background:var(--device);border:1px solid var(--line-strong);
  box-shadow:0 0 0 8px var(--device-ring),var(--sh-lift);
}
/* Die Oberflaeche darin wird AM GERAET gemessen (cqw), nicht in festen Pixeln
   — sonst laeuft der Profilname aus dem Bildschirm, sobald das Telefon
   schmaler wird. Bezugsbreite ist --screen-ref (224px): fuer diese Groesse
   waren die Werte unten gesetzt. */
.phone-screen{
  position:absolute;inset:0;overflow:hidden;
  background:var(--device-screen);color:var(--ink-screen);
  container-type:inline-size;
}
.phone-glare{
  position:absolute;inset:0;border-radius:var(--r-4);pointer-events:none;
  background:linear-gradient(115deg,rgba(255,255,255,.16) 0%,rgba(255,255,255,0) 34%,
             rgba(255,255,255,0) 66%,rgba(255,255,255,.07) 100%);
  will-change:opacity;
}
.phone-shadow{
  position:absolute;left:8%;right:8%;bottom:-38px;height:36px;border-radius:50%;
  background:radial-gradient(ellipse,rgba(0,0,0,.7),rgba(0,0,0,0) 70%);
  filter:blur(9px);
}

/* ── Geraet 2 · Plattform-Fenster ────────────────────────────────────────
   Nicht das Geraet, sondern die Bildflaeche traegt das Seitenverhaeltnis der
   Vorlage — sonst frisst die Leiste Hoehe und der Kanal wird unten
   beschnitten. Die Breite wird deshalb aus der Zielhoehe minus Leiste
   gerechnet. */
.yt{
  --yt-bar:34px;
  position:relative;
  width:min(56vw,calc((min(38vh,380px) - var(--yt-bar)) * var(--shot-ratio-w) / var(--shot-ratio-h)));
  max-width:100%;transform-style:preserve-3d;will-change:transform;
}
.yt-body{
  position:relative;border-radius:var(--r-3);overflow:hidden;
  background:var(--tile);border:1px solid rgba(255,255,255,.12);
  box-shadow:var(--sh-lift);
}
.yt-body .browser-bar{height:var(--yt-bar);padding:0 12px;flex:none;}
.yt-body .browser-bar .url{margin-left:11px;font-size:9.5px;padding:4px 11px;}
.yt-screen{position:relative;aspect-ratio:var(--shot-ratio);overflow:hidden;}
.yt-screen img{width:100%;height:100%;object-fit:cover;}
.yt-glare{border-radius:var(--r-3);opacity:.4;}

/* Blenden ueber den Thumbnails. Position und Groesse kommen inline vom
   Element (--x/--y/--w/--h) — am jeweiligen Screenshot gemessen. Dadurch
   funktioniert der Effekt mit beliebig vielen Kacheln. */
.yt-tiles{position:absolute;inset:0;pointer-events:none;}
.yt-tiles i{
  position:absolute;
  left:var(--x);top:var(--y,70.2%);width:var(--w,17.9%);height:var(--h,18.6%);
  background:var(--tile);
  opacity:1;transition:opacity var(--t-4) var(--ease);
}
.yt-tiles i.on{opacity:0;}
/* Deckt Titelzeile, Aufrufzahlen und Datum zu — Konzeptbild, keine realen
   Kennzahlen, also wird die Zeile ausgeblendet. */
.yt-fade{
  position:absolute;left:0;right:0;bottom:0;height:var(--tile-fade-h,11.5%);pointer-events:none;
  background:linear-gradient(180deg,
    rgba(var(--tile-rgb),0) 0%,rgba(var(--tile-rgb),.96) 18%,var(--tile) 32%);
}

/* ── Kanalliste unter beiden Geraeten ────────────────────────────────────
   Ein Kanal ist kein System. Vier abgestimmte Kanaele sind eines. */
.channels-block{width:100%;max-width:1000px;margin:0 auto;text-align:center;}
.channels-lead{
  font-size:clamp(13px,1.15vw,16px);line-height:1.5;color:var(--ink-2);
  margin-bottom:clamp(12px,1.8vh,20px);
}
.channels{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 clamp(16px,2.4vw,34px);}
.channels li{
  display:flex;flex-direction:column;gap:4px;align-items:center;
  padding:clamp(8px,1.2vh,13px) 0;border-top:1px solid var(--line);
  opacity:0;transform:translateY(14px);
  transition:opacity var(--t-3) var(--ease),transform var(--t-4) var(--ease);
}
.channels li.on{opacity:1;transform:none;}
.channels b{font-size:clamp(12px,1.1vw,15px);letter-spacing:-.01em;}
.channels span{font-size:clamp(10px,.85vw,12px);color:var(--ink-3);letter-spacing:.04em;line-height:1.4;}
.channels-block .concept-note{display:block;margin-top:clamp(10px,1.6vh,18px);}

/* ── Profil-Oberflaeche im Telefon ───────────────────────────────────────
   Alle Groessen in cqw gegen --screen-ref. Nicht auf px umstellen. */
.ig-head{display:flex;align-items:center;gap:5.4cqw;padding:9.8cqw 7.1cqw 4.5cqw;}
.ig-avatar{width:20.5cqw;height:20.5cqw;border-radius:50%;object-fit:cover;border:1px solid rgba(255,255,255,.15);}
.ig-id{min-width:0;}
.ig-id b{display:block;font-size:5.6cqw;letter-spacing:.01em;}
.ig-id span{font-size:4.7cqw;color:var(--ink-screen-3);}
.ig-bio{padding:0 7.1cqw 6.3cqw;font-size:4.7cqw;line-height:1.55;color:var(--ink-screen-2);}
.ig-tabs{display:flex;gap:8.9cqw;padding:0 7.1cqw 4.5cqw;border-bottom:1px solid rgba(255,255,255,.09);}
.ig-tabs b,.ig-tabs span{font-size:4.2cqw;letter-spacing:.14em;text-transform:uppercase;padding-bottom:4cqw;}
.ig-tabs b{border-bottom:1px solid #fff;}
.ig-tabs span{color:var(--ink-screen-4);}
.ig-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;padding:2px;}
.ig-grid i{
  display:block;aspect-ratio:1;background-size:cover;background-position:center;
  opacity:0;transform:scale(.9);
  transition:opacity var(--t-4) var(--ease),transform .8s var(--ease);
}
.ig-grid i.on{opacity:1;transform:none;}

/* ═══ 13-fx-rail.css ════════════════════════════════════════════ */
/* ═══ FX · RAIL ════════════════════════════════════════════════════════════
   N Hochformat-Panels laufen als durchgehende Schiene durch die Mitte.
   Das naechstliegende Panel spielt sein Video, sein Poster fuellt unscharf
   den Hintergrund, seine Aussagezeile steht unten. Ein Bewegungsvokabular
   fuer Film, FPV, Aerial, 360 — was der Client eben liefert.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--rail{height:var(--h-rail);}
.chapter--rail .stage{background:var(--surface-deep);}

/* Unscharf skalierte Kopie fuellt die Breite, ohne das Hochformat zu beschneiden */
.fpv-blur{
  position:absolute;inset:-8%;background-size:cover;background-position:center;
  filter:blur(46px) brightness(.34) saturate(.7);
  transition:background-image var(--t-2) linear;will-change:transform;
}
.fpv-rail{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;}
.fpv-panel{
  position:absolute;margin:0;height:min(58vh,580px);aspect-ratio:9/16;
  border-radius:var(--r-2);overflow:hidden;background:var(--surface-deep);
  border:1px solid rgba(255,255,255,.09);
  box-shadow:var(--sh-panel);
  will-change:transform,opacity;
}
.fpv-panel video{width:100%;height:100%;object-fit:cover;}
.fpv-panel figcaption{
  position:absolute;left:16px;bottom:14px;font-size:10px;
  letter-spacing:.22em;text-transform:uppercase;color:rgba(255,255,255,.72);
}
.fpv-head{
  position:absolute;left:var(--pad);right:var(--pad);top:clamp(26px,6vh,70px);
  text-align:center;opacity:0;transform:translateY(18px);
  transition:opacity var(--t-4) var(--ease),transform .8s var(--ease);pointer-events:none;
}
.fpv-head.on{opacity:1;transform:none;}
.fpv-head .h-xl{font-size:clamp(26px,4.4vw,60px);}
.fpv-sub{
  margin-top:14px;font-size:clamp(11px,1.1vw,16px);line-height:1.5;
  color:var(--ink-2);
}
/* Die Aussagezeilen laufen in der Schiene mit — eigene Sektion entfaellt */
.fpv-lines{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(28px,7vh,72px);
  height:2.6em;text-align:center;pointer-events:none;
}
.fpv-lines li{
  position:absolute;left:0;right:0;top:0;
  font-size:clamp(14px,1.7vw,22px);color:var(--ink-2);letter-spacing:-.01em;
  opacity:0;transform:translateY(12px);
  transition:opacity var(--t-3) var(--ease),transform var(--t-4) var(--ease);
}
.fpv-lines li.on{opacity:1;transform:none;color:var(--ink);}

/* ═══ 14-fx-marks.css ═══════════════════════════════════════════ */
/* ═══ FX · MARKS ═══════════════════════════════════════════════════════════
   Text, der beim Scrollen aufgedeckt wird — Zeile fuer Zeile, ueber clip-path
   statt ueber echtes Tippen. Sitzt hier ueber einem laufenden Video.
   Die Schwellen stehen als data-at am Element, nicht im JS.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--voice{height:var(--h-voice);}

/* Poster liegt als Hintergrund darunter — kein Schwarzblitz vor dem Videostart.
   Das Bild setzt die Engine zur Laufzeit aus dem poster-Attribut des Videos. */
.voice-media{
  position:absolute;inset:0;
  background-position:center;background-size:cover;background-repeat:no-repeat;
}
.voice-media video{width:100%;height:100%;object-fit:cover;opacity:.5;}
.voice-scrim{
  position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(4,6,9,.96) 12%,rgba(4,6,9,.62) 62%,rgba(4,6,9,.9) 100%);
}
.voice-copy{
  position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
  padding:0 var(--pad);max-width:var(--wrap);margin:0 auto;
}
.voice-type{display:flex;flex-direction:column;gap:4px;margin-bottom:24px;}
.vt{display:block;clip-path:inset(0 0 100% 0);transition:clip-path 1.1s var(--ease);}
.vt.on{clip-path:inset(0 0 0 0);}
.voice-type .vt:nth-child(2){transition-delay:.18s;}
.voice-lead{
  max-width:44ch;font-size:clamp(14px,1.25vw,18px);line-height:1.55;
  color:var(--ink-2);margin-bottom:26px;
}
.voice-list li{
  font-size:clamp(13px,1.35vw,17px);color:var(--ink-2);padding:9px 0;
  opacity:0;transform:translateY(14px);
  transition:opacity var(--t-3) var(--ease),transform var(--t-4) var(--ease);
}
.voice-list.on li{opacity:1;transform:none;}
.voice-list.on li:nth-child(2){transition-delay:.1s;}
.voice-list.on li:nth-child(3){transition-delay:.2s;}

/* ═══ 15-fx-layers.css ══════════════════════════════════════════ */
/* ═══ FX · LAYERS ══════════════════════════════════════════════════════════
   Beliebig viele Bildkacheln starten auf einer Ellipse verstreut und rasten
   beim Scrollen exakt uebereinander ein. Das Bild fuer "aus vielen Teilen
   wird ein System". Vollstaendig datengetrieben ueber data-depth.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--layers{height:var(--h-layers);}
.chapter--layers .stage{display:flex;align-items:center;justify-content:center;}

.layers{position:absolute;inset:0;}
.layer{
  position:absolute;top:50%;left:50%;width:clamp(200px,26vw,380px);aspect-ratio:1;
  background-size:cover;background-position:center;border-radius:var(--r-1);opacity:.3;
  border:1px solid rgba(255,255,255,.08);will-change:transform;
}
/* Eigener Hintergrund statt Pseudo-Element: er malt garantiert hinter dem
   eigenen Text, aber vor den Ebenen — sonst verschwindet die Unterzeile,
   sobald die Kacheln in der Mitte zusammenlaufen. */
.one-copy{
  position:relative;text-align:center;
  padding:clamp(28px,6vh,72px) var(--pad);
  background:radial-gradient(ellipse 72% 100% at 50% 50%,
    rgba(5,8,11,.9) 0%,rgba(5,8,11,.62) 52%,rgba(5,8,11,0) 80%);
}
.one-list{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(14px,2.5vw,40px);margin-top:36px;}
.one-list li{font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-2);}

/* ═══ 16-fx-close.css ═══════════════════════════════════════════ */
/* ═══ FX · CLOSE ═══════════════════════════════════════════════════════════
   Abschluss. Ruhiges Partikelfeld im oberen Drittel, darunter der Textblock
   mit den Kontaktwegen.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter--close{height:var(--h-close);}
.chapter--close .stage{background:radial-gradient(ellipse at 50% 40%,#0C1218,#05080B 72%);}

/* Der Block traegt Eyebrow, Fliesstext, Tags, zwei Buttons und die
   Kopierzeile — er muss tief sitzen, sonst laeuft er in die Partikelzone. */
.close-copy{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(20px,4vh,48px);
  text-align:center;
}
.close-copy .eyebrow{margin-bottom:14px;}
.close-copy h2{margin-bottom:14px;}
.close-text{
  color:var(--ink-2);font-size:clamp(14px,1.2vw,17px);line-height:1.6;
  max-width:56ch;margin:0 auto 16px;
}
.close-tags{
  font-size:10px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:18px;
}
.cta-row{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:12px;}

/* Kopierzeile: die Adresse ist sichtbar UND mit einem Klick uebernehmbar */
.copy-line{
  display:inline-flex;align-items:center;gap:12px;margin:0 0 14px;
  padding:8px 16px;border:1px solid transparent;border-radius:var(--r-pill);
  background:none;color:inherit;font-family:inherit;cursor:pointer;
  transition:border-color var(--t-2) var(--ease),background var(--t-2) var(--ease);
}
.copy-line:hover{border-color:var(--line);background:rgba(255,255,255,.03);}
.copy-mail{font-size:13px;letter-spacing:.04em;color:var(--ink-2);}
.copy-hint{font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);}
.copy-line.copied .copy-hint{color:var(--accent);}
.sig{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-3);}

/* ═══ 20-components.css ═════════════════════════════════════════ */
/* ═══ KOMPONENTEN ══════════════════════════════════════════════════════════
   Bausteine, die mehrere Sections teilen. Nichts hier kennt einen Kunden.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Button ─────────────────────────────────────────────────────────────── */
.cta{
  pointer-events:auto;display:inline-flex;align-items:center;gap:12px;
  padding:14px 26px;border:1px solid var(--line);border-radius:var(--r-pill);
  font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;
  background:rgba(255,255,255,.03);backdrop-filter:blur(6px);
  transition:border-color .5s var(--ease),background .5s var(--ease),transform .5s var(--ease);
}
.cta svg{width:15px;height:15px;fill:none;stroke:var(--accent);stroke-width:2;}
.cta:hover{
  border-color:rgba(var(--accent-rgb),.55);
  background:rgba(var(--accent-rgb),.08);
  transform:translateY(-2px);
}
.cta--solid{border-color:rgba(var(--accent-rgb),.4);}

/* ── Bildrahmen ──────────────────────────────────────────────────────────
   --ratio wird inline am Element gesetzt, wenn ein Motiv einen anderen
   Beschnitt braucht (Gebaeude 2/3, Portraet 4/5, Panorama 16/5).
   --grade und --focal ebenso: pro Foto, nicht pro System. */
.media-frame{
  position:relative;overflow:hidden;border-radius:var(--r-1);
  background:var(--panel);border:1px solid var(--line);
  aspect-ratio:var(--ratio,4/5);
}
.media-frame img{
  width:100%;height:100%;object-fit:cover;
  object-position:var(--focal,50% 50%);
  transform:scale(1.06);transition:transform var(--t-7) var(--ease);
}
.reveal.is-in .media-frame img{transform:scale(1);}
.media-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:var(--z-cap);
  padding:44px 16px 13px;
  font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:rgba(var(--ink-rgb),.72);
  background:linear-gradient(0deg,rgba(4,6,9,.9),rgba(4,6,9,0));
}
/* Farbkorrektur fuer Fotos, die nicht aus der dunklen Palette kommen —
   Tageslicht, Studio, Handyfoto. Der Grade steht inline am Element. */
.media-frame--graded img{filter:var(--grade,none);}
.media-frame--graded::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(7,12,18,.32) 0%,rgba(7,12,18,0) 40%,rgba(4,6,9,.5) 100%);
}

/* ── Split: Bild + Text ──────────────────────────────────────────────────── */
.about-split{
  display:grid;grid-template-columns:minmax(0,.6fr) minmax(0,1fr);
  gap:clamp(28px,4.5vw,72px);align-items:center;
}
.about-media.media-frame{max-width:360px;width:100%;}
.about-role{
  font-size:clamp(11px,1.05vw,14px);letter-spacing:.22em;text-transform:uppercase;
  color:var(--accent);margin-top:20px;font-weight:600;
}
.about-copy .body:first-of-type{margin-top:22px;}

.see-split{
  display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,.7fr);
  gap:clamp(28px,4.5vw,72px);align-items:start;margin-top:8px;
}
.see-copy .body{max-width:52ch;}
.see-media.media-frame{
  max-width:320px;width:100%;margin:0 0 0 auto;
  box-shadow:var(--sh-tall);
}

/* ── Aufzaehlung mit Trennstrichen ───────────────────────────────────────
   Traegt Anwendungsbereiche, Leistungen, Themen — typografisch statt mit
   erfundenen Bildern. .segments gross, .spectrum klein und versalisiert. */
.segments,.spectrum{
  display:flex;flex-wrap:wrap;
  border-top:1px solid var(--line);
}
.segments{row-gap:12px;margin-top:clamp(34px,4.5vh,58px);padding-top:22px;}
.spectrum{row-gap:10px;margin-top:16px;padding-top:18px;}
.segments li,.spectrum li{position:relative;}
.segments li{padding:0 clamp(13px,1.7vw,24px);}
.spectrum li{padding:0 clamp(11px,1.4vw,20px);}
.segments li:first-child,.spectrum li:first-child{padding-left:0;}
.segments li::before,.spectrum li::before{
  content:"";position:absolute;left:0;top:.3em;bottom:.3em;width:1px;background:var(--line);
}
.segments li:first-child::before,.spectrum li:first-child::before{display:none;}
.segments li span{
  font-size:clamp(12px,1.1vw,15px);letter-spacing:.04em;
  color:var(--ink-3);transition:color var(--t-3) var(--ease);
}
.spectrum li span{
  font-size:clamp(10px,.95vw,13px);letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-3);transition:color var(--t-3) var(--ease);
}
.segments li.on span,.spectrum li.on span{color:var(--ink-2);}
/* Ein Eintrag darf markiert sein — das Neue, das Beispiel, der Anlass */
.segments-new span::before{
  content:"";display:inline-block;width:5px;height:5px;border-radius:50%;
  background:var(--accent);margin-right:9px;vertical-align:middle;
}
.segments li.segments-new.on span{color:var(--ink);}

.spectrum-lead{
  margin-top:clamp(34px,4.5vh,60px);
  font-size:clamp(15px,1.5vw,20px);letter-spacing:-.01em;
}

/* ── Breites Bild mit Textfuss ───────────────────────────────────────────── */
.tech-wide{
  margin:clamp(30px,4.5vh,60px) 0 0;
  --ratio:16/5;min-height:220px;max-width:100%;
}
/* Verlauf statt blossem Textschatten — Motive sind stellenweise hell */
.tech-wide-copy{
  position:absolute;left:0;right:0;bottom:0;
  padding:clamp(44px,9vh,110px) clamp(20px,3vw,44px) clamp(18px,3vh,36px);
  background:linear-gradient(0deg,rgba(4,6,9,.94) 0%,rgba(4,6,9,.72) 48%,rgba(4,6,9,0) 100%);
}
.tech-wide-copy .eyebrow{margin-bottom:10px;}
.tech-wide-text{
  font-size:clamp(16px,2vw,28px);line-height:1.24;letter-spacing:-.02em;
  text-shadow:0 2px 22px rgba(0,0,0,.8);
}
/* Schleier, der beim Eintreten zur Seite zieht und das Motiv freigibt */
.xray-veil{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(7,9,11,.92),rgba(7,9,11,0) 55%);
  clip-path:inset(0 0 0 0);
  transition:clip-path var(--t-6) var(--ease) .35s;
}
.reveal.is-in .xray-veil{clip-path:inset(0 0 0 100%);}

/* ── Karten auf Haarlinie ────────────────────────────────────────────────
   .vision-grid (4-up) und .why-triad (3-up) teilen die Mechanik: die Linie
   oben zieht in Akzentfarbe auf, der Text hellt nach. */
.vision-grid,.why-triad{display:grid;}
.vision-grid{
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(14px,2vw,32px);margin-top:clamp(44px,6vh,84px);
}
.why-triad{
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(18px,2.6vw,44px);margin-top:clamp(40px,5.5vh,76px);
}
.vision-grid li,.why-triad li{position:relative;border-top:1px solid var(--line);padding-top:22px;}
.vision-grid li::before,.why-triad li::before{
  content:"";position:absolute;left:0;top:-1px;height:1px;width:0;
  background:var(--accent);transition:width var(--t-5) var(--ease);
}
.vision-grid li.on::before,.why-triad li.on::before{width:100%;}
.vision-grid b{
  display:block;font-size:clamp(13px,1.4vw,18px);letter-spacing:.2em;
  text-transform:uppercase;font-weight:600;margin-bottom:13px;
  color:var(--ink-3);transition:color var(--t-4) var(--ease);
}
.vision-grid p{
  font-size:clamp(13px,1.05vw,15px);line-height:1.6;
  color:var(--ink-3);transition:color var(--t-4) var(--ease);
}
.vision-grid li.on b{color:var(--ink);}
.vision-grid li.on p{color:var(--ink-2);}
.why-num{
  display:block;font-size:10px;letter-spacing:.22em;color:var(--ink-3);margin-bottom:14px;
}
.why-triad b{
  display:block;font-size:clamp(17px,2vw,26px);letter-spacing:-.02em;margin-bottom:12px;
  color:var(--ink-3);transition:color var(--t-4) var(--ease);
}
.why-triad li.on b{color:var(--ink);}
.why-triad p{font-size:clamp(13px,1.1vw,15px);line-height:1.6;color:var(--ink-2);}

/* ── Kaskade: aus einem Anlass werden viele Ergebnisse ───────────────────── */
.cascade{
  margin-top:clamp(40px,5.5vh,76px);position:relative;padding-left:26px;
  column-gap:clamp(30px,5vw,80px);
}
.cascade::before{
  content:"";position:absolute;left:0;top:8px;bottom:8px;width:1px;background:var(--line);
}
.cascade li{position:relative;padding:clamp(10px,1.6vh,17px) 0;break-inside:avoid;}
.cascade li::before{
  content:"";position:absolute;left:-26px;top:50%;width:16px;height:1px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform var(--t-4) var(--ease);
}
.cascade li.on::before{transform:scaleX(1);}
.cascade-root b{font-size:clamp(17px,2vw,26px);letter-spacing:-.02em;}
.cascade li span{
  font-size:clamp(14px,1.4vw,19px);color:var(--ink-2);
  transition:color var(--t-3) var(--ease);
}
.cascade li.on span{color:var(--ink);}

/* ── Weg: nummerierte Schritte ───────────────────────────────────────────── */
.funnel{
  display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  gap:8px;margin-top:clamp(34px,4.5vh,60px);
  counter-reset:fstep;
}
.funnel li{position:relative;padding-top:20px;counter-increment:fstep;}
.funnel li::before{
  content:"";position:absolute;left:0;right:8px;top:0;height:1px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform var(--t-4) var(--ease);
}
.funnel li.on::before{transform:scaleX(1);}
.funnel-step{
  display:block;font-size:clamp(11px,1vw,14px);letter-spacing:.06em;
  color:var(--ink-3);transition:color var(--t-3) var(--ease);
}
.funnel li.on .funnel-step{color:var(--ink);}
.funnel-step::before{
  content:"0" counter(fstep);display:block;
  font-size:9px;letter-spacing:.2em;color:var(--ink-3);margin-bottom:8px;
}

/* ── Spec-Liste an linker Kante ──────────────────────────────────────────── */
.basis-row{
  display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.5fr);
  gap:clamp(24px,4vw,64px);align-items:start;
}
.basis-head .eyebrow{margin-bottom:12px;}
.basis-text{font-size:clamp(14px,1.2vw,17px);line-height:1.55;color:var(--ink-2);}
.basis-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,2vw,32px);}
.basis-list li{border-left:1px solid var(--line);padding-left:16px;}
.basis-list b{
  display:block;font-size:clamp(11px,1vw,13px);letter-spacing:.16em;text-transform:uppercase;
  margin-bottom:8px;color:var(--ink-3);transition:color var(--t-3) var(--ease);
}
.basis-list li.on b{color:var(--ink);}
.basis-list span{font-size:clamp(12px,1vw,14px);color:var(--ink-3);line-height:1.55;}

/* ═══ 21-video.css ══════════════════════════════════════════════ */
/* ═══ VIDEO · Facade ═══════════════════════════════════════════════════════
   Poster + Play-Knopf. Der Iframe wird erst beim Klick eingehaengt: kein
   Request an die Plattform beim Seitenaufruf, keine Third-Party-Cookies,
   kein Ladeeinbruch. Erst wenn jemand wirklich schauen will.
   ═══════════════════════════════════════════════════════════════════════════ */

.film{
  position:relative;margin:clamp(30px,4.5vh,60px) auto 0;
  width:100%;max-width:1080px;aspect-ratio:16/9;
  border:1px solid var(--line);border-radius:var(--r-3);overflow:hidden;
  background:var(--panel);box-shadow:var(--sh-wide);
}
.film-trigger{
  position:absolute;inset:0;width:100%;height:100%;padding:0;
  border:0;background:none;cursor:pointer;display:block;
}
.film-trigger img{width:100%;height:100%;object-fit:cover;transition:transform 1.2s var(--ease);}
.film-trigger:hover img{transform:scale(1.03);}
.film-trigger::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 70% 70% at 50% 50%,rgba(4,6,9,.25) 0%,rgba(4,6,9,.72) 100%);
}
.film-btn{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:var(--z-cap);
  display:flex;align-items:center;gap:14px;
  padding:15px 28px 15px 24px;border:1px solid var(--line);border-radius:var(--r-pill);
  background:rgba(0,0,0,.4);backdrop-filter:blur(8px);
  font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink);
  transition:border-color .5s var(--ease),background .5s var(--ease),transform .5s var(--ease);
}
.film-trigger:hover .film-btn{
  border-color:rgba(var(--accent-rgb),.55);
  background:rgba(0,0,0,.55);
  transform:translate(-50%,-50%) scale(1.04);
}
.film-btn svg{width:14px;height:14px;fill:var(--accent);}
.film iframe{position:absolute;inset:0;width:100%;height:100%;border:0;}
.film-cap{
  margin-top:14px;text-align:center;
  font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3);
}

/* ═══ 90-responsive.css ═════════════════════════════════════════ */
/* ═══ RESPONSIVE ═══════════════════════════════════════════════════════════
   ALLE Media Queries stehen hier, in genau dieser Reihenfolge:

     1  min-width:900          Aufwertung fuer breite Fenster
     2  max-height              kurze Viewports (unabhaengig von der Breite)
     3  max-width:899           Hauptumbruch — mehrspaltig wird einspaltig
     4  max-width:768           Mobile Rhythmus + Performance
     5  max-width:620           schmale Telefone
     6  max-width:768 + kurz    iPhone SE & Co

   Die max-width-Bloecke MUESSEN breit → schmal laufen, sonst gewinnt der
   falsche. Im Original stand 620 vor 768; dadurch hat .compare{gap:10px}
   still ueber gap:14px gewonnen. Reihenfolge ist jetzt korrekt, und die
   14px-Regel ist geloescht statt wiederbelebt — das ausgelieferte Verhalten
   bei ≤620px bleibt damit unveraendert bei 10px.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Breite Fenster ───────────────────────────────────────────────────── */
@media (min-width:900px){
  .cascade{columns:2;}
}

/* ── 2 · Kurze Viewports ──────────────────────────────────────────────────
   Laptop-Fenster mit Browser-Chrome, eingebettete Vorschauen: der Copy-Block
   verkleinert sich, damit er nie in die Logo-Zone reicht. */
@media (max-height:760px){
  .hero-copy{bottom:clamp(22px,5vh,54px);}
  .hero-copy .lead{font-size:clamp(17px,2.6vw,30px);margin-bottom:12px;}
  .hero-copy .eyebrow{margin-bottom:13px;}
  .hero-sub{margin-bottom:18px;letter-spacing:.24em;}
}
@media (max-height:560px){
  .hero-copy{bottom:12px;}
  .hero-copy .eyebrow,.hero-sub{display:none;}
  .hero-copy .lead{font-size:15px;line-height:1.25;margin-bottom:12px;}
  .hero-copy .cta{padding:9px 18px;font-size:11px;}
}

/* ── 3 · Hauptumbruch ─────────────────────────────────────────────────────
   Eine einzige Kante fuer alle mehrspaltigen Bloecke. 1024 als Grenzwert
   traefe gaengige Geraetebreiten exakt und feuert dort nicht zuverlaessig. */
@media (max-width:899px){
  .about-split{grid-template-columns:1fr;gap:30px;}
  .about-media.media-frame{max-width:300px;margin:0 auto;}
  .see-split{grid-template-columns:1fr;gap:28px;}
  .see-media.media-frame{max-width:320px;margin:0 auto;}
  .tech-wide{--ratio:16/7;}
  .vision-grid{grid-template-columns:repeat(2,minmax(0,1fr));}
  .why-triad{grid-template-columns:1fr;gap:22px;}
  .basis-row{grid-template-columns:1fr;gap:24px;}
  .basis-list{grid-template-columns:1fr;gap:14px;}
  /* Schmaler Viewport: die Breite fuehrt, die Hoehe folgt dem Verhaeltnis */
  .browser-scene{--shot-h:92vh;}
  /* Geraete untereinander statt nebeneinander */
  .phone-scene{grid-template-columns:1fr;gap:16px;justify-items:center;}
  .phone{height:min(30vh,300px);max-width:70vw;}
  .yt{width:min(100%,460px);}
  /* Gestapelt laege der Schlagschatten auf dem zweiten Geraet */
  .phone-shadow{display:none;}
  .channels-block{max-width:560px;}
  .channels{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 20px;}
  .channels li:nth-child(2){border-top:1px solid var(--line);}
  .funnel{grid-template-columns:1fr;gap:0;}
  .funnel li{padding:14px 0 14px 26px;}
  .funnel li::before{
    left:0;right:auto;top:0;bottom:0;width:1px;height:auto;
    transform:scaleY(0);transform-origin:top;transition:transform var(--t-3) var(--ease);
  }
  .funnel li.on::before{transform:scaleY(1);}
  .funnel-step::before{display:inline-block;margin:0 10px 0 0;}
}

/* ── 4 · Mobile ───────────────────────────────────────────────────────────
   Dieselbe Dramaturgie, engere Abstaende. Ziel: ≤ 14 Screens. */
@media (max-width:768px){
  /* Die Storytelling-Uhr auf Mobile — frueher acht verstreute height-Regeln.
     Der Dive braucht Weg, sonst wird die Aufloesung am Ende zum Schnitt. */
  :root{
    --h-hero:125vh;
    --h-shots:200vh;
    --h-devices:140vh;
    --h-rail:128vh;
    --h-voice:108vh;
    --h-layers:105vh;
    --h-close:115vh;
  }

  /* Auf kleinen Telefonen zaehlt jede Zeile in den 100vh-Buehnen */
  .stage--pad{padding:12px var(--pad);}
  .section{padding:clamp(56px,8vh,110px) var(--pad);}
  .section--tight{padding:clamp(42px,5.5vh,80px) var(--pad);}
  .section--flat{padding:clamp(32px,4.5vh,56px) var(--pad);}
  .section--statement{min-height:66vh;}
  .body{margin-top:16px;}
  .body--wide{margin-top:26px;}
  .cascade{margin-top:26px;}
  .cascade li{padding:9px 0;}
  .segments{margin-top:26px;padding-top:18px;}
  .vision-grid{margin-top:30px;}
  .why-triad{margin-top:28px;}
  .why-triad li{padding-top:18px;}
  .about-split{gap:24px;}
  .about-media.media-frame{max-width:230px;}
  .see-split{gap:22px;}
  .see-media.media-frame{max-width:240px;}
  /* aspect-ratio + min-height blaehen sonst die BREITE auf (220 × 16/9 = 391px)
     und sprengen bei 375px den Viewport. Hoehe folgt hier der Breite. */
  .tech-wide{margin-top:24px;--ratio:16/9;min-height:0;}
  .statement{font-size:clamp(24px,7vw,38px);}
  .funnel{margin-top:24px;}
  .funnel li{padding:8px 0 8px 22px;}

  .hero-bg{filter:brightness(.66);}          /* blur auf Mobile aus — zu teuer */
  .hero-bg--sharp{display:none;}
  .fpv-blur{filter:brightness(.3) saturate(.7);}
  .fpv-panel{height:50vh;}
  .fpv-head .h-xl{font-size:clamp(22px,6.5vw,32px);}
  .fpv-sub{font-size:12px;margin-top:10px;}
  .voice-lead{margin-bottom:18px;}

  /* Zwei Geraete plus Kanaele in einer 100vh-Buehne: jede Zeile zaehlt */
  .phone-scene{gap:12px;}
  .phone{height:min(27vh,240px);max-width:44vw;}
  .yt{width:min(100%,380px);}
  .yt-body .browser-bar{padding:6px 9px;}
  .yt-body .browser-bar .url{font-size:8px;padding:3px 8px;margin-left:8px;}
  .yt-body .concept-tag{font-size:7.5px;padding:3px 6px;}
  .channels-lead{font-size:12px;margin-bottom:8px;}
  .channels{gap:0 16px;}
  .channels li{padding:7px 0;}
  .channels span{font-size:10px;line-height:1.3;}
  .channels-block .concept-note{margin-top:8px;}

  /* Der Vergleich sitzt in der Buehne — hier zaehlt jede Zeile */
  .compare{margin-top:14px;gap:10px;}
  .compare-label{font-size:8px;margin-bottom:4px;}
  .compare-col b{font-size:10px;line-height:1.4;}

  .shot-blur{display:none;}                   /* wie hero-bg--sharp: zu teuer */
  .shot-label{margin-top:10px;font-size:9px;letter-spacing:.18em;}
  .waves{display:none;}                       /* Mobile: kein WebGL-Layer */
  .film-btn{padding:11px 20px 11px 17px;font-size:10px;gap:10px;}
}

/* ── 5 · Schmale Telefone ─────────────────────────────────────────────────── */
@media (max-width:620px){
  .vision-grid{grid-template-columns:1fr;gap:0;}
  .vision-grid li{padding:18px 0;}
  .compare-arrow{display:none;}
}

/* ── 6 · Kurze Telefone (iPhone SE & Co) ──────────────────────────────────
   Zwei Geraete, Kopf und Kanaele passen nur, wenn die Kanalliste auf ihre
   Namen zusammenschnurrt. */
@media (max-width:768px) and (max-height:720px){
  .chapter--devices .stage--pad{gap:10px;}
  .phone-scene{gap:10px;}
  .phone{height:min(22vh,190px);}
  .channels-lead{font-size:11px;line-height:1.4;margin-bottom:6px;}
  .channels{grid-template-columns:repeat(4,minmax(0,1fr));gap:0 10px;}
  .channels span{display:none;}
  .channels li{padding:6px 0;}
  .channels b{font-size:11px;}
  .channels-block .concept-note{margin-top:6px;font-size:8.5px;}
}

/* ═══ 95-reduced.css ════════════════════════════════════════════ */
/* ═══ REDUZIERTE BEWEGUNG ══════════════════════════════════════════════════
   Vollstaendiger Fallback. Nichts bewegt sich, alles ist trotzdem lesbar.

   ACHTUNG beim Aendern: dieser Block adressiert sieben Klassennamen direkt
   (.vt, .ig-grid i, .yt-tiles i, .shot, .fpv-head, .fpv-lines li,
   .voice-list li). Wer eine davon umbenennt, bricht diesen Block still — und
   ausgerechnet fuer den Pfad, der am seltensten getestet wird.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{animation-duration:.001s !important;transition-duration:.001s !important;}

  .reveal [class*="eyebrow"],.reveal h2,.reveal .body,.reveal li,
  .reveal .media-frame,
  .reveal .close-text,.reveal .cta-row,.reveal .about-role,
  .reveal .basis-text,.reveal .close-tags,.reveal .copy-line,
  .d1,.d2,.d3,.d4{opacity:1 !important;transform:none !important;}

  .vt{clip-path:none !important;}
  .ig-grid i,.channels li{opacity:1 !important;transform:none !important;}
  .yt-tiles i{opacity:0 !important;}          /* Blenden liegen offen */
  .shot{transform:none !important;}           /* Deckkraft bleibt scrollgesteuert */
  .fpv-head{opacity:1 !important;transform:none !important;}
  .fpv-lines{position:static;height:auto;}
  .fpv-lines li{position:static;opacity:1 !important;transform:none !important;}
  .voice-list li{opacity:1 !important;transform:none !important;}
  .waves{display:none;}
}

/* ═══ 99-client.css — generiert aus pitch.config.mjs, nicht editieren ═══ */
:root{
  --accent: #06A7EA;
  --accent-rgb: 6,167,234;
  --accent-ink: #02344A;
  --bg: #05131A;
  --bg-2: #08202C;
  --surface-deep: #020C12;
  --panel: #102B38;
  --chrome: #0D2432;
  --chrome-2: #071A24;
  --chrome-dot: #1E4254;
  --ink-2: #8A99A7;
  --ink-3: #5A6875;
  --h-hero: 175vh;
  --h-rail: 145vh;
  --h-voice: 150vh;
}

/* ═══ brand.css (Client) ═══ */
/* ═══ HUBER IMMOBILIEN — eigene Regeln ═══════════════════════════════════════
   Achtung: das hier ist normales CSS und landet am Ende von css/pitch.css.
   url() loest also gegen css/ auf und braucht ../ — anders als in
   brand.tokens, wo der Build das ../ selbst setzt (fixUrls gilt nur dort).
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── 1 · Mobil-Takt ──────────────────────────────────────────────────────────
   Die --h-*-Overrides in brand.tokens landen im :root und gelten damit nur am
   Desktop: 90-responsive.css setzt die Kapitelhoehen fuer schmale Viewports
   selbst neu und ueberschreibt sie. Ohne diesen Block liefe der Pitch am
   Telefon im Default-Tempo — und dort wird er gelesen. */
@media (max-width: 768px) {
  :root {
    --h-hero:  130vh;   /* 175/170 auf mobil 125 */
    --h-rail:  135vh;   /* Default mobil 128. Ein einzelnes Panel braucht
                           trotzdem Weg: die Bewegung kommt hier allein aus
                           dem Massstab, und der braucht Strecke. */
    --h-voice: 145vh;   /* 150/108 auf mobil 108, leicht darunter: die Zeilen
                           lesen sich in einer schmalen Spalte schneller */
  }
}


/* ── 2 · Das Logo ruhig setzen ───────────────────────────────────────────────
   Der Kunde will die Wortmarke unveraendert sehen, nicht als Partikelfeld.
   Deshalb steht in pitch.config.mjs KEIN logo-Block: window.PITCH_LOGO ist
   null, der Partikelteil in 11-fx-hero.js steigt aus (der Bild-Dive laeuft
   weiter) und 17-fx-field.js lehnt ab. Die PNG-Datei wird trotzdem
   ausgeliefert, weil build.mjs assets/ komplett kopiert.

   Beide Canvas bleiben als leere, transparente Flaechen im DOM stehen. Sie
   sind unsichtbar, liegen aber ueber der Buehne — raus damit. */
#s-hero  .hero-canvas,
#s-close .hero-canvas { display: none; }

/* Das Logo sitzt im Textblock, direkt ueber der Ueberschrift. Damit gehoert
   es zur Auftakt-Staffel und blendet mit dem Copy-Block aus, wenn der Dive
   laeuft — es soll den Anfang rahmen, nicht die ganze Fahrt begleiten.

   NEGATIVFASSUNG: Hubers Logo ist dunkle Schrift auf Transparenz — "HUBER"
   in Indigo (#2A2F77), "IMMOBILIEN" und die Claimzeile in Schwarz. Auf dem
   Petrolgrund waere das praktisch unsichtbar. brightness(0) macht alle
   deckenden Pixel schwarz, invert(1) macht sie weiss. Der ALPHAKANAL bleibt
   dabei unangetastet — deshalb steht die Wortmarke frei auf dem Grund und
   nicht auf einem weissen Kasten.
   opacity .94 nimmt das reine Weiss eine Spur zurueck, damit es neben --ink
   (#E8EDF2) nicht haerter steht als die Ueberschrift darunter.

   Quelle ist die 4x-Fassung (1616x260, Lanczos). Huber hat nur die 404er
   Datei ("_klein") online — geprueft, eine groessere oder eine SVG gibt es
   nicht. Hochrechnen fuegt keine Details hinzu, aber hier zaehlt allein die
   ALPHAKANTE: der Filter macht ohnehin eine flaechige weisse Silhouette
   daraus, es gibt also keine Farbsaeume, die eine Interpolation verraten
   koennten. Bei 640 CSS-px und DPR 2 liegen 1280 Geraetepixel an — die
   1616er Quelle wird heruntergerechnet statt hochgezogen. */
#s-hero .hero-copy::before,
#s-close .close-copy::before {
  content: "";
  display: block;
  margin: 0 auto clamp(26px, 4vh, 46px);
  aspect-ratio: 404 / 65;
  background: url(../assets/logo/logo-huber@4x.png) center / contain no-repeat;
  filter: brightness(0) invert(1);
  opacity: .94;
}
#s-hero  .hero-copy::before  { width: min(640px, 88vw); }
/* Im Abschluss kleiner: dort traegt der Text, das Logo signiert nur. */
#s-close .close-copy::before { width: min(340px, 62vw); margin-bottom: clamp(18px, 3vh, 34px); }

/* Die Ueberschrift unter dem Logo. Der Master gibt dem eyebrow 11px in
   --ink-2; als Zeile direkt unter einer 400px breiten Wortmarke ist das zu
   duenn. Etwas groesser, in --ink, mit mehr Luft nach unten — sie soll als
   Ueberschrift lesen, ohne dem lead die Buehne zu nehmen. */
#s-hero .hero-copy .eyebrow {
  font-size: clamp(12px, 1.2vw, 16px);
  letter-spacing: .28em;
  color: var(--ink);
  margin-bottom: clamp(22px, 3.6vh, 40px);
}

/* 90-responsive.css blendet bei sehr flachen Viewports eyebrow und hero-sub
   aus, weil die Buehne dann nicht mehr hergibt. Das Logo braucht dieselbe
   Behandlung, sonst drueckt es den Rest aus dem Bild. */
@media (max-height: 560px) {
  #s-hero .hero-copy::before { display: none; }
  #s-close .close-copy::before { width: min(180px, 44vw); }
}


/* ── 3 · Die Scrims auf Petrol ziehen ────────────────────────────────────────
   Sieben Regeln im Master haben ihre Abdunklung HART kodiert statt ueber
   Tokens: rgba(4,6,9) · rgba(5,8,11) · rgba(3,5,7) · rgba(7,12,18) sowie der
   Verlauf der Abschluss-Buehne. Auf dem Default-Grund #07090B ist das
   dieselbe Farbe. Auf #05131A sind es neutralgraue Loecher in einer
   Petrolflaeche — sichtbar an jeder Kapitelnaht.

   Hier dieselben Deckkraefte auf den petrolseitigen Aequivalenten. Bewusst
   KEIN Master-Eingriff (CLAUDE.md Regel 4): ein Master-Eingriff muesste jeden
   bestehenden Pitch ueberleben, und diese Verschiebung gilt nur hier.

   KEINE dieser Klassen umbenennen — .voice-scrim, .media-frame und .ig-grid
   stehen im prefers-reduced-motion-Block (95-reduced.css). */

/* Hero-Vignette · 10-fx-hero.css:22 */
.hero-vig{
  background:radial-gradient(ellipse 62% 62% at 50% 46%,
    rgba(4,14,20,0) 0%, rgba(4,14,20,.58) 60%, rgba(2,10,14,.96) 100%);
}

/* Storytelling · 14-fx-marks.css:18 */
.voice-scrim{
  background:linear-gradient(90deg,
    rgba(3,12,17,.96) 12%, rgba(3,12,17,.62) 62%, rgba(3,12,17,.9) 100%);
}

/* Textfuss im Breitbild · 20-components.css:119 */
.tech-wide-copy{
  background:linear-gradient(0deg,
    rgba(3,12,17,.94) 0%, rgba(3,12,17,.72) 48%, rgba(3,12,17,0) 100%);
}

/* Bildunterschrift · 20-components.css:40 */
.media-cap{
  background:linear-gradient(0deg, rgba(3,12,17,.9), rgba(3,12,17,0));
}

/* Verlauf ueber gegradeten Fotos · 20-components.css:45 */
.media-frame--graded::after{
  background:linear-gradient(180deg,
    rgba(6,20,28,.32) 0%, rgba(6,20,28,0) 40%, rgba(3,12,17,.5) 100%);
}

/* Buehne des Abschlusskapitels · 16-fx-close.css:7 — der Master setzt hier
   #0C1218 auf #05080B. Ohne diese Regel waere der Abschluss die einzige
   neutralgraue Flaeche im ganzen Pitch, ausgerechnet auf der letzten Seite. */
.chapter--close .stage{
  background:radial-gradient(ellipse at 50% 40%, #0A2231, #030E15 72%);
}


/* ── 4 · Storytelling: das Video bleibt unter der Schrift ────────────────────
   Fehlerbild: beim Scrollen legt sich das laufende Video ueber den Text.

   Ursache: 14-fx-marks.css stapelt drei absolut positionierte Ebenen
   (.voice-media, das <video>, .voice-copy) OHNE ein einziges z-index. Die
   Ordnung haengt allein an der Baumreihenfolge. Dazu macht
   14-fx-marks.css:15 mit opacity:.5 das <video> zu einem eigenen Stacking
   Context und hebt es damit auf die Ebene von .voice-copy — und .voice-copy
   hat keinerlei Compositor-Promotion (kein transform, kein will-change, kein
   filter). Sobald der Browser die Video-Surface in eine eigene Layer hebt,
   gewinnt sie.

   Gegenprobe im selben Master: 13-fx-rail.css hat dasselbe Muster und kippt
   nicht — dort sind BEIDE Seiten promoted (.fpv-panel:23 und .fpv-head:32).
   Genau das fehlt hier.

   isolation sperrt das Video in seinen Kontext, z-index erzwingt die Ordnung
   deklarativ, translateZ(0) gibt dem Text die Layer, ohne die der Compositor
   die Ordnung gar nicht respektieren kann. */
#s-verkauft .voice-media{
  z-index: 0;
  isolation: isolate;
}
#s-verkauft .voice-copy{
  z-index: 2;
  transform: translateZ(0);
  /* .hero-copy und .fpv-head haben das, .voice-copy nicht — es faengt sonst
     Klicks ueber der gesamten Buehne ab. In dieser Section liegt nichts
     Interaktives, also risikofrei. */
  pointer-events: none;
}


/* ── 5 · Die Film-Buehne auf Querformat ──────────────────────────────────────
   Der Master baut die Schiene fuer Hochformat: .fpv-panel ist
   aspect-ratio 9/16 bei height:min(58vh,580px) (13-fx-rail.css:19-21).
   Hier laeuft ein einzelner 16:9-Film, also muss das Panel gedreht werden.

   Die Breite wird gegen DREI Groessen gedeckelt, und die dritte ist die
   wichtige: 83vh entspricht bei 16:9 einer Hoehe von rund 47vh. Ohne diesen
   Deckel waere das Panel auf einem breiten, flachen Fenster hoeher als die
   Buehne. Ueber max-height zu gehen waere falsch: das bricht das
   Seitenverhaeltnis, und object-fit:cover wuerde den Film beschneiden statt
   ihn kleiner zu zeichnen.

   Nachgemessen bei 1440x900: .fpv-head laeuft bis 285 px, .fpv-lines beginnt
   bei 796 px. Das nutzbare Band ist also rund 510 px hoch und liegt mit
   seiner Mitte bei ~540 px — nicht bei 450, wo die Buehnenmitte liegt.
   Deshalb wird die Schiene um 20vh nach unten gesetzt: bei drei schmalen
   Hochformat-Panels war die Buehnenmitte richtig, bei einem breiten
   Querformat-Panel kollidiert sie mit der Ueberschrift. */
#s-fpv .fpv-rail{
  top: 20vh;
}
#s-fpv .fpv-panel{
  aspect-ratio: 16 / 9;
  width: min(940px, 90vw, 83vh);
  height: auto;
}


/* ── 6 · Das Hero-Bild frueher lesbar machen ─────────────────────────────────
   10-fx-hero.css:13 legt blur(9px) brightness(.72) auf die Grundebene. Das
   ist fuer eine Makroaufnahme richtig — dort ist das Bild Atmosphaere. Hier
   ist es Information: der erste Eindruck soll "das ist eine Immobilie" sein,
   nicht ein dunkler Farbnebel. Deshalb 3 px statt 9 und .88 statt .72.

   ACHTUNG bei der Spezifitaet: die zweite Regel MUSS mitgeschrieben werden.
   Im Master gewinnt .hero-bg--sharp ueber .hero-bg allein durch die spaetere
   Position; sobald hier eine ID-Regel steht, schlaegt sie beide — und die
   scharfe Ebene waere ploetzlich auch unscharf, womit der Aufloesungsmoment
   am Ende des Dives verloren ginge. */
#s-hero .hero-bg        { filter: blur(3px) brightness(.88); }
#s-hero .hero-bg--sharp { filter: brightness(.94); }


/* ── 7 · Zum uebrigen Bildmaterial: hier steht bewusst nichts ────────────────
   Alle Aufnahmen sind Tageslicht — gruenes Laub, blauer Himmel, helle
   Interieurs — und der Pitch steht auf tiefem Petrol. Gedaempft wird
   trotzdem nichts, weil der Master das an jeder Stelle schon selbst tut:

     Panel-Schiene   .fpv-blur fuellt den Hintergrund mit brightness(.34)
                     saturate(.7), die Buehne steht auf --surface-deep.
     Storytelling    das Video liegt bei opacity .5 hinter dem Scrim.
     about-Foto      traegt seinen grade inline aus der Config.

   Ein Filter auf .fpv-panel waere hier sogar schaedlich: er wuerde die
   figcaption mitdaempfen und einen Containing Block erzeugen, in dem die
   Transforms der Schiene sitzen (.fpv-panel traegt will-change:transform).
   Falls die Schiene am grossen Bildschirm doch zu hell liest, ist der
   richtige Hebel .fpv-panel video — nicht das Panel selbst. */
