/* ============================================================================
   seite-start  —  aus index.html des statischen Standes
   Automatisch extrahiert (_work/theme-css-extrakt.mjs), inhaltlich unveraendert.
   Einzige Aenderung: Bildpfade zeigen auf das Theme-Verzeichnis.
   ========================================================================= */


/* ============================ Page-specific ============================ */
/* ==========================================================================
   HERO — Inhaber-Vorlage "AZB Hero Redesign" 3a (Desktop) + 3b (Mobil), 1:1.
   Abweichungen ausschliesslich dort, wo die Vorlage auf dieser Seite technisch
   nicht 1:1 gehen kann; jede ist in _design/hero-regie.md entschieden:
   - Der Vorlage-Header wird NICHT gebaut. Unsere fixe Nav bleibt die einzige
     und wird am Seitenanfang transparent (html.nav-klar, Inline-JS unten).
   - Barlow entfaellt, UI-Text laeuft auf var(--font-body) (Regie 1).
   - prefers-reduced-motion ist Pflicht (die Vorlage hat keine Sperre, Regie 3).
   - Die Vorlage rechnet in festen Pixeln gegen 1440x920. Diese Seite muss
     jede Hoehe tragen, darum haengen Typo- und Abstandsmasse an --az-h (der
     tatsaechlichen Buehnenhoehe) UND an der Breite: min() nimmt, was zuerst
     eng wird. Bei 1440x920+ ergeben alle Formeln exakt die Vorlage-Werte.
   ========================================================================== */
@keyframes az-rise{from{transform:translateY(112%) rotate(1.1deg)}to{transform:translateY(0) rotate(0)}}
@keyframes az-fade{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes az-in{from{opacity:0}to{opacity:1}}
@keyframes az-ken{0%{transform:scale(1.04)}100%{transform:scale(1.1) translate3d(-.8%,-1%,0)}}
@keyframes az-mq{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes az-pulse{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(46,204,113,.5)}50%{opacity:.6;box-shadow:0 0 0 8px rgba(46,204,113,0)}}
@keyframes az-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
@keyframes az-wipe{0%{transform:translateX(0)}100%{transform:translateX(102%)}}
@keyframes az-shutter-t{from{transform:translateY(0)}to{transform:translateY(-100%)}}
@keyframes az-shutter-b{from{transform:translateY(0)}to{transform:translateY(100%)}}
/* Die Vorlage bewegt hier background-position. Das ist ein Neu-Zeichnen der
   3px-Kachel ueber die ganze Buehne, 6x pro 2,6 s — gemessen der teuerste
   Einzelposten des Stapels. Als transform ist es Sache des Compositors und
   optisch nicht zu unterscheiden: das Element hat durch inset:-60px genug
   Schlupf fuer die 37/61 px Versatz. */
@keyframes az-grain{0%{transform:translate3d(0,0,0)}100%{transform:translate3d(37px,61px,0)}}
@keyframes az-blur{from{opacity:0;filter:blur(16px);transform:translateY(26px)}to{opacity:1;filter:blur(0);transform:none}}
@keyframes az-flare{0%,100%{opacity:.16;transform:scaleX(1)}50%{opacity:.4;transform:scaleX(1.2)}}
@keyframes az-scan{0%{transform:translateY(-10%);opacity:0}10%{opacity:.6}90%{opacity:.4}100%{transform:translateY(110%);opacity:0}}
@keyframes az-mote{0%{transform:translate3d(0,20px,0);opacity:0}18%{opacity:.7}82%{opacity:.45}100%{transform:translate3d(28px,-190px,0);opacity:0}}
@keyframes az-underline{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes az-corner{from{opacity:0;transform:scale(1.14)}to{opacity:1;transform:scale(1)}}
@keyframes az-cue{0%{transform:translateY(-8px);opacity:0}40%{opacity:1}100%{transform:translateY(14px);opacity:0}}
@keyframes az-bloom{0%,100%{opacity:.25}50%{opacity:.45}}

/* --- Buehne ------------------------------------------------------------- */
.az-hero {
  --az-rot: #ff2d2d;          /* Rot der Vorlage. EINE Quelle fuer alle Stellen */
  --az-tief: #070709;
  --az-mqh: 108px;            /* Hoehe der Marken-Leiste direkt darunter */
  /* Hero + Laufband fuellen zusammen den ersten Schirm, hoechstens aber die
     920 px der Vorlage. Der Boden lag auf 600 px — darunter passt die Copy
     (Eyebrow + dreizeilige H1 + Lede + zwei CTAs, zusammen gemessen 425 px)
     samt Stat-Streifen (93 px) und Fusspolster aber nicht mehr in die Buehne,
     und der Ueberlauf landete im Stat-Streifen. 700 px ist die gemessene
     Untergrenze, ab der beides nebeneinander Platz hat; ein niedrigeres
     Fenster laesst die Buehne jetzt lieber ein Stueck unter den Falz reichen,
     als Text uebereinander zu stapeln. Bindet erst unter 758 px Fensterhoehe. */
  --az-h: clamp(700px, calc(100svh - var(--az-mqh)), 920px);
  --az-rand: clamp(24px, 4.44vw, 64px);       /* 64px @1440 */
  /* Schriftgrade: min() nimmt die engere der beiden Achsen (Breite/Hoehe).
     @1440x920 -> exakt 88 / 126 / 46 px wie in der Vorlage. */
  --az-t1: max(40px, min(5.8vw, calc(var(--az-h) * .0957), 88px));
  --az-t2: max(52px, min(8.3vw, calc(var(--az-h) * .137), 126px));
  --az-tz: max(28px, min(3.19vw, calc(var(--az-h) * .05), 46px));
  position: relative; width: 100%; height: var(--az-h);
  overflow: hidden; background: var(--az-tief);
  isolation: isolate;
}

/* Alle Bild-/Licht-/Textur-Ebenen liegen in EINEM Band. Auf Mobil wird genau
   dieses Band zum 452-px-Streifen, unter dem die Typo auf Schwarz steht (3b) —
   deshalb steckt es in einem eigenen Element und nicht direkt im Hero. */
.az-band { position: absolute; inset: 0; z-index: 0; overflow: hidden; }

/* .7s -> .8s: dieselbe Geste ("Bild bewegt sich weich") lief site-weit auf
   vier Dauern (.6/.7/.8/.9). .8s ist der haeufigste Wert und damit der
   Familien-Wert (Review 20/10, Inventar 1). Kurve unveraendert. */
.az-bild { position: absolute; inset: 0; will-change: transform;
           transition: transform .8s cubic-bezier(.2,.7,.2,1); }
.az-bild img {
  width: 100%; height: 100%; object-fit: cover; object-position: 53% 62%;
  filter: brightness(1.36) contrast(1.1) saturate(1.05);
  animation: az-ken 36s ease-in-out infinite alternate;
}
/* Unterkante: dasselbe Bild, stark geblurrt, nach oben ausmaskiert — die
   Kante loest sich in Licht auf statt abzuschneiden. */
/* Muss mit .az-bild deckungsgleich bleiben — die Spiegelung ist dasselbe Bild
   und wuerde bei abweichender Dauer sichtbar nachlaufen. */
.az-fuss { position: absolute; inset: -30px; pointer-events: none; will-change: transform;
           transition: transform .8s cubic-bezier(.2,.7,.2,1); }
.az-fuss img {
  width: 100%; height: 100%; object-fit: cover; object-position: 53% 88%;
  transform: scale(1.24); filter: blur(20px) brightness(1.1); will-change: transform;
  -webkit-mask-image: linear-gradient(to top,#000 0%,rgba(0,0,0,.55) 12%,rgba(0,0,0,0) 26%);
          mask-image: linear-gradient(to top,#000 0%,rgba(0,0,0,.55) 12%,rgba(0,0,0,0) 26%);
}

/* Vier Schleier. Der senkrechte traegt oben die Nav, unten den Stat-Streifen;
   der waagerechte gibt der Copy links ihren Kontrast, laesst die Bildmitte
   (Francesco) aber frei. */
.az-scrim { position: absolute; inset: 0; pointer-events: none; }
.az-scrim-v { background: linear-gradient(180deg,rgba(7,7,9,.86) 0%,rgba(7,7,9,.3) 17%,rgba(7,7,9,.04) 40%,rgba(7,7,9,.46) 70%,rgba(7,7,9,.95) 100%); }
.az-scrim-h { background: linear-gradient(96deg,rgba(7,7,9,.92) 0%,rgba(7,7,9,.56) 25%,rgba(7,7,9,.04) 47%,rgba(7,7,9,0) 66%,rgba(7,7,9,.42) 100%); }
.az-scrim-r { background: radial-gradient(74% 64% at 50% 46%,rgba(0,0,0,0) 40%,rgba(0,0,0,.58) 100%); }
.az-scrim-s { mix-blend-mode: soft-light; background: linear-gradient(180deg,rgba(88,140,180,.3) 0%,rgba(0,0,0,0) 44%,rgba(255,92,60,.18) 100%); }

.az-flare {
  position: absolute; left: 0; top: 35%; width: 100%; height: 150px;
  pointer-events: none; filter: blur(32px);
  background: linear-gradient(90deg,rgba(0,0,0,0) 0%,rgba(96,170,255,.2) 34%,rgba(196,228,255,.48) 52%,rgba(96,170,255,.18) 70%,rgba(0,0,0,0) 100%);
  animation: az-flare 10s ease-in-out infinite;
  /* Eigene Ebene: so wird der 32-px-Blur EINMAL gerastert und die Animation
     aendert nur noch die Deckkraft, statt den Blur je Frame neu zu rechnen. */
  will-change: opacity, transform;
}
.az-bloom {
  position: absolute; left: -40px; top: 32.6%; width: 820px; height: 420px;
  pointer-events: none; filter: blur(90px);
  background: radial-gradient(closest-side,rgba(255,45,45,.16),rgba(255,45,45,0) 72%);
  animation: az-bloom 11s ease-in-out infinite;
  will-change: opacity;   /* wie beim Flare: 90-px-Blur einmal rastern */
}
.az-grain {
  position: absolute; inset: -60px; pointer-events: none; opacity: .5;
  background-image: radial-gradient(rgba(255,255,255,.075) .5px,rgba(0,0,0,0) .5px);
  background-size: 3px 3px; animation: az-grain 2.6s steps(6) infinite;
  will-change: transform;
}
.az-lines {
  position: absolute; inset: 0; pointer-events: none; opacity: .3;
  background-image: repeating-linear-gradient(0deg,rgba(255,255,255,.05) 0 1px,rgba(0,0,0,0) 1px 3px);
}
.az-scanwrap { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.az-scan {
  position: absolute; left: 0; top: 0; width: 100%; height: 24%;
  background: linear-gradient(180deg,rgba(255,255,255,0),rgba(255,255,255,.05),rgba(255,255,255,0));
  animation: az-scan 8.5s cubic-bezier(.35,0,.25,1) 1.6s infinite;
}
.az-motes { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.az-motes span { position: absolute; border-radius: 50%; }
.az-motes span:nth-child(1){left:18%;bottom:22%;width:3px;height:3px;background:rgba(255,255,255,.7);animation:az-mote 14s linear infinite}
.az-motes span:nth-child(2){left:33%;bottom:14%;width:2px;height:2px;background:rgba(255,255,255,.55);animation:az-mote 18s linear 2.6s infinite}
.az-motes span:nth-child(3){left:49%;bottom:30%;width:2.5px;height:2.5px;background:rgba(255,222,192,.65);animation:az-mote 16s linear 5.4s infinite}
.az-motes span:nth-child(4){left:66%;bottom:18%;width:2px;height:2px;background:rgba(255,255,255,.5);animation:az-mote 20s linear 1.3s infinite}
.az-motes span:nth-child(5){left:79%;bottom:26%;width:3px;height:3px;background:rgba(196,228,255,.55);animation:az-mote 15s linear 7.6s infinite}

/* Ecken-Klammern */
.az-ecke { position: absolute; width: 52px; height: 52px; z-index: 7; pointer-events: none; }
.az-ecke-lo { left: var(--az-rand); top: 52px; border-left: 1px solid rgba(255,255,255,.28); border-top: 1px solid rgba(255,255,255,.28); animation: az-corner 1.1s cubic-bezier(.16,1,.3,1) 1.5s both; }
.az-ecke-ro { right: var(--az-rand); top: 52px; border-right: 1px solid rgba(255,255,255,.28); border-top: 1px solid rgba(255,255,255,.28); animation: az-corner 1.1s cubic-bezier(.16,1,.3,1) 1.6s both; }
.az-ecke-lu { left: var(--az-rand); bottom: 52px; border-left: 1px solid rgba(255,255,255,.28); border-bottom: 1px solid rgba(255,255,255,.28); animation: az-corner 1.1s cubic-bezier(.16,1,.3,1) 1.7s both; }
.az-ecke-ru { right: var(--az-rand); bottom: 52px; border-right: 1px solid rgba(255,255,255,.28); border-bottom: 1px solid rgba(255,255,255,.28); animation: az-corner 1.1s cubic-bezier(.16,1,.3,1) 1.8s both; }

/* --- Buehnen-Raster: Copy oben, Stat-Streifen unten ---------------------- */
/* Grid statt zweier absoluter Positionen: so garantiert der Browser, dass
   Copy und Stat-Streifen sich nie ueberlagern, egal wie flach das Fenster ist.
   Die Polster entsprechen bei 920 px Hoehe exakt den 258 px / 78 px der Vorlage. */
/* Das Kopfpolster war fest an die Buehnenhoehe gekoppelt (.2804), die Copy
   waechst aber flacher als das Polster. Unterhalb der Vorlage-Hoehe lief die
   Copy deshalb aus ihrer 1fr-Zeile heraus UEBER den Stat-Streifen: bei
   1440x800 lagen "Marktplatz entdecken" und "Termin anfragen" auf "15 / Jahre
   Erfahrung" und "A->Z / Alle Marken" (gemessen 76 px Ueberlappung, bei
   1440x700 sogar 118 px). Ein Grid verhindert das NICHT — eine minmax(0,1fr)-
   Zeile schrumpft, ihr Inhalt laeuft trotzdem weiter.
   Der zweite Term ist die gemessene Obergrenze (Serie 602-920 px, Solver
   _finetune/ft-solver.mjs: nutzbar ~ .7125*h - 396) mit Sicherheitsabstand,
   min() nimmt wie ueberall auf dieser Buehne, was zuerst eng wird. Bei
   var(--az-h) = 920 (Vorlage) gewinnt der erste Term und es bleiben exakt die
   258 px der Vorlage stehen — dort aendert sich nichts. */
.az-stage {
  position: absolute; inset: 0; z-index: 6;
  display: grid; grid-template-rows: minmax(0,1fr) auto;
  padding: min(clamp(84px, calc(var(--az-h) * .2804), 258px),
               max(0px, calc(var(--az-h) * .9 - 568px)))
           var(--az-rand)
           clamp(26px, calc(var(--az-h) * .0848), 78px);
}
.az-copy { align-self: start; max-width: 100%; }

.az-eyebrow {
  display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap;
  animation: az-fade .8s cubic-bezier(.2,.8,.2,1) 1.1s both;
}
.az-eyebrow .strich { width: 34px; height: 1px; background: var(--az-rot); flex: none; }
.az-eyebrow .txt {
  font: 700 10px/1 var(--font-mono); letter-spacing: .3em; text-transform: uppercase;
  color: rgba(255,255,255,.92);
  text-shadow: 0 1px 6px rgba(0,0,0,.9), 0 0 22px rgba(0,0,0,.85);
}
.az-eyebrow .est {
  padding: 5px 9px; border: 1px solid rgba(255,255,255,.3);
  font: 700 8.5px/1 var(--font-mono); letter-spacing: .22em; text-transform: uppercase;
  color: rgba(255,255,255,.78); background: rgba(7,7,9,.5);
}

/* --- Headline ------------------------------------------------------------ */
.az-h1 {
  font-family: Archivo, var(--font-body), sans-serif;
  font-weight: 900; font-style: italic; font-stretch: 78%;
  text-transform: uppercase; letter-spacing: -.03em;
  margin: 26px 0 0;
}
.az-clip { display: block; overflow: hidden; width: max-content; max-width: 100%; padding-right: .14em; }
.az-line { display: block; white-space: nowrap; color: #fff; }
.az-clip-1 { padding-bottom: .06em; }
.az-clip-1 .az-line {
  font-size: var(--az-t1); line-height: .9;
  text-shadow: 0 22px 60px rgba(0,0,0,.6);
  animation: az-rise 1.1s cubic-bezier(.16,1,.3,1) 1.1s both;
}
.az-row { display: flex; align-items: baseline; gap: .2em; width: max-content; max-width: 100%; margin-top: .04em; }
.az-clip-2, .az-clip-3 { padding-bottom: .09em; }
.az-clip-2 .az-line, .az-clip-3 .az-line {
  font-size: var(--az-t2); line-height: .88; letter-spacing: -.032em;
  animation: az-rise 1.2s cubic-bezier(.16,1,.3,1) 1.28s both;
}
.az-outline { color: transparent; -webkit-text-stroke: 1.5px rgba(255,255,255,.66); }
.az-foto { color: #fff; }
.az-rot { position: relative; color: var(--az-rot); }
.az-strich {
  position: absolute; left: .02em; right: .1em; bottom: .05em; height: 6px;
  background: linear-gradient(90deg,var(--az-rot) 70%,rgba(255,45,45,0));
  transform-origin: left; animation: az-underline .9s cubic-bezier(.16,1,.3,1) 2.35s both;
}

/* --- Lede + CTAs --------------------------------------------------------- */
.az-unten { margin-top: 30px; animation: az-blur 1.1s cubic-bezier(.2,.8,.2,1) 1.6s both; }
.az-lede {
  margin: 0; max-width: 480px;
  font: 400 18px/1.7 var(--font-body); color: rgba(255,255,255,.92);
  text-wrap: pretty;
  /* Die Lede steht auf dem um 1.36 aufgehellten Foto. Der Schatten ist hier
     kein Effekt, sondern der Kontrast-Traeger: gemessen gegen die echten
     Pixel hebt er die hellste Stelle wieder ueber 4,5:1. */
  text-shadow: 0 1px 4px rgba(0,0,0,.92), 0 2px 18px rgba(0,0,0,.8);
}
.az-cta { display: flex; width: max-content; max-width: 100%; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 32px; }
.az-btn {
  display: flex; flex: none; white-space: nowrap; align-items: center; gap: 12px;
  font: 700 12.5px/1 var(--font-body); letter-spacing: .16em; text-transform: uppercase;
  will-change: transform;
}
.az-btn .pfeil { font-size: 15px; }
.az-btn-rot {
  padding: 20px 30px; background: var(--az-rot); color: #fff;
  box-shadow: 0 18px 44px rgba(255,45,45,.36);
  transition: box-shadow .3s, background .3s;
}
.az-btn-rot:hover { background: #ff4444; box-shadow: 0 22px 54px rgba(255,45,45,.5); }
.az-btn-geist {
  padding: 19px 28px; border: 1px solid rgba(255,255,255,.34);
  background: rgba(255,255,255,.06);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  color: #fff; transition: transform .3s, background .3s, border-color .3s;
}
.az-btn-geist:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.6); transform: translateY(-2px); }
.az-btn:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

/* --- Stat-Streifen ------------------------------------------------------- */
.az-stats {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 40px;
  padding-top: 26px; border-top: 1px solid rgba(255,255,255,.14);
  animation: az-fade 1s cubic-bezier(.2,.8,.2,1) 2s both;
}
.az-statgruppe { display: flex; align-items: flex-start; gap: clamp(24px,3.6vw,52px); }
.az-trenner { width: 1px; height: 58px; background: rgba(255,255,255,.12); flex: none; align-self: center; }
.az-zahl {
  display: flex; align-items: baseline; gap: 2px;
  font-family: Archivo, var(--font-body), sans-serif; font-weight: 900; font-style: italic;
  font-size: var(--az-tz); line-height: 1; color: #fff;
}
.az-zahl .plus { color: var(--az-rot); }
.az-zahl.gold { color: #f0c14b; gap: 6px; }
.az-zahl.gold .stern { font-size: .565em; }
.az-zahl .pfeilchen { font-size: .435em; color: var(--az-rot); }
/* 9px war die Vorlage; als BESCHRIFTUNG der Beleg-Zahlen ist das unter der
   Lesbarkeitsgrenze (Review 20/9 §2, Graesslich-Gesetz F1: >=11px fuer
   lesbare Information). Das Mono-Tracking wandert dabei von .24em auf .18em —
   sonst waechst die Zeile staerker als die Schrift und die Vorlagen-Optik
   ("stiller, breit gesperrter Kleinsttext") kippt in Morsecode. */
.az-label {
  margin-top: 10px; font: 500 11px/1.5 var(--font-mono);
  letter-spacing: .18em; text-transform: uppercase; color: rgba(255,255,255,.72);
}
.az-beleg { display: flex; flex-direction: column; align-items: flex-end; gap: 9px; text-align: right; }
/* Kleinster Text der Seite (8,5/7,5 px). Auf 10 px gehoben — die Untergrenze
   fuer Deko-nahe, aber lesbare Zeilen (Review 20/9 §2); Tracking .24em -> .2em
   aus demselben Grund wie bei .az-label. */
.az-credit { font: 500 10px/1.5 var(--font-mono); letter-spacing: .2em; text-transform: uppercase; color: rgba(255,255,255,.62); }
.az-sterne { display: flex; align-items: center; gap: 14px; }
.az-sterne .sterne { font-size: 14px; letter-spacing: .1em; color: #f0c14b; }
.az-sterne .txt { font: 400 12px/1 var(--font-body); color: rgba(255,255,255,.78); white-space: nowrap; }
.az-sterne .pfeil-knopf {
  display: grid; place-items: center; width: 44px; height: 44px;
  border: 1px solid rgba(255,255,255,.3); font-size: 15px; color: #fff;
  transition: background .25s, transform .25s, border-color .25s;
}
.az-sterne .pfeil-knopf:hover { background: var(--az-rot); border-color: var(--az-rot); transform: translateX(3px); }
.az-sterne .pfeil-knopf:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
@media (max-width: 1199px) { .az-sterne .txt { display: none; } }

/* --- Schwebende Beigaben ------------------------------------------------- */
.az-chip {
  position: absolute; right: var(--az-rand); top: clamp(76px, calc(var(--az-h) * .2022), 186px);
  z-index: 6; display: inline-flex; align-items: center; gap: 10px; padding: 11px 17px;
  background: rgba(9,9,11,.72); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(46,204,113,.3);
  animation: az-float 6s ease-in-out infinite, az-fade .8s ease 1.4s both;
}
.az-chip .punkt { width: 7px; height: 7px; border-radius: 50%; background: #2ecc71; flex: none; animation: az-pulse 2.4s ease-in-out infinite; }
/* ausserhalb der Oeffnungszeiten (Klasse setzt site.js aus den echten Zeiten) */
.az-chip.ist-zu .punkt { background: #8a8a8a; animation: none; box-shadow: none; }
/* Der Chip traegt den echten Oeffnungsstatus — Information, kein Ornament.
   9,5/8,5 px -> 11 px (F1-Untergrenze), Tracking .22em -> .18em, damit der
   Chip nicht breiter wird als die Buehne unter ihm haelt. */
.az-chip .txt { font: 700 11px/1 var(--font-mono); letter-spacing: .18em; text-transform: uppercase; color: #fff; }

.az-seite {
  position: absolute; right: 30px; top: 50%; z-index: 7;
  display: flex; flex-direction: column; align-items: center; gap: 20px;
  transform: translateY(-50%); pointer-events: none;
  animation: az-in 1.1s ease 2s both;
}
.az-seite .txt {
  font: 500 9px/1 var(--font-mono); letter-spacing: .34em; text-transform: uppercase;
  color: rgba(255,255,255,.62); writing-mode: vertical-rl;
  text-shadow: 0 0 10px rgba(0,0,0,.9);
}
.az-seite .schiene { position: relative; width: 1px; height: 74px; background: rgba(255,255,255,.16); overflow: hidden; }
.az-seite .schiene i { position: absolute; inset: 0; background: linear-gradient(to bottom,rgba(255,45,45,0),var(--az-rot)); animation: az-cue 2.4s ease-in-out infinite; }
@media (max-width: 1439px) { .az-seite { display: none; } }

/* --- Letterbox + Intro --------------------------------------------------- */
.az-bar { position: absolute; left: 0; width: 100%; height: 34px; z-index: 9; background: #050506; }
.az-bar-t { top: 0; }
.az-bar-b { bottom: 0; }
.az-bar > i { position: absolute; left: 0; width: 100%; height: 100%; background: #050506; box-shadow: 0 0 60px 30px #050506; display: block; }
.az-bar-t > i { top: 0; transform-origin: top; animation: az-shutter-t 1.6s cubic-bezier(.16,1,.3,1) 1.1s both; }
.az-bar-b > i { bottom: 0; animation: az-shutter-b 1.6s cubic-bezier(.16,1,.3,1) 1.1s both; }

/* --- Nav am Seitenanfang durchsichtig (Regie 7) -------------------------- */
/* Kein Eingriff in site.js: nur eine Klasse auf <html>, die das Inline-JS
   unten bei scrollY < 40 setzt. */
html.nav-klar .nav {
  background: transparent; border-bottom-color: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* ======================= 3b MOBIL (unter 1024) =========================== */
/* Text NICHT mehr im Bild: oben ein Bild-Band, darunter die Typo auf Schwarz.
   Das ersetzt den frueheren Mobil-Hero (Text-auf-Bild) vollstaendig. */
@media (max-width: 1023px) {
  .az-hero {
    height: auto;
    --az-t1: clamp(34px, 10.8vw, 62px);   /* 42px @390 */
    --az-t2: clamp(46px, 14.4vw, 84px);   /* 56px @390 */
    --az-tz: clamp(26px, 7.7vw, 44px);    /* 30px @390 */
  }
  /* Gemessener Befund: bei 200 % Nutzerschrift auf 390 px verlor dieses Band
     140 px Hoehe hinter dem `overflow:hidden` (WCAG 1.4.4). Nachgerechnet sind
     diese 140 px die Deko-Ebene `.az-bloom`: mobil top:38 % von 452 px = 172,
     plus 420 px Hoehe = 592 — genau 140 px unter der Bandkante. Diese Ebene
     SOLL beschnitten werden, dafuer ist der Rahmen da (auch `.az-grain` und
     `.az-fuss` stehen bewusst auf negativen Insets). Der Ueberlauf wurde dem
     Chip zugeschrieben, weil er der einzige TEXT im Band ist.
     Beschnitten werden darf er trotzdem nie: er traegt den Oeffnungsstatus —
     die Information, wegen der viele die Seite ueberhaupt aufrufen.
     Darum zwei Aenderungen, die bei normaler Schrift NICHTS am Bild aendern:
     (1) die 452 px sind jetzt ein BODEN (min-height) statt einer Decke,
     (2) der Chip liegt als einziges Kind im Fluss — alle anderen Ebenen sind
         absolut positioniert, ein `align-items:flex-end`-Flex-Kontext setzt
         ihn deckungsgleich dorthin, wo ihn vorher `bottom:16px; left:20px`
         hatte. Waechst seine Schrift, waechst das Band jetzt mit, statt zu
         kappen. */
  .az-band {
    position: relative; inset: auto; width: 100%;
    min-height: 452px;
    display: flex; align-items: flex-end;
  }
  .az-bild img { object-position: 55% 50%; filter: brightness(1.38) contrast(1.1) saturate(1.05); }
  .az-fuss, .az-seite, .az-ecke, .az-bar { display: none; }
  .az-flare { top: 42%; }
  .az-bloom { top: 38%; }

  .az-stage {
    position: static; display: block;
    background: #08080a; padding: 26px 20px 32px;
  }
  .az-eyebrow .est { display: none; }        /* 3b: nur Linie + eine Zeile */
  .az-eyebrow .txt { font-size: 8.5px; letter-spacing: .28em; text-shadow: none; }
  .az-eyebrow .strich { width: 22px; }
  .az-h1 { margin-top: 18px; }
  /* Drei eigene Zeilen mit gestaffeltem Einlauf (Vorlage 1.05 / 1.19 / 1.33s) */
  .az-row { display: block; width: auto; margin-top: 0; }
  /* Ein Wert je animation-name: der zweite (1.85s) stammt aus einer frueher
     hier stehenden zweiten Animation und wurde von der Spec ohnehin verworfen. */
  .az-clip-1 .az-line { animation-delay: 1.05s; }
  .az-clip-2 .az-line { animation-delay: 1.19s; }
  .az-clip-3 .az-line { animation-delay: 1.33s; }
  .az-clip-1 .az-line { font-size: var(--az-t1); }
  .az-strich { height: 4px; }
  .az-lede { font: 400 15.5px/1.7 var(--font-body); max-width: none; text-shadow: none; color: rgba(255,255,255,.8); }
  .az-unten { margin-top: 20px; }
  .az-cta { display: grid; grid-template-columns: 1fr; width: auto; gap: 10px; margin-top: 24px; }
  .az-btn { justify-content: center; height: 56px; padding: 0 24px; }
  .az-stats {
    display: block; margin-top: 28px; padding-top: 18px;
    border-top: 1px solid rgba(255,255,255,.14);
  }
  .az-statgruppe { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; align-items: start; }
  .az-trenner { display: none; }
  /* Mobil war die Beschriftung auf 8 px heruntergerechnet — der kleinste
     lesbare Text der Startseite und genau die Stelle, die auf dem Handy
     zuerst durchfaellt. Jetzt gilt der Desktop-Wert auch hier; das Tracking
     geht dafuer auf .12em, weil eine Rasterzelle @390 nur 109 px breit ist. */
  .az-label { font-size: 11px; letter-spacing: .12em; margin-top: 7px; }
  .az-beleg { align-items: flex-start; text-align: left; margin-top: 18px; }
  .az-credit { font-size: 10px; letter-spacing: .16em; }
  .az-sterne { display: none; }
  /* Der Chip sitzt im Bild-Band unten links — jetzt im Fluss statt absolut
     (Begruendung am `.az-band` oben). `position:relative` statt `static`, weil
     sonst das `z-index:6` der Grundregel wirkungslos waere und der Chip unter
     die Schleier- und Korn-Ebenen rutschte. Die Raender ersetzen 1:1 die
     frueheren Offsets; `margin-right` ist neu und haelt den Chip bei sehr
     grosser Schrift 20 px von der rechten Kante weg, statt ihn dagegen zu
     druecken — bei normaler Schrift ist er ~300 px breit und beruehrt sie nie. */
  .az-chip { position: relative; inset: auto; margin: 0 20px 16px; }
  html.nav-klar .nav { background: transparent; }
}

/* =================== MARKEN-LEISTE unter dem Hero ========================
   Ersetzt das fruehere Text-Laufband (Reparatur/Inspektion/HU/AU ...). Dessen
   Leistungen stehen unveraendert in den sechs Service-Kacheln weiter unten, es
   geht also keine Information verloren — und zwei Laufbaender auf EINER Seite
   (hier + Partner ganz unten) lasen sich beide als blosse Deko. Diese Leiste
   traegt stattdessen die Aussage, nach der Kunden laut Inhaber am haeufigsten
   fragen: AZB setzt den Serviceheft-Eintrag bei zehn Marken selbst.

   Bauart bewusst aus derselben Familie wie die Partner-Leiste (Monochrom-Logos
   auf dunklem Band, Haarlinien-Zellen, weiche Kanten-Maske), aber flacher und
   mit FESTEM Label links: ein reines Logo-Band waere Dekoration — das Label
   macht daraus Information, und die Aussage steht als echter Text da, nicht
   nur in alt-Attributen.

   Die Hoehe haengt an --az-mqh, weil der Hero genau diesen Wert von 100svh
   abzieht: Hero + Leiste fuellen zusammen exakt einen Schirm. Wer die Hoehe
   hier aendert, muss --az-mqh oben mitziehen, sonst kippt der erste Schirm.

   Die Logos sind SVG (alle zehn zusammen ~14 KB) und tragen ihre optische
   Groesse als --h je Zelle. Gleiche Pixelhoehe waere hier falsch: eine breite
   Wortmarke (AMG, Verhaeltnis 10:1) wirkt neben einem runden Zeichen (Stern,
   1:1) bei gleicher Hoehe massiv groesser. --h ist deshalb pro Marke optisch
   eingemessen, nicht gerechnet — und wird mobil mit EINEM Faktor gezogen. */
.az-marken {
  position: relative; height: var(--az-mqh, 108px);
  display: grid; grid-template-columns: auto minmax(0,1fr); align-items: stretch;
  background: #0b0b0c;
  border-top: 1px solid rgba(225,6,0,.55);
  border-bottom: 1px solid var(--border-1);
  overflow: hidden;
  --mk-faktor: 1;
}
.az-mk-label {
  display: flex; flex-direction: column; justify-content: center; gap: 8px;
  flex: none; padding: 0 clamp(20px,2.4vw,32px) 0 clamp(24px,4.44vw,64px);
  border-right: 1px solid rgba(255,255,255,.1);
}
.az-mk-label .zeile { display: flex; align-items: center; gap: 10px; margin: 0; }
.az-mk-label .strich { width: 26px; height: 2px; background: var(--red); flex: none; }
/* 10px = F1-Untergrenze fuer gesperrten Kleinsttext, wie .az-credit im Hero
   darueber. Die Zeile ist Beschriftung, nicht Fliesstext. */
.az-mk-label .klein {
  font: 700 10px/1 var(--font-mono); letter-spacing: .26em; text-transform: uppercase;
  color: #fff; white-space: nowrap;
}
/* text-wrap:balance verteilt die drei Zeilen gleichmaessig, statt das letzte
   Wort ("lueckenlos.") allein in eine vierte Zeile zu schieben. Dieselbe
   Familie wie das text-wrap:pretty der Hero-Lede darueber; Browser ohne
   Unterstuetzung brechen einfach wie bisher um. */
.az-mk-label .satz {
  margin: 0; font: 400 12.5px/1.4 var(--font-body); color: var(--text-secondary);
  max-width: 44ch; text-wrap: balance;
}

/* Die Maske ist bewusst in PIXELN gerechnet, nicht in Prozent: rechts muss sie
   genau dort ausgelaufen sein, wo der Pause-Knopf beginnt (--mk-stop), sonst
   schiebt sich ein voll deckendes Logo unter den Knopf und beide ueberlagern
   sich. Bei Prozentwerten wandert dieser Punkt mit der Fensterbreite. */
.az-mk-band {
  position: relative; overflow: hidden; display: flex; align-items: center;
  --mk-stop: 52px;
  -webkit-mask-image: linear-gradient(90deg,rgba(0,0,0,0) 0,#000 26px,#000 calc(100% - var(--mk-stop) - 72px),rgba(0,0,0,0) calc(100% - var(--mk-stop)));
          mask-image: linear-gradient(90deg,rgba(0,0,0,0) 0,#000 26px,#000 calc(100% - var(--mk-stop) - 72px),rgba(0,0,0,0) calc(100% - var(--mk-stop)));
}
/* flex:none auf BEIDEN Ebenen ist Pflicht, nicht Kosmetik: .az-mk-spur und
   .az-mk-satz sind selbst Flex-Elemente (.az-mk-band ist ein Flex-Container)
   und wuerden mit dem Vorgabewert flex-shrink:1 unter ihre Inhaltsbreite
   gedrueckt. Gemessen bei 768 px: beide Saetze schrumpften, der zweite schob
   sich in den ersten und die Logos lagen uebereinander. width:max-content
   allein reicht dagegen NICHT — Schrumpfen sticht die Wunschbreite. */
.az-mk-spur { display: flex; flex: none; width: max-content; align-items: stretch; animation: az-mk 52s linear infinite; }
.az-mk-satz { display: flex; flex: none; align-items: stretch; }
/* Zellenbreite folgt dem Inhalt (Polster links/rechts) statt einer festen
   Zahl: bei fester Breite muss sich eine 10:1-Wortmarke wie AMG in dieselbe
   Spalte quetschen wie der runde Stern und wird dadurch unlesbar duenn.
   Gleiches OPTISCHES Polster ist hier das richtige Raster, nicht gleiche
   Spaltenbreite. */
.az-mk-zelle {
  display: grid; place-items: center; flex: none;
  padding: 0 clamp(22px,2vw,30px);
  border-right: 1px solid rgba(255,255,255,.06);
}
.az-mk-zelle img {
  width: auto; height: calc(var(--h) * var(--mk-faktor) * 1px);
  opacity: .85; transition: opacity .3s, transform .3s;
}
/* Anhalten bei Zeigergeraeten oder per Schalter.
   Hier stand zusaetzlich :focus-within — das war ein Fehler und ist gemessen:
   ein Mausklick auf den Schalter LAESST den Fokus auf ihm liegen, damit blieb
   :focus-within dauerhaft wahr und das Band stand fest, egal was der Schalter
   sagte (aria-pressed=false, Spur trotzdem paused). Der Schalter war damit
   einweg. Er ist ohnehin das WCAG-2.2.2-Mittel; im Band selbst gibt es kein
   weiteres fokussierbares Element, die Regel hatte also nur Nachteile. */
.az-marken:hover .az-mk-spur,
.az-marken.mk-pause .az-mk-spur { animation-play-state: paused; }
@media (hover: hover) { .az-mk-zelle:hover img { opacity: 1; transform: scale(1.05); } }
@keyframes az-mk { from { transform: translateX(0) } to { transform: translateX(-50%) } }

/* Pause-Schalter: WCAG 2.2.2 (Pause, Stop, Hide) — Bewegung, die laenger als
   5 s automatisch laeuft, braucht eine Bedienmoeglichkeit. Hover allein deckt
   Tastatur und Touch nicht ab; dieselbe Begruendung wie bei .halle-pause. Er
   sitzt am rechten Bandende auf einem eigenen Verlauf, damit er auch ueber
   einem hellen Logo lesbar bleibt. Bei reduzierter Bewegung entfaellt er, weil
   dann ohnehin nichts laeuft. */
.az-mk-stop {
  position: absolute; right: 0; top: 0; bottom: 0; z-index: 3;
  width: 52px; display: grid; place-items: center;
  border: 0; border-left: 1px solid rgba(255,255,255,.08);
  background: linear-gradient(90deg,rgba(11,11,12,0),#0b0b0c 42%);
  color: rgba(255,255,255,.55); cursor: pointer;
  transition: color .25s;
}
.az-mk-stop:hover { color: #fff; }
.az-mk-stop:focus-visible { outline: 2px solid var(--red); outline-offset: -3px; }
.az-mk-stop .glyph { display: inline-flex; gap: 3px; }
.az-mk-stop .bar-l, .az-mk-stop .bar-r { display: block; width: 3px; height: 11px; background: currentColor; }
.az-mk-stop[aria-pressed="true"] .bar-r { display: none; }
.az-mk-stop[aria-pressed="true"] .bar-l {
  width: 0; height: 0; background: none;
  border-left: 9px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent;
}
@media (prefers-reduced-motion: reduce) { .az-mk-stop { display: none; } }

/* ---- Mobil: bewusst klein. Auf dem Handy soll die Leiste eine ruhige Zeile
   sein und kein Block — Label oben (zwei kurze Zeilen), Logos darunter in
   einer 58-px-Spur, alle zehn optischen Hoehen mit Faktor .58 gezogen. Der
   Hero steht hier ohnehin auf height:auto, --az-mqh spielt mobil keine Rolle. */
@media (max-width: 1023px) {
  .az-marken {
    height: auto; --mk-faktor: .62;
    grid-template-columns: minmax(0,1fr); grid-template-rows: auto 62px;
  }
  /* Die drei breiten Wortmarken (AMG 10:1, Audi 2,9:1, MINI 2,3:1) vertragen
     die Handy-Reduktion nicht im selben Mass wie die runden Zeichen: sie sind
     ohnehin flach, und derselbe Faktor macht aus AMG einen 6-px-Strich
     (gemessen). Sie bekommen deshalb einen eigenen, milderen Faktor — die
     Breite haben sie dank inhaltsbreiter Zellen dafuer zur Verfuegung. */
  .az-mk-zelle.breit { --mk-faktor: .8; }
  .az-mk-label {
    border-right: 0; border-bottom: 1px solid rgba(255,255,255,.08);
    padding: 11px 20px 10px; gap: 4px;
  }
  .az-mk-label .klein { font-size: 9.5px; letter-spacing: .2em; }
  .az-mk-label .strich { width: 18px; }
  .az-mk-label .satz { font-size: 11.5px; line-height: 1.35; max-width: none; }
  .az-mk-zelle { padding: 0 15px; }
  .az-mk-spur { animation-duration: 32s; }
  .az-mk-stop { width: 40px; top: auto; height: 58px; }
  .az-mk-band { --mk-stop: 40px; }
}

/* ======================= Bewegungs-Sperre (Regie 3) ===================== */
/* Pflicht, die Vorlage hat keine. Wichtig: die Intro-Vorhaenge und die
   Letterbox-Innenblenden laufen mit fill-mode "both" — ein blosses
   animation:none wuerde sie im Anfangszustand STEHEN lassen, also den Hero
   zudecken. Sie muessen deshalb ausgehaengt werden, nicht nur angehalten. */
@media (prefers-reduced-motion: reduce) {
  .az-hero *, .az-hero *::before, .az-hero *::after,
  .az-marken, .az-mk-spur {
    animation: none !important;
    transition: none !important;
  }
  .az-bar > i, .az-scan { display: none !important; }
  .az-strich { transform: scaleX(1); }
  .az-bild, .az-fuss { transform: none !important; }
}

/* Services grid — GRAVIERTE PLAKETTEN (Kachel-Design v2, Inhaber-Vorlage 2026-08-03)
   ---------------------------------------------------------------------------
   Drei bewusste Abweichungen von der Vorlage, jede mit Grund:
   1) Die Vorlage rechnet jede Alpha-Stufe in rgba(225,29,38,x). Auf dieser
      Seite ist der Akzent --red #e10600. Damit die Ein-Akzent-Doktrin haelt,
      laufen alle Alpha-Stufen ueber --red-rgb (exakt die Kanaele von --red)
      statt ueber einen zweiten Hexwert; solide Flaechen nehmen direkt
      var(--red)/var(--red-bright). Der Farbunterschied ist unsichtbar, aber
      es gibt jetzt nur noch EINE Quelle fuer den Akzent.
   2) Die Kartenkante nimmt var(--border-1) statt der Vorlage-Konstante
      rgba(255,255,255,.075). Auf tuning.html ist --border-1 gemessen auf .14
      angehoben (Karten muessen ueber der Platine eine Kante behalten) — eine
      harte .075 haette genau diese Entscheidung wieder kassiert.
   3) grid-auto-rows:1fr statt einer gerechneten min-height als einziger
      Hoehen-Garant: das haelt alle sechs Kacheln auch dann exakt gleich hoch,
      wenn ein Text nachtraeglich laenger wird oder das Raster einspaltig
      steht (390 px, wo jede Zeile sonst ihrer eigenen Hoehe folgt).
      Die min-height bleibt als Untergrenze fuer die Plaketten-Proportion.   */

.services-grid {
  display: grid; gap: 16px;
  grid-template-columns: 1fr;
  grid-auto-rows: 1fr;
}
@media (min-width: 640px) { .services-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .services-grid { grid-template-columns: repeat(3, 1fr); } }

/* Die Kachel selbst (.azb-card / -edge / -halo / -head / -plate / -num /
   -title / -body / -foot / -rule) steht seit 2026-08-04 in shared.css am
   Dateiende — sie war hier und in tuning.html zeilengleich doppelt (Review 4
   F2). Hier bleibt nur, was DIESE Seite eigen hat: das Raster und der CTA,
   denn nur hier sind die Kacheln Links. */
/* Das kleinste klickbare Wort der Seite stand auf 9,5 px. Interaktives gehoert
   nach dem Lesbarkeits-Gesetz (F1) auf >=12 px — Review 20/9 §2, Prio HOCH.
   Tracking .16em -> .12em, damit "Mehr erfahren" in der Kachel nicht umbricht. */
.azb-cta {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); text-transform: uppercase;
  letter-spacing: .12em; font-size: 12px;
  color: rgba(255,255,255,.62);
  transition: color .3s;
}
.azb-card:hover .azb-cta { color: var(--red-bright); }
.azb-arrow {
  display: inline-flex; color: var(--red);
  transition: transform .35s cubic-bezier(.2,.7,.2,1), color .3s;
}
.azb-card:hover .azb-arrow { transform: translateX(5px); color: var(--red-bright); }

/* Featured marketplace section */
.featured-grid {
  display: grid; gap: 24px;
  grid-template-columns: 1fr;
}
@media (min-width: 768px)  { .featured-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .featured-grid { grid-template-columns: repeat(3, 1fr); } }

/* Mobile horizontal slider — only <768px */
@media (max-width: 767px) {
  .featured-grid {
    display: flex;
    grid-template-columns: none;
    gap: 16px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scroll-padding: 0 24px;
    padding: 4px 24px 8px;
    margin: 0 -24px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none; /* Firefox */
  }
  .featured-grid::-webkit-scrollbar { display: none; }
  .featured-grid > * {
    flex: 0 0 84%;
    max-width: 320px;
    scroll-snap-align: center;
  }
  .featured-grid > *:first-child { scroll-snap-align: start; }
  .featured-grid > *:last-child  { scroll-snap-align: end; }
  .featured-grid:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; border-radius: var(--r-md); }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .featured-grid { scroll-behavior: auto; }
}

/* CTA-card at end of mobile slider — mobile-only */
.veh-card.veh-cta {
  background: linear-gradient(160deg, var(--red), var(--red-deep));
  border: 1px solid var(--red-bright);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 28px 26px;
  min-height: 380px;
  text-decoration: none;
  color: #fff;
  box-shadow: var(--shadow-red);
}
.veh-card.veh-cta:hover {
  transform: translateY(-4px);
  border-color: #fff;
  background: linear-gradient(160deg, var(--red-bright), var(--red));
}
.veh-card.veh-cta:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.veh-card.veh-cta .cta-eye {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.22em;
  text-transform: uppercase; color: rgba(255,255,255,.85);
  margin-bottom: 12px;
}
.veh-card.veh-cta .cta-h {
  font-family: var(--font-display); font-style: italic; font-weight: 400;
  font-size: 36px; line-height: 0.95; letter-spacing: -0.02em;
  text-transform: uppercase; color: #fff;
  margin-bottom: 16px;
}
.veh-card.veh-cta .cta-count {
  font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.16em;
  color: rgba(255,255,255,.85);
  margin-bottom: 24px;
}
.veh-card.veh-cta .cta-arrow {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: #fff; color: var(--red);
  display: grid; place-items: center;
  margin-top: auto;
  align-self: flex-end;
  transition: transform .35s var(--ease-spring);
}
.veh-card.veh-cta:hover .cta-arrow { transform: translateX(6px); }
@media (min-width: 768px) { .veh-card.veh-cta { display: none !important; } }

/* Mobile-only "Wischen" hint */
.swipe-hint {
  display: none;
  margin: 12px 24px 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-muted);
}
@media (max-width: 767px) {
  .swipe-hint { display: flex; align-items: center; gap: 10px; }
}
.swipe-hint .arrow {
  display: inline-block; width: 24px; height: 1px; background: var(--red);
  position: relative;
}
.swipe-hint .arrow::after {
  content: ""; position: absolute; right: 0; top: -3px;
  border-left: 6px solid var(--red); border-top: 3px solid transparent; border-bottom: 3px solid transparent;
}
.veh-card {
  position: relative; overflow: hidden;
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: var(--r-lg);
  transition: transform .4s var(--ease-spring), border-color .35s, box-shadow .35s;
  display: flex; flex-direction: column;
}
.veh-card:hover { transform: translateY(-4px); border-color: var(--border-red); box-shadow: var(--shadow-red); }
.veh-img { aspect-ratio: 16/10; overflow: hidden; position: relative; }
.veh-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease-out); }
.veh-card:hover .veh-img img { transform: scale(1.06); }
.veh-img::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 50%, rgba(5,5,5,.65));
}
.veh-tag {
  position: absolute; top: 16px; left: 16px;
  z-index: 2;
  font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 6px 10px; border-radius: var(--r-sm);
  background: rgba(5,5,5,.7); backdrop-filter: blur(12px);
  border: 1px solid var(--border-2);
  color: var(--text-primary);
}
.veh-tag.tag-red { background: var(--red); border-color: var(--red); }
/* Gleiche Farbe wie das Reserviert-Kennzeichen im Marktplatz (.tag-reserved
   dort) — die beiden Seiten sollen dasselbe Auto gleich beschriften. */
.veh-tag.tag-reserved { background: rgba(255,176,32,.92); border-color: #ffb020; color: #1a1000; }
/* Der Textkoerper waechst mit der Karte (die Karte ist schon eine Flex-Spalte,
   er war es nicht). Ohne das endete die Preis-/CTA-Zeile dort, wo der Text
   zufaellig aufhoerte — bei zweizeiligem Modellnamen also 30 px tiefer als bei
   der Nachbarkarte, drei Preise auf drei Hoehen. Die Abstaende bleiben exakt
   gleich: die Geschwister-Margins hatten vorher keinen Kollaps-Partner. */
.veh-body { padding: 22px 24px 26px; display: flex; flex-direction: column; flex: 1 1 auto; }
.veh-make { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.24em; color: var(--text-muted); text-transform: uppercase; }
/* Zwei Zeilen sind das Format: Modell, darunter Ausstattung. Die Marktplatz-
   Daten kommen aus einem Fremd-Export, in dem einzelne Modellnamen den halben
   Datenblatt-Text tragen ("Touran 2,0 Benzin / Erdgas / Klima / Navi /
   Tempomat"). Ungeklemmt wuchs eine der drei Karten auf vier Zeilen a 30px und
   sprengte die Reihe. Geklemmt bleibt jede wohlgeformte Karte pixelgleich zu
   vorher — nur der Ausreisser wird gedeckelt. Der vollstaendige Name steht
   weiterhin im aria-label und auf der Marktplatz-Seite. */
.veh-name {
  font-family: var(--font-display); font-style: italic;
  font-size: 30px; line-height: 1; letter-spacing: -0.02em;
  text-transform: uppercase;
  margin: 8px 0 16px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
/* Ohne Umbruch-Regel zerreisst der Flex-Container die einzelne Angabe statt
   die Reihe: auf der schmalsten Karte (287 px, "247.485 km") stand das "km"
   allein in einer zweiten Zeile. Jede Angabe bleibt jetzt zusammen, umbrochen
   wird zwischen den Angaben. */
.veh-meta {
  display: flex; flex-wrap: wrap; gap: 8px 16px;
  font-size: 13px; color: var(--text-secondary);
  padding-bottom: 16px; margin-bottom: 16px;
  border-bottom: 1px dashed var(--border-1);
}
.veh-meta span { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
/* Gleiche Langnamen-Bremse wie bei .veh-name: der Platzhalter trug den vollen
   Modellstring und lief auf drei Zeilen, waehrend die Nachbarkarten eine
   brauchten. */
.veh-placeholder .ph-label > span:first-child {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.veh-foot { display: flex; justify-content: space-between; align-items: end; margin-top: auto; }
/* Dasselbe Bauteil steht auf marktplatz.html mit 26 px. Gleiche Rolle =
   ein Wert (Review 20/9 §1); 26 ist der haeufigere und der auf der Seite,
   auf der die Karten die Hauptsache sind. */
.veh-price {
  font-family: var(--font-display); font-style: italic;
  font-size: 26px; letter-spacing: -0.02em;
  color: var(--text-primary);
}
.veh-price .euro { color: var(--red); }

/* --- AUS DER HALLE: fortlaufendes Bilder-Band ---------------------------
   Seit 2026-08-03 KEIN CSS-Marquee mehr, sondern ein echter Scroll-Container:
   der Inhaber will das Band selbst bewegen koennen. translateX() ist dafuer
   ungeeignet — es laesst sich nicht anfassen. Ein overflow-x:auto-Container
   bringt Touch-Swipe (inkl. Momentum) gratis vom Browser, das Ziehen mit der
   Maus kommt aus dem Skript am Seitenende, und der Selbstlauf schiebt dort
   scrollLeft weiter statt einen Rahmen zu verschieben. Die zwei identischen
   Spuren bleiben: der Umlauf wird jetzt per scrollLeft-Umbruch bei EINER
   Spurbreite erzeugt (gleiches Prinzip, andere Mechanik).                  */
.halle {
  background: linear-gradient(180deg, var(--bg-base-2) 0%, #000 46%, var(--bg-base) 100%);
  border-top: 1px solid var(--border-1);
  overflow: hidden;              /* Sicherheitsnetz: das Band ragt nie in den Body-Scroll */
}
.halle-kopf {
  display: grid; gap: 28px;
  grid-template-columns: 1fr;
  align-items: end;
  margin-bottom: 56px;
}
@media (min-width: 1024px) {
  .halle-kopf { grid-template-columns: 1.15fr 1fr; gap: 56px; }
}
.halle-kopf .lede { max-width: 480px; }
/* Gleiche Umlaut-Kollision wie bei .cta-strip h2, hier "auf der BÜHNE steht."
   unter "Was bei uns": die roten Punkte des Ü lagen in der weissen Zeile
   (gemessen 8 px @390, 18 px @1440). .display-md bringt aus shared.css
   line-height .92 mit — das bleibt fuer alle uebrigen Ueberschriften richtig,
   nur diese eine braucht die Umlaut-Freiheit. */
.halle-kopf h2 { line-height: 1.1; }

/* Der Pause-Schalter ist kein Extra, sondern WCAG 2.2.2 (Pause, Stop, Hide):
   Bewegung, die laenger als 5s automatisch laeuft, braucht eine Bedien-
   moeglichkeit — Hover allein deckt Tastatur und Touch nicht ab. Bei
   reduzierter Bewegung steht das Band ohnehin, dann faellt der Schalter weg. */
.halle-pause {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: 22px;
  /* 9px Polster ergaben 39px Hoehe — unter der 44px-Fingerkuppe. Der Schalter
     ist auf Touch die einzige Bedienung fuer das laufende Band (WCAG 2.2.2),
     also darf er nicht der kleinste Treffer der Seite sein. */
  min-height: 44px;
  padding: 11px 16px;
  border: 1px solid var(--border-2); border-radius: 999px;
  background: var(--surface-1);
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--text-secondary);
  transition: border-color .3s, color .3s, background-color .3s;
}
.halle-pause:hover { border-color: var(--border-red); color: var(--text-primary); background: var(--surface-2); }
.halle-pause:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
.halle-pause .bar-l, .halle-pause .bar-r {
  display: block; width: 3px; height: 11px; background: var(--red-bright); border-radius: 1px;
}
.halle-pause .glyph { display: inline-flex; gap: 3px; }
.halle-pause[aria-pressed="true"] .glyph { gap: 0; }
.halle-pause[aria-pressed="true"] .bar-l {
  width: 0; height: 0; background: none; border-radius: 0;
  border-left: 9px solid var(--red-bright);
  border-top: 6px solid transparent; border-bottom: 6px solid transparent;
}
.halle-pause[aria-pressed="true"] .bar-r { display: none; }
@media (prefers-reduced-motion: reduce) { .halle-pause { display: none; } }

/* Buehne: die einzige Stelle, an der beschnitten wird. Die Maske loest die
   beiden Kanten ins Schwarz auf, statt die Kacheln hart abzusaegen.
   Gleichzeitig der Scroll-Container — deshalb overflow-x:auto statt hidden. */
.halle-buehne {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;            /* y kann in einem Scroll-Container nie 'visible' sein */
  /* Die Kacheln ragen beim Hover ueber ihren Kasten hinaus (scale 1.04 ≈ 7px je
     Seite) und werfen einen Schatten. Weil overflow-y zwangslaeufig klemmt,
     muss dafuer Polsterung stehen, sonst wird beides abgesaegt. */
  padding: 12px 0 32px;
  /* html traegt global scroll-behavior:smooth. Auf einem Container, dessen
     scrollLeft 60x pro Sekunde gesetzt wird, waere das fatal: jeder Schritt
     wuerde animiert und der Umbruch am Spurende sichtbar weggescrollt. */
  scroll-behavior: auto;
  overscroll-behavior-x: contain; /* kein Zurueck-Swipe / kein Ketten auf die Seite */
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* alte Edge */
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
}
.halle-buehne::-webkit-scrollbar { display: none; }
.halle-buehne:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; }
/* Ziehen mit der Maus: der Greif-Cursor nur dort, wo es auch eine Maus gibt.
   Waehrend des Ziehens darf nichts markiert werden, sonst haengt beim Loslassen
   eine blaue Textauswahl im Band. */
@media (hover: hover) {
  .halle-buehne { cursor: grab; }
  .halle-buehne.zieht { cursor: grabbing; }
}
.halle-buehne.zieht { user-select: none; -webkit-user-select: none; }
.halle-bild img { -webkit-user-drag: none; user-drag: none; }
/* Steht das Band (reduzierte Bewegung), faengt es links buendig an — dort
   verschwindet nichts, also darf dort auch nichts weggeblendet werden. Die
   linke Maskenkante haette sonst dauerhaft die erste Kachel abgedunkelt. */
@media (prefers-reduced-motion: reduce) {
  .halle-buehne {
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 94%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0%, #000 94%, transparent 100%);
  }
}
/* Traegt nur noch die zwei Spuren nebeneinander. Der Selbstlauf sitzt jetzt im
   Skript (scrollLeft), nicht mehr in einer CSS-Animation — sonst wuerden sich
   Transform und Nutzer-Scroll gegenseitig ueberfahren. Pause-Schalter,
   Hover-Pause und die reduced-motion-Sperre haengen dort am selben Schalter. */
.halle-lauf {
  display: flex;
  width: max-content;
}

.halle-spur {
  display: flex; align-items: flex-start;
  gap: 20px; padding-right: 20px;
  list-style: none;
}
.halle-kachel { flex: 0 0 auto; width: 380px; }
/* Der Saegezahn (jede zweite Kachel 24px tiefer) ist am 2026-08-03 auf
   Inhaber-Wunsch entfallen: "alle Kacheln exakt auf einer Höhe". Gleich hohe
   Kacheln allein haetten das nicht erfuellt — versetzt sitzende Kacheln stehen
   sichtbar NICHT auf einer Hoehe, egal wie gleich sie gebaut sind. Ober- und
   Unterkante liegen jetzt auf einer Linie. Rueckbau = eine Zeile:
   .halle-kachel:nth-child(even) { transform: translateY(24px); } */
.halle-karte {
  position: relative; overflow: hidden;
  border: 1px solid var(--border-2);
  border-radius: var(--r-xl);
  background: linear-gradient(180deg, var(--surface-1), var(--surface-2));
  /* Karten-Lift lief auf .35/.4/.45s fuer dieselbe Geste; .4s ist der
     Familien-Wert (= .veh-card, Review 20/10 Inventar 1). Kurve unveraendert. */
  transition: transform .4s var(--ease-spring), border-color .35s, box-shadow .35s;
}
@media (hover: hover) {
  .halle-kachel:hover .halle-karte {
    transform: scale(1.04);
    border-color: var(--border-red);
    box-shadow: var(--shadow-red);
  }
  .halle-kachel:hover .halle-bild img { transform: scale(1.06); }
}
.halle-bild {
  position: relative; overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
}
.halle-bild img {
  width: 100%; height: 100%; object-fit: cover;
  filter: contrast(1.03) saturate(0.96);
  /* .9s war der langsamste der vier Bildzoom-Werte — auf den Familien-Wert
     .8s gezogen (Review 20/10 Inventar 1). Kurve unveraendert. */
  transition: transform .8s var(--ease-out);
}
.halle-bild::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 58%, rgba(5,5,5,.55));
}
.halle-nr {
  position: absolute; top: 14px; left: 14px; z-index: 2;
  padding: 5px 9px; border-radius: var(--r-sm);
  background: rgba(5,5,5,.72);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-2);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.2em;
  color: var(--red-bright);
}
/* FESTE Zeilenhoehe — das ist die eigentliche Zusage an den Inhaber. Vorher
   bestimmte die Zahl der Label-Zeilen die Kachelhoehe: "Mini #74 · mit
   Startnummer im Haus" brach um, "350Z · Breitbau" nicht, und die Karten
   endeten auf unterschiedlicher Unterkante. min-height half nur nach unten.
   Mit fester height ist die Kachelhoehe rein rechnerisch:
   Bild (Breite x 0.75, per aspect-ratio) + 56px Label + 2px Rahmen — fuer
   jede Kachel identisch, unabhaengig vom Text. Zu langer Text wird nach zwei
   Zeilen abgeschnitten, statt die Karte zu dehnen. */
.halle-label {
  display: flex; align-items: center; gap: 10px;
  padding: 0 18px;
  height: 56px;
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-muted);
}
.halle-label .dot { flex: 0 0 6px; }
.halle-label > span:not(.dot) {
  min-width: 0;                  /* ohne das greift kein Abschneiden im Flex-Kind */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  line-height: 1.35;
}
.halle-label b { color: var(--text-primary); font-weight: 500; letter-spacing: 0.12em; }

@media (max-width: 767px) {
  .halle-kopf { margin-bottom: 40px; }
  .halle-spur { gap: 14px; padding-right: 14px; }
  .halle-kachel { width: 260px; }
  .halle-buehne { padding-bottom: 24px; }
  .halle-karte { border-radius: var(--r-lg); }
  /* Zweizeilige Labels sind mobil die Regel (260px Kachel) — die feste
     56px-Hoehe von oben faengt das ab und bleibt bewusst dieselbe. */
  .halle-label { padding: 0 14px; font-size: 10px; gap: 8px; }
  .halle-nr { top: 10px; left: 10px; }
}

/* About strip */
.about-strip {
  position: relative;
  background:
    radial-gradient(ellipse 50% 60% at 80% 50%, rgba(225,6,0,.18), transparent 60%),
    linear-gradient(180deg, #050505, #0a0a0a);
  border-top: 1px solid var(--border-1);
  border-bottom: 1px solid var(--border-1);
}
.about-grid {
  display: grid; gap: 64px;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 1024px) { .about-grid { grid-template-columns: 1fr 1fr; } }

/* GESICHTER-STREIFEN (2026-08-23). Steht direkt hinter dem Satz "Geführt von
   Francesco Rao — und einem Team, das Autos genauso liebt wie du" und belegt
   ihn. Vorher stand dort eine Behauptung ohne ein einziges Gesicht — genau
   die Sorte Leerstelle, die diese Seite sonst konsequent schliesst.
   Bewusst ECKIG, nicht rund: die Site ist durchgehend eckig (--r-sm/md/lg/xl),
   rund sind nur die Jahres-Plakette und der alte Avatar. Ein ueberlappender
   Kreis-Stapel waere hier ein Fremdkoerper aus einer anderen Formsprache. */
.gesichter { display: flex; align-items: center; gap: 14px; margin: 0 0 32px; text-decoration: none; flex-wrap: wrap; }
.gesichter .koepfe { display: flex; gap: 8px; flex: none; align-items: center; }
.gesichter img { display: block; width: 56px; height: 75px; object-fit: cover;
  border-radius: var(--r-md); border: 1px solid var(--border-2); filter: saturate(.9);
  transition: filter .35s var(--ease-out), border-color .35s var(--ease-out); }
/* Das Gruppenbild fuehrt die Reihe an — quer und etwas breiter als die drei
   Portraits, damit es als "das ganze Team" gelesen wird und nicht als vierte
   Person. Bewusst klein gehalten (Inhaber-Wunsch: kompakt, keine eigene
   Sektion); die grosse Fassung steht auf Ueber uns. */
.gesichter img.gruppe { width: 130px; }
.gesichter .namen { font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-secondary); line-height: 1.7; }
.gesichter .namen b { color: var(--red-bright); font-weight: 500; }
.gesichter:hover img { filter: saturate(1.05); border-color: var(--red); }
.gesichter:hover .namen { color: #fff; }
.gesichter:hover .namen b { color: #fff; }
@media (max-width: 560px) {
  .gesichter img { width: 44px; height: 59px; }
  .gesichter img.gruppe { width: 104px; }
  .gesichter .namen { font-size: 10px; letter-spacing: .1em; }
}

.about-img-wrap { position: relative; aspect-ratio: 4/3; }
.about-img-wrap .frame {
  position: absolute; inset: 0;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--border-2);
  box-shadow: var(--shadow-lg);
}
.about-img-wrap img { width: 100%; height: 100%; object-fit: cover; }
.about-img-wrap .badge {
  position: absolute; bottom: -28px; right: -28px;
  width: 168px; height: 168px;
  border-radius: 999px;
  background: var(--red);
  display: grid; place-items: center;
  font-family: var(--font-display); font-style: italic;
  font-size: 18px; line-height: 1; letter-spacing: -0.01em; text-align: center;
  text-transform: uppercase;
  color: #fff;
  box-shadow: var(--shadow-glow);
  transform: rotate(-6deg);
}
.about-img-wrap .badge .big {
  display: block;
  font-size: 64px; line-height: 1; letter-spacing: -0.04em;
  margin-bottom: 4px;
}
/* Altbefund (nicht vom Bildtausch): das um -6deg gedrehte Badge ragte bei
   right:-28px 12px ueber den Viewport und erzeugte auf 390px horizontalen
   Scroll. Zusaetzlich deckte es bei 168px auf einer 342x257-Bildflaeche das
   Motiv zu statt auf ruhiger Flaeche zu sitzen — mobil deshalb kleiner.
   Desktop bleibt in Groesse und Position unveraendert. */
@media (max-width: 767px) {
  .about-img-wrap .badge {
    right: -12px; bottom: -20px;
    width: 124px; height: 124px;
    font-size: 13px;
  }
  .about-img-wrap .badge .big { font-size: 46px; margin-bottom: 2px; }
}

/* Reviews preview */
.reviews-grid {
  display: grid; gap: 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 768px)  { .reviews-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .reviews-grid { grid-template-columns: repeat(3, 1fr); } }
.review {
  padding: 32px 28px;
  background: linear-gradient(180deg, var(--surface-1), var(--surface-2));
  border: 1px solid var(--border-1);
  border-radius: var(--r-lg);
  position: relative;
}
.review .stars { color: var(--red-bright); margin-bottom: 16px; letter-spacing: 4px; }
.review p { color: var(--text-secondary); font-size: 14.5px; line-height: 1.7; margin-bottom: 24px; }
.review footer { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--text-muted); }
.review footer .avatar {
  width: 36px; height: 36px; border-radius: 999px;
  background: linear-gradient(135deg, var(--red), var(--red-deep));
  display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: 14px;
}

/* Big CTA */
.cta-strip {
  position: relative; overflow: hidden;
  padding: 96px 0;
  text-align: center;
}
.cta-strip::before {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 80% 50% at 50% 50%, rgba(225,6,0,.35), transparent 60%),
    linear-gradient(180deg, #050505, #1a0000);
  z-index: -1;
}
/* line-height war 0.9. Anton setzt die Umlautpunkte deutlich ueber die
   Versalhoehe — bei "Wir KÜMMERN uns." unter "Fahr vorbei." standen die roten
   Punkte des Ü dadurch MITTEN in der weissen Zeile darueber (pixelgemessen
   15 px Ueberlappung @390, 35 px @1440; Messung _finetune/ft-lh.mjs). 1.05
   raeumt sie noch nicht frei (1 px Rest), ab 1.1 ist das Ink-Band sauber
   getrennt. Zeilen ohne Umlaut (z.B. "Eine Werkstatt. / Ein Versprechen.")
   waren nie betroffen und bleiben deshalb auf dem knappen Grundwert. */
/* margin-top 16px: der Schluss-CTA der Startseite war der einzige der fuenf,
   dessen Eyebrow ("BEREIT?") mit 5 px an der Headline klebte — die vier
   anderen Seiten haben 21-22 px (h2 margin: 16px auto 24px). Review 20/9 §4.
   letter-spacing -0.04em -> -0.03em: Gleichstand mit .display-md/.display-sm,
   die einzige Anzeigen-Headline der Site, die aus dem Token fiel (§6). */
.cta-strip h2 {
  font-family: var(--font-display); font-style: italic; font-weight: 400;
  font-size: clamp(48px, 8vw, 128px); line-height: 1.1; letter-spacing: -0.03em;
  text-transform: uppercase;
  margin-top: 16px;
  margin-bottom: 24px;
}
.cta-strip p { max-width: 540px; margin: 0 auto 40px; }
.cta-strip .row { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }

/* Partner-/Hersteller-Leiste: CSS lebt seit 2026-08-23 in assets/shared.css
   (die Sektion steht jetzt auch auf tuning.html). */

/* ===== Offscreen-Standby fuer CSS-Dauerlaeufer (Review 20/6 R3) ==========
   CSS-Animationen kennen kein Offscreen-Gate: der Ken-Burns am Hero laeuft
   weiter, waehrend man im Footer liest; das Partner-Band laeuft ab Load, auch
   wenn es nie im Bild war. Gemessen kostete das auf dieser Seite 1298 ms
   Main-Thread pro 10 s ABSOLUTER Ruhe (mobil, CPU 4x) = ~13 % Dauerlast.
   Ein IntersectionObserver (Skript am Seitenende) setzt den drei
   animationstragenden Bereichen diese Klasse, solange sie NICHT im Bild sind.
   `animation-play-state` friert nur ein — beim Zurueckscrollen laufen die
   Animationen an derselben Stelle weiter, nichts startet neu und nichts stirbt.
   Bewusst NICHT gegatet: Nav und Footer (dort haengt das 3D-Logo-Canvas und
   das Mobile-Menue) und `[data-reveal]` — das sind Transitions, keine
   Animations, und von dieser Regel gar nicht erfasst. */
.anim-standby,
.anim-standby *,
.anim-standby::before,
.anim-standby::after,
.anim-standby *::before,
.anim-standby *::after { animation-play-state: paused !important; }
