/* ═══════════════════════════════════════════════════════════════════════════
   teil-zzzzzz-makrobrille.css — die Bühne der Startseite mit der Makro-Brille
   ───────────────────────────────────────────────────────────────────────────
   Christopher, 23.10.2026: „eine Brille, die sich schließt … 8K Makroaufnahme …
   Videoanimation" und „Sticky Scroll … verwende das nicht … neue moderne
   Transformationen". Markup: vorlagen/teil-makrobrille.php, Skript:
   assets/js/makrobrille.js. Lädt nur in der Vorschau (Präfix teil-zzzzzz-,
   functions.php) und wirkt nur unter .mb-buehne.

   Zwei Formen:
     ab 1180 px  Der Film füllt die Bühne über die ganze Breite (16:9). Die Texte
                 stehen links im freien Teil des Bildes: die Brille beginnt bei
                 34,4 % der Bildbreite (gemessen über alle 191 Bilder, linkes
                 Scharnier) und reicht nie unter 73 % der Bildhöhe — darunter steht
                 die Zahlenzeile.
     darunter    Der Film oben (Telefon: der 4:3-Rahmen zeigt den rechten Teil des
                 16:9-Films, die offene Brille steht ganz darin), die Texte darunter,
                 mittig.

   Nach dem Schließen positioniert sich die Brille (Christopher, 24.10.2026: „nur
   sich schließen und dann positionieren und cool abgebildet"): der Film gleitet
   als Kamera heran, bis die geschlossene Brille mittig im freien Teil steht —
   makrobrille.js rechnet --mb-kx/--mb-ky/--mb-ks aus ihrer gemessenen Lage.

   Beim Scrollen (makrobrille.js schreibt --mb-p, 0 … 1): der Filmrahmen wird zur
   Karte — Maßstab 1 → 0,9, Ecken 0 → --mb-rund über clip-path, er hebt sich
   leicht und bekommt einen Schatten; die Texte gleiten nach oben und blenden aus
   (nur ab 1180 px, darunter liest man sie gerade). Kein position:sticky, keine
   Änderung an overflow, bewegt werden nur transform, opacity und clip-path.
   Keine neue Farbe, keine neue Schrift, kein !important.
   ═══════════════════════════════════════════════════════════════════════════ */

.mb-buehne{
  --mb-p:0;                                   /* Scrollfortschritt, makrobrille.js */
  --mb-rund:clamp(18px, 3.2cqw, 42px);        /* Ecken der fertigen Karte */
  position:relative;
  isolation:isolate;
  container:mb / inline-size;
  display:grid;
  grid-template-columns:minmax(0,1fr);
  padding:clamp(76px, 15vw, 104px) 0 clamp(2.6rem, 7vw, 4rem);
  background:var(--grund);
}

/* ── Der Filmrahmen ───────────────────────────────────────────────────────── */
.mb-rahmen,
.mb-schatten{
  grid-row:1; grid-column:1;
  position:relative;
  width:100%;
  aspect-ratio:4/3;
  /* Quer gehaltene Tablets und kleine Laptops (bis 1179 px): sonst füllte der Film
     den ersten Bildschirm und die Überschrift läge darunter (1024 × 768: Text ab
     655 px). 31vw ist die Untergrenze, bei der die Brille im mittig beschnittenen
     16:9-Film noch ganz im Rahmen steht (sie braucht 48,7 % der Filmhöhe). */
  max-height:max(54svh, 31vw);
  transform-origin:50% 50%;
  transform:translate3d(0, calc(var(--mb-p) * -1.4cqw), 0) scale(calc(1 - var(--mb-p) * .1));
}
.mb-rahmen{
  z-index:1;
  /* Größencontainer: der Film rechnet seine Fläche in cqw/cqh dieses Rahmens. */
  container:mbr / size;
  overflow:hidden;
  background:var(--grund);
  clip-path:inset(0 round calc(var(--mb-p) * var(--mb-rund)));
  will-change:transform;
}
/* „hebt sich leicht": der Schatten liegt als eigene Fläche darunter, weil
   clip-path den Schatten des Rahmens selbst mit abschneiden würde. */
.mb-schatten{
  z-index:0;
  border-radius:var(--mb-rund);
  box-shadow:0 30px 70px rgba(19,55,109,.16), 0 8px 22px rgba(19,55,109,.08);
  opacity:var(--mb-p);
  pointer-events:none;
}

.mb-bild,
.mb-bild img,
.mb-film{
  position:absolute; inset:0;
  display:block;
  width:100%; height:100%;
}
.mb-bild img,
.mb-film{
  object-fit:cover;
  /* Wird beschnitten, dann links: dort ist nur Grund, rechts reicht der offene Bügel
     bis 98 % der Bildbreite. */
  object-position:100% 50%;
}
/* Der Film liegt über dem Standbild und erscheint erst, wenn er wirklich läuft —
   sein erstes Bild IST das Standbild, der Wechsel ist unsichtbar. */
.mb-film{
  opacity:0;
  transform-origin:0 0;
  transform:translate3d(var(--mb-kx, 0px), var(--mb-ky, 0px), 0) scale(var(--mb-ks, 1));
  transition:opacity .3s linear, transform 2.4s cubic-bezier(.4, 0, .1, 1);
}
.mb-laeuft .mb-film{ opacity:1; }
/* Zum Positionieren braucht der Film seine ganze Fläche statt des Beschnitts durch
   object-fit: dieselbe Lage wie das Standbild (cover, rechts, mittig), nur ragt das
   Element über den Rahmen hinaus, der es abschneidet. So kann transform den Teil
   links neben dem Ausschnitt ins Bild holen. Ohne cq-Einheiten bleibt der Beschnitt,
   makrobrille.js erkennt das am Seitenverhältnis und positioniert dann nicht. */
@supports (width:1cqh){
  .mb-film{
    /* bau.css begrenzt jedes video auf max-width:100% — am Telefon wäre der Film dann
       nur so breit wie der Rahmen (gemessen 375 × 812: 366,8 statt 489 px). */
    max-width:none;
    inset:auto;
    right:0;
    top:calc(50cqh - max(100cqh, 100cqw * 9 / 16) / 2);
    width:max(100cqw, 100cqh * 16 / 9);
    height:max(100cqh, 100cqw * 9 / 16);
  }
}
/* Bei einem Größenwechsel nach dem Positionieren springt der Film ohne Gleiten
   auf die neue Lage. */
.mb-sofort .mb-film{ transition:opacity .3s linear; }

/* Kennzeichnung: KI-Bilder werden gekennzeichnet (seine Regel). */
.mb-ki{
  position:absolute; z-index:2;
  right:clamp(10px, 1.6cqw, 24px);
  bottom:clamp(10px, 1.6cqw, 24px);
  padding:.34em .8em;
  border-radius:var(--r-rund);
  background:var(--glas);
  border:1px solid var(--glas-rand);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  color:var(--text-leise);
  font-size:.66rem; font-weight:750; letter-spacing:.08em; line-height:1.4;
  white-space:nowrap;
  pointer-events:none;
}

/* ── Die Texte (Telefon und Tablet: unter dem Film, mittig) ──────────────── */
.mb-text{
  grid-row:2;
  position:relative; z-index:2;
  padding:clamp(1.6rem, 5vw, 2.4rem) var(--gasse) 0;
  text-align:center;
}
.mb-text h1{ margin-bottom:1.1rem; }
.mb-text p.gross{
  font-size:clamp(1.02rem, 1.25vw, 1.2rem);
  max-width:52ch;
  margin:0 auto 1.9rem;
  color:var(--text-leise);
  text-wrap:pretty;          /* kein einzelnes „Gehör." in der letzten Zeile (1920 px) */
}
.mb-text .knopfreihe{ justify-content:center; }

/* Die Zahlenzeile — dieselbe Gestalt wie .vertrauen (grund.css), eigene Klasse,
   damit bewegung.js sie nicht hochzählt (siehe teil-makrobrille.php). */
.mb-zahlen{
  grid-row:3;
  position:relative; z-index:2;
  padding:2.2rem var(--gasse) 0;
}
.mb-reihe{
  display:flex; flex-wrap:wrap; gap:1.4rem;
  align-items:center; justify-content:center;
}
.mb-reihe .zahl{ font-size:1.55rem; font-weight:850; letter-spacing:-.03em; line-height:1; color:var(--blau); }
.mb-reihe .wofuer{ font-size:.76rem; color:var(--text-leise); letter-spacing:.04em; }
.mb-reihe .strich{ width:1px; height:30px; background:var(--linie); }
@media (max-width:620px){ .mb-reihe .strich{ display:none; } }

/* Eintritt: reines CSS, kein Skript, das hängen bleiben kann — auf den inneren
   Teilen, damit es nie mit dem Scroll-transform der Hüllen kollidiert. */
.mb-ein{ animation:mb-ein .62s var(--weich) both; }
.mb-text > .mb-ein:nth-child(1){ animation-delay:.08s; }
.mb-text > .mb-ein:nth-child(2){ animation-delay:.14s; }
.mb-text > .mb-ein:nth-child(3){ animation-delay:.2s; }
.mb-text > .mb-ein:nth-child(4){ animation-delay:.26s; }
.mb-zahlen > .mb-ein{ animation-delay:.32s; }
@keyframes mb-ein{ from{ opacity:0; transform:translateY(14px); } to{ opacity:1; transform:none; } }

/* ── Ab 1180 px: Film über die ganze Bühne, Texte im freien Teil links ───── */
@media (min-width:1180px){
  .mb-buehne{
    --mb-links:clamp(28px, 5.4cqw, 120px);    /* Abstand der Texte vom linken Rand */
    --mb-frei:34cqw;                          /* Brille ab 34,4 % der Breite */
    --mb-luft:max(28px, 2.4cqw);              /* Abstand der Texte zur Brille */
    --mb-spalte:calc(var(--mb-frei) - var(--mb-links) - var(--mb-luft));
    --mb-fuss:max(1.4rem, 4.4%);              /* Zahlenzeile über der Unterkante */
    display:block;
    /* width:100% hält die Breite fest: ohne sie übertrug Chrome die Höhengrenze
       über das Seitenverhältnis auf die Breite (gemessen 2560 × 1080: Bühne nur
       1920 px breit, rechts 608 px leer). */
    width:100%;
    aspect-ratio:16/9;
    /* 92svh, nicht 100svh: Chrome wertet ein Bild, das das Fenster fast ganz
       füllt, als Hintergrund und nicht als LCP (gemessen: 1920 × 1080 mit Bühne
       1888 × 1062 → kein LCP-Eintrag fürs Standbild, LCP wurde die Überschrift nach
       1,2 s bzw. das erste Filmbild; ebenso 1366 × 768, 1600 × 900, 2560 × 1440;
       ab 2,6 % Luft unten zählte es). Unten bleibt so ein Streifen der Partnerleiste
       sichtbar. Die Brille steht auch im beschnittenen Film ganz im Rahmen. */
    max-height:max(92svh, 600px);
    min-height:600px;
    padding:0;
  }
  .mb-rahmen,
  .mb-schatten{
    position:absolute; inset:0;
    aspect-ratio:auto;
    max-height:none;
  }
  .mb-text{
    position:absolute;
    left:var(--mb-links);
    width:var(--mb-spalte);
    top:max(6.6rem, 13%);
    bottom:calc(var(--mb-fuss) + 5.4rem);
    padding:0;
    display:flex; flex-direction:column; justify-content:safe center;
    text-align:left;
    transform:translate3d(0, calc(var(--mb-p) * -5.5cqw), 0);
    opacity:calc(1 - var(--mb-p) * 1.6);
  }
  /* „Sehen, wie es" soll in die Spalte passen: gemessen 6,13 × Schriftgröße breit
     (Nunito 800); mit 6,4 bleiben rund 4 % der Spalte frei. */
  .mb-text h1{ font-size:clamp(2.3rem, calc(var(--mb-spalte) / 6.4), 5rem); }
  .mb-text p.gross{ font-size:clamp(1rem, 1.2cqw, 1.2rem); margin:0 0 1.7rem; max-width:none; }
  .mb-text .knopfreihe{ justify-content:flex-start; }
  .mb-zahlen{
    position:absolute;
    left:var(--mb-links);
    bottom:var(--mb-fuss);
    padding:0;
    transform:translate3d(0, calc(var(--mb-p) * -3cqw), 0);
    opacity:calc(1 - var(--mb-p) * 2);
  }
  .mb-reihe{ justify-content:flex-start; }
}

/* ── Die Partnerleiste darunter ─────────────────────────────────────────────
   Mit dieser Bühne steht sie im ersten Bildschirm (1440 × 900: ab 808 px). Ihre
   Namen setzt erst das Inline-Skript am Seitenende; vorher ist .spur 0 px hoch,
   danach eine Zeile. Gemessen (23.10.2026, 1 von 5 Ladevorgängen): #leistungen
   rutschte 35 px tiefer, CLS 0,004. Die Zeile wird darum vorgehalten — Größe der
   Namen aus grund.css × Zeilenhöhe 1,62 (body), gemessen 25,9 / 31,1 / 33,7 px
   bei 16 / 19,2 / 20,8 px Schrift. */
.mb-buehne + .laufband .spur{ min-height:calc(clamp(1rem, 1.5vw, 1.3rem) * 1.62); }

/* ── Das Blatt um die Bühne ─────────────────────────────────────────────────
   Das LCP-Bild soll das Standbild sein. Der Eintritt der Startseite vergrößert
   .blatt anfangs auf 1,045 (grund.css): je nachdem, wann das Standbild zuerst
   gemalt wird, ragt die Bühne dabei oben aus dem Fenster und zählt kleiner — dann
   meldete Chrome später das erste Filmbild als größeres LCP (gemessen 1440 × 900:
   Standbild 1 004 679 px² nach 336 ms, Film 1 082 755 px² nach 1 824 ms). Ohne die
   Vergrößerung sind Standbild und Film gleich groß, das Standbild bleibt das LCP.
   Unschärfe und Deckkraft des Eintritts bleiben. */
.blatt:has(> .mb-buehne){ transform:none; }

/* ── Netze ───────────────────────────────────────────────────────────────────
   Ohne Skript setzt niemand body.offen: .blatt bliebe unscharf (blur 7px) und
   bei Deckkraft 0,55 stehen (grund.css; auf der bisherigen Startseite ebenso,
   dort zusätzlich 16 px breiter als das Fenster: 1440 → 1456, 375 → 379). */
@media (scripting:none){
  .blatt:has(> .mb-buehne){ filter:none; opacity:1; }
}
/* Bewegung reduziert: das <picture> zeigt schon das geschlossene Standbild,
   makrobrille.js tut nichts; hier steht alles in der Grundform. */
@media (prefers-reduced-motion:reduce){
  .mb-film{ display:none; }
  .mb-ein{ animation:none; }
  .mb-rahmen, .mb-schatten, .mb-text, .mb-zahlen{ transform:none; }
  .mb-rahmen{ clip-path:none; }
  .mb-schatten{ opacity:0; }
  .mb-text, .mb-zahlen{ opacity:1; }
}
