/* ============================================================
   Parlour – main.css
   CSS Custom Properties + Base Reset
   ============================================================ */

:root {

  /* ── Farben ───────────────────────────────────────────── */
  /* Quelle: Figma „Parlour Webdesign" › Design System, Stand 2026-06-29 */
  --honey:    #F5F9EA;  /* light honey   – Haupthintergrund, helle Flächen  */
  --lavender: #E5E6F4;  /* lavender      – Seiten-Background, helle Trapeze */
  --lime:     #A2C140;  /* yellow green  – Akzentfarbe                      */
  --mauve:    #8E80B6;  /* mauve         – mittleres Lila                   */
  --indigo:   #4E3580;  /* indigo velvet – dunkles Lila, Text, Footer       */

  /* ── Typografie ───────────────────────────────────────── */
  --font-condensed:    'Barlow Condensed', system-ui, sans-serif;
  --font-body:         'Barlow', system-ui, sans-serif;
  --font-size-base:    16px;
  --line-height-base:  1.55;

  /* ── Spacing ──────────────────────────────────────────── */
  --space-xs:   0.5rem;
  --space-s:    1rem;
  --space-m:    2rem;
  --space-l:    4rem;
  --space-xl:   8rem;

  /* ── Layout ───────────────────────────────────────────── */
  --container-max: 1440px;
  --container-pad: clamp(1.5rem, 5vw, 6rem);

  /* ── Transitions ──────────────────────────────────────── */
  --ease-default:     cubic-bezier(0.4, 0, 0.2, 1);
  --duration-default: 0.3s;

}

/* ============================================================
   Reset
   ============================================================ */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: var(--font-size-base);
  -webkit-text-size-adjust: 100%;
}

body {
  background-color: var(--lavender);
  color: var(--indigo);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: var(--line-height-base);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a {
  color: inherit;
  text-decoration: none;
}

#main {
  min-height: 100vh;
}

/* ============================================================
   Typografie-Scale
   Quelle: Figma „Parlour Webdesign“ › Design System, Stand 2026-06-29
   ============================================================ */

/* Fluid, gekoppelt an dieselbe 1440px-Referenz wie das Raster (%-basierte
   Trapez-/Logo-Skalierung). clamp(min, calc(figma-px / 1440 * 100vw), max)
   sorgt dafür, dass Schrift im selben Verhältnis wächst wie Grafik –
   min/max verhindern, dass Text bei sehr kleinen/sehr breiten Viewports
   unlesbar bzw. übergroß wird. */

.type-headline {
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: clamp(28px, calc(45 / 1440 * 100vw), 64px);
  line-height: 1;
  letter-spacing: 0;
}

.type-subline {
  font-family: var(--font-condensed);
  font-weight: 300;
  font-size: clamp(18px, calc(30 / 1440 * 100vw), 42px);
  line-height: 1;
  letter-spacing: 0;
}

.type-body {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(16px, calc(18 / 1440 * 100vw), 24px);
  line-height: 1.55;
  letter-spacing: 0;
}

/* ============================================================
   Raster-System
   Ein persistenter Container für die gesamte Seite, gesperrt auf
   das Figma-Seitenverhältnis 1440:8967 (Desktop-Frame, vollständige
   Höhe). Neue Sektionen werden als weitere .trapez-Kinder mit
   eigenen %-Koordinaten ergänzt, ohne dass sich die Skalierungs-
   basis je ändert. Quelle: Desktop_-_1.svg (Figma-Export, 2026-07-02)
   ============================================================ */

.raster {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  aspect-ratio: 1440 / 8967;
  overflow: hidden;
  background-color: var(--lavender);
}

/* Crop-Wrapper: schneidet die volle 8967px-Referenzhoehe von .raster auf
   die tatsaechlich genutzte Hoehe zu (aktuell endet der tiefste Content -
   Fassungen-Dekofuellung Vector 15 - bei 46.5521%; 4200/8967=46.847% laesst
   knapp 300px Puffer als "ueblichen Rand" vor Baukaesten). .raster selbst
   behaelt seine volle aspect-ratio - dadurch bleiben ALLE bestehenden
   --tz-top/--tz-height-Prozentwerte gueltig, nur der Ausschnitt wird
   kleiner. Bei neuen Sektionen im .raster-System: diesen Wert anpassen
   (naechster Vector-Endpunkt statt 4200). */
.raster-crop {
  position: relative;
  width: 100%;
  aspect-ratio: 1440 / 3950;
  overflow: hidden;
}

.trapez {
  position: absolute;
  left: var(--tz-left);
  top: var(--tz-top);
  width: var(--tz-width);
  height: var(--tz-height);
  background-color: var(--tz-color);
  clip-path: var(--tz-clip);
}

.trapez__content {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* flex-end statt center: die Trapez-Form ist oben schräg geschnitten
     (linke Ecke liegt deutlich tiefer als die rechte, siehe clip-path).
     Bei vertikaler Zentrierung ragt der Inhalt oben in die abgeschnittene
     Zone hinein. Unten ist die Kante bei allen Trapezen nahe 100%, also
     deutlich verlässlicher als Ankerpunkt. */
  justify-content: flex-end;
  gap: var(--space-s);
  padding: 6% 9% 10%;
}

/* ============================================================
   Hero
   ============================================================ */

.hero-logo-wrap {
  position: absolute;
  left: 11.3194%;
  top: 0.9925%;
  width: 62.2917%;
  perspective: 1400px;
}

.hero-logo {
  display: block;
  width: 100%;
  height: auto;
  transform-origin: 50% 0%;
}

/* Reveal-Effekt-Typ ist austauschbar über Modifier-Klasse,
   ohne Markup-Änderung – aktuell 3D-Klapp, später ggf. Fade. */
.hero-logo.reveal-flip {
  animation: hero-logo-flip 1s var(--ease-default) 0.2s both;
}

@keyframes hero-logo-flip {
  0%   { transform: rotateX(-100deg); opacity: 0; }
  60%  { opacity: 1; }
  100% { transform: rotateX(0deg); opacity: 1; }
}

.hero-logo.reveal-fade {
  animation: hero-logo-fade 0.8s var(--ease-default) 0.2s both;
}

@keyframes hero-logo-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.hero-subline {
  position: absolute;
  left: 40%;
  top: 6.4%;
  width: 42%;
  text-align: right;
  color: var(--indigo);
}

/* ============================================================
   Sektion: Am Anfang war das Wort
   ============================================================ */

.wort-content {
  color: var(--honey);
  /* Absätze kommen als rohes <p>-HTML aus ACF/WYSIWYG ohne eigene Klasse –
     Größe/Zeilenhöhe hier am Container setzen, damit alle Kind-<p>
     (egal ob aus Fallback oder ACF-Feld) automatisch korrekt erben. */
  font-family: var(--font-body);
  font-size: clamp(16px, calc(16 / 1440 * 100vw), 24px);
  line-height: 1.55;
  /* 2026-07-16: Nach dem Text/Video-Tausch sitzt der Text hier links in
     Shape [02] (mauve) statt wie vorher rechts. Das geerbte
     justify-content:flex-end aus .trapez__content passt hier NICHT mehr:
     Shape [02] ist unten schraeg geschnitten, der Text lief mit der
     letzten Zeile in die abgeschnittene Zone ("Aus Worten werden
     Prompts." war unten angeschnitten - Kunden-Screenshot).

     PADDING-HERLEITUNG (gemessen im Browser, nicht geschaetzt - ein
     erster Versuch mit 12%/16% war zu hoch und liess die Headline oben
     rechts in die Diagonale laufen):

     clip-path ist polygon(100% 27.759%, 0% 0%, 0% 86.027%, 100% 100%).
     Die OBERE Kante steigt also von y=0% (links) auf y=27.759% (rechts),
     die Gefahrenzone waechst nach rechts. Die Headline endet bei ca.
     69.8% der Boxbreite - dort liegt die Kante bei
     27.759 * 0.698 = 19.38%. padding-top muss also >= 19.38% sein.

     22% (= Minimum + Puffer) war kollisionsfrei, wirkte dem Kunden aber
     zu hoch -> auf Wunsch nochmal 50px tiefer (bei 643px Boxhoehe im
     Test-Viewport entspricht das 7.78%), gerundet auf 30%. Das ist eine
     rein optische Entscheidung, kein Kollisionswert - die Untergrenze
     bleibt 19.38%.

     Die UNTERE Kante laeuft von y=86.027% (links) auf y=100% (rechts);
     bei der aktuellen Textmenge endet der letzte Absatz bei ca. 77.6%,
     die Kante liegt dort bei 95.8% - also noch 18.2% Luft. padding-bottom
     ist damit reine Optik, kein Kollisionsschutz.

     Bei laengerem Text unten neu pruefen: erst ab ca. 90% Boxhoehe wird
     die untere Diagonale relevant. */
  justify-content: flex-start;
  padding-top: 30%;
  padding-bottom: 14%;
}

.wort-content .type-headline {
  color: var(--honey);
  margin-bottom: var(--space-xs);
}

.wort-content strong {
  font-weight: 700;
}

/* ============================================================
   Sektion: Zwei Gewerke unter einem Dach
   ============================================================ */

.handwerk-content {
  color: var(--indigo);
  font-family: var(--font-body);
  /* 2026-07-16: Schrift hier BEWUSST kleiner als der Rest der Seite
     (14/1440 statt 16/1440, min 14px statt 16px).

     Grund: Shape [06] ist mit 420x354px das KLEINSTE Content-Trapez der
     Seite, hat aber nach dem Relayout die zweitlaengste Textmenge
     (~280 Zeichen + 2-zeilige Headline). Gemessen bei 1693px Viewport:
     Trapez 416px hoch, Inhalt 558px = 134% -> 142px Ueberlauf.

     Global zu verkleinern waere falsch: die anderen drei Content-
     Sektionen (wort/waende/fassungen) wurden gemessen und laufen alle
     bei exakt 100% - eine globale Reduktion wuerde drei intakte
     Sektionen beschaedigen, um eine zu retten.

     EHRLICH: Das ist eine Kaschierung, kein Fix. Die eigentliche Ursache
     ist zu viel Text fuer die im Figma vorgesehene Box (~200 Zeichen).
     Wenn Mica den Text kuerzt, kann diese Sonderregel zurueckgebaut
     werden. */
  /* 2026-09-14: 14 -> 12 (Faktor UND Minimum), weil im Text ein weiterer
     Satz dazugekommen ist und der letzte Absatz vom clip-path abgeschnitten
     wurde (Kunden-Screenshot). Ueberlauf ist hier nicht nur haesslich: das
     Trapez ist geclippt, ueberstehender Text verschwindet spurlos.

     WO DIE GRENZEN GREIFEN (wichtig beim naechsten Anfassen):
     Das ganze Raster skaliert prozentual mit der Viewportbreite, eine
     vw-Schrift also im selben Tempo wie die Box. Solange WEDER Minimum
     noch Maximum greift, ist das Verhaeltnis Text zu Box ueber alle
     Breiten konstant - es passt ueberall oder nirgends. Nur an den beiden
     Grenzen aendert sich etwas:
       - max 20px greift ab 2400px: Box waechst weiter, Schrift nicht ->
         Text relativ kleiner -> passt. (Mit dem alten 14er-Faktor lag
         diese Schwelle bei 2057px - daher die Beobachtung, dass es erst
         oberhalb ~2200px hielt.)
       - min 12px greift unter 1440px: Box schrumpft weiter, Schrift nicht
         -> Text relativ GROESSER. Das ist die kritische Zone, und sie
         liegt bei 1025-1440px, also Laptop. Unter 1025px uebernimmt die
         Mobile-Regel im 1024er-Block (16/1440, vollbreiter Block, keine
         Platznot) - deshalb wirkt das Minimum nur in diesem Fenster.
     Bei Textaenderungen also bei 1280px UND 1366px gegenpruefen, nicht
     nur auf dem grossen Monitor.

     Das bleibt eine Kaschierung, keine Loesung - siehe Absatz oben. 12px
     ist die Untergrenze des Vertretbaren; der naechste zusaetzliche Satz
     bricht es wieder. Echte Fixes: line-height auf 1.35, Text kuerzen
     (Box ist im Figma fuer ca. 200 Zeichen entworfen, traegt jetzt ca.
     380) oder Shape [06] im Layout vergroessern.
     ROLLBACK: beide 12 wieder auf 14. */
  font-size: clamp(12px, calc(12 / 1440 * 100vw), 20px);
  /* 1.45 -> 1.35 (2026-09-14): Bei 1280px lief der letzte Satz trotz der
     12px noch aus dem Trapez, bei 1366px passte er. Genau das Verhalten,
     das die Minimum-Grenze oben beschreibt - bei 1280px muesste die
     Schrift 10.7px sein, das Minimum haelt sie bei 12 (~12% zu gross),
     bei 1366px sind es nur noch ~5%.
     Zeilenabstand statt Schriftgroesse als Hebel: 1.45 -> 1.35 sind knapp
     7% weniger Hoehe im Fliesstext, ohne dass die Schrift weiter unter
     12px rutscht. Wirkt nur auf den Text, nicht auf die zweizeilige
     Headline - der effektive Gewinn ueber den ganzen Block liegt daher
     eher bei 5%. Die Mobile-Regel im 1024er-Block setzt weiterhin
     eigenstaendig 1.55, sie ist davon nicht beruehrt.
     ROLLBACK: zurueck auf 1.45. */
  line-height: 1.35;
  /* Oben verankert: Gefahrenzonen liegen an BEIDEN Enden dieser Box
     (oben rechts durch Shape [03] aus "Am Anfang war das Wort", unten
     rechts durch Shape [07]), jeweils diagonal und nach rechts zunehmend.

     2026-07-16: padding-top 15% -> 10%, padding-bottom 14% -> 10%.
     Die urspruenglichen Werte hatten Sicherheitspuffer ueber das
     rechnerische Minimum hinaus (noetig: min. 9,2% oben / 11,8% unten
     laut Vector-Berechnung). Der Puffer wird hier gegen den Ueberlauf
     eingetauscht - bringt ca. 40px. Zusammen mit der kleineren Schrift
     reicht das. Bei Aenderung der Textmenge neu pruefen. */
  justify-content: flex-start;
  padding-top: 10%;
  padding-bottom: 10%;
  max-width: 88%;
  gap: 0.6rem;
}

/* Headline-Umbruch: "Zwei Gewerke unter einem Dach" brach dreizeilig um
   ("ZWEI GEWERKE / UNTER EINEM / DACH") und kostete dadurch ~53px extra.
   Etwas kleiner + text-wrap:balance verteilt auf zwei ausgewogene Zeilen.
   balance ist ein Progressive Enhancement - aeltere Browser ignorieren es
   und brechen normal um, die kleinere Schrift greift trotzdem. */
.handwerk-content .type-headline {
  color: var(--indigo);
  font-size: clamp(24px, calc(38 / 1440 * 100vw), 52px);
  text-wrap: balance;
}

.trapez--video {
  overflow: hidden;
}

.trapez--video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Logo-Loop: Film komplett sichtbar im Trapez. contain zeigt den ganzen
   Frame, leere Flächen zeigen den Trapez-Hintergrund (weiß statt Indigo,
   weil das Video einen hellen Hintergrund hat). */
.trapez--logo-loop {
  background-color: #ffffff;
}

.trapez--logo-loop video {
  width: 100%;
  height: unset;
  aspect-ratio: 16 / 9;
  object-fit: contain;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* ============================================================
   Sektion: Die Wände stehen schon
   ============================================================ */

/* Wrapper um die Wände-Bloecke (section-waende.php). Auf DESKTOP wirkungs-
   los: display:contents nimmt das Element aus dem Layout, seine Kinder
   (die .trapez-Bloecke) verhalten sich, als saessen sie direkt im .raster
   - die absolute %-Positionierung bleibt exakt erhalten. Erst mobil (im
   1024er-Query) wird der Wrapper zu einer echten honey-Flaeche, gegen die
   lila Block + Karussell abgesetzt sind. */
/* Desktop-Default: Wrapper wirkungslos (siehe Kommentar im ≤1024px-Block
   bei .waende-section-wrap). Handwerk-Wrapper folgt demselben Muster. */
.waende-section-wrap,
.handwerk-section-wrap {
  display: contents;
}

.waende-content {
  color: var(--honey);
  font-family: var(--font-body);
  font-size: clamp(16px, calc(16 / 1440 * 100vw), 24px);
  line-height: 1.55;
  /* Gefahrenzone oben-links (Vector 8 clip-path schneidet dort scharf ein,
     bis zu ~22% Boxhöhe an der linken Kante) – Text startet erst danach.
     36% statt 26%: war bei längerem Text/Screenshot immer noch zu weit
     oben, siehe Screenshot-Feedback. */
  justify-content: flex-start;
  padding-top: 36%;
  padding-bottom: 6%;
}

.waende-content .type-headline {
  color: var(--honey);
}

/* ============================================================
   Sektion: Ein Raum fuer Alle (Feld-/Klassennamen bleiben "fassungen_*",
   siehe Kommentar in section-fassungen.php)
   ============================================================ */

.fassungen-content {
  color: var(--honey);
  font-family: var(--font-body);
  /* 15/1440 statt 16/1440 wie der Rest der Seite: vom Kunden live im
     Inspektor kalibriert und bestaetigt (2026-07-16). Ein erster Anlauf
     mit 17/1440 (= exakt 20px bei 1693px Viewport) war zu gross - 15
     ergibt bei 1693px ca. 17.6px.

     Bewusst als clamp/vw statt als fester px-Wert: das gesamte Raster
     (Trapeze, Logo, Typo) skaliert prozentual mit der Viewportbreite.
     Ein absoluter Wert waere auf EINEM Monitor exakt richtig, wuerde die
     Sektion aber als einzige NICHT mitskalieren - und der hier austarierte
     Ueberlauf-Spielraum waere wieder offen.

     Gegenprobe: 1440px -> 15.0px | 1693px -> 17.6px | 1920px -> 20.0px */
  font-size: clamp(16px, calc(15 / 1440 * 100vw), 26px);
  /* 1.45 statt 1.55 (Rest der Seite) - zusammen mit der etwas groesseren
     Schrift vom Kunden bestaetigt. Zeilenabstand ist hier der Hebel gegen
     den Ueberlauf bei padding-top:70%, nicht die Schriftgroesse. */
  line-height: 1.45;
  /* 2026-07-16: Shape [13] (mauve) traegt jetzt den Text - vorher war das
     der Video-Slot, der Text sass rechts in [14]. Die alten Padding-Werte
     galten fuer die ANDERE Box.

     Das [13]-Polygon ist
     polygon(100% 100%, 100% 0%, 0% 43.624%, 0% 79.134%):
     Die obere Kante faellt von y=43.624% (links) auf y=0% (rechts), die
     untere steigt von y=79.134% (links) auf y=100% (rechts). Der
     sichtbare Bereich ist links also nur 35.5% der Boxhoehe hoch und
     oeffnet sich nach rechts.

     padding-top:70% ist vom Kunden live im Inspektor gesetzt und
     bestaetigt (2026-07-16). Der erste, rein rechnerische Vorschlag (38%)
     war kollisionsfrei, sass aber optisch zu hoch.

     ACHTUNG bei kuenftigen Messungen: [data-slide-reveal="left"] auf
     diesem Element verschiebt es per translateX aus der Box heraus.
     getBoundingClientRect liefert dann Koordinaten AUSSERHALB des
     Trapezes (gemessen: left=-8.5%) - fuer Kantenkollisions-Pruefungen
     muss die reveal-armed-Klasse vorher entfernt werden, sonst sind die
     Werte wertlos. */
  justify-content: flex-start;
  padding-top: 70%;
  padding-bottom: 4%;
  padding-left: 18%;
  padding-right: 8%;
}

.fassungen-content .type-headline {
  color: var(--honey);
}

/* ============================================================
   Sektion: Die Elefanten im Raum
   ============================================================ */

/* NEUBAU 2026-07-16: Die alte vierteilige Diagonal-Kaskade
   (.elefanten-cascade + .elefanten-block--1..4, absolut positioniert mit
   gestaffelten Reveal-Delays) ist entfallen - der neue Kundentext hat nur
   noch zwei Absaetze, und im Figma-Referenzlayout stehen Headline + Text
   als EIN linksbuendiger Block rechts neben dem Bild.

   Shape [10] ist 1440px breit (volle Seitenbreite) - ein Textblock ueber
   die ganze Breite waere unlesbar. Laut Figma sitzt der Block bei ca.
   x=665px (46%) und ist ca. 400px breit (28% der Seitenbreite).

   Positionierung per absolute (nicht padding): top/left loesen sich gegen
   die jeweils passende Achse der Trapez-Box auf, waehrend %-padding IMMER
   gegen die BREITE aufloest - bei einer 1440x723-Box (Ratio ~2:1) waere
   das ein grober Fehler (dieselbe Falle wie bei .waende-grid, siehe
   Kommentar dort).

   Vertikal: Das [10]-Polygon
   polygon(0% 35.270%, 34.653% 0%, 100% 27.870%, 100% 100%) hat seine
   obere Kante zwischen x=34.653% (y=0%) und x=100% (y=27.87%) ansteigend.
   Bei x=50% liegt die Kante rechnerisch bei
   27.87 * (50-34.653)/(100-34.653) = 6.55% - top:24% haelt also reichlich
   Abstand.

   left:50% / top:24% vom Kunden live im Inspektor gesetzt und bestaetigt
   (2026-07-16). Der erste, rein rechnerische Vorschlag (46%/12%) war
   kollisionsfrei, sass aber optisch zu weit oben/links. */
.elefanten-text {
  position: absolute;
  left: 50%;
  top: 24%;
  width: 28%;
  color: var(--indigo);
  font-family: var(--font-body);
  font-size: clamp(16px, calc(16 / 1440 * 100vw), 24px);
  line-height: 1.55;
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.elefanten-text .type-headline {
  color: var(--indigo);
  margin-bottom: var(--space-xs);
  text-wrap: balance;
}

/* Bild-Trapez (Shape [11]). Eigener Modifier statt .trapez--video, weil
   urspruenglich ein <img> statt <video> drin sass - Regeln sind aber
   identisch: overflow:hidden + object-fit:cover fuellen die Bounding-Box,
   der clip-path maskiert.

   2026-09-14: Der Slot kann jetzt WAHLWEISE ein Bild oder einen muted
   Loop enthalten (Kundenwunsch, siehe section-elefanten.php). Deshalb
   gilt dieselbe Regel fuer img UND video. Der Modifier bleibt
   .trapez--image, damit die vorhandenen Mobile-Regeln fuer diesen Block
   (u.a. margin-bottom im 1024er-Query) unveraendert greifen.
   ROLLBACK: video aus dem Selektor entfernen. */
.trapez--image {
  overflow: hidden;
}

.trapez--image img,
.trapez--image video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ============================================================
   Sektion: Wände (NEU: 7 absolute Video-Slots statt 9er-Grid)
   ============================================================ */

.waende-slot {
  position: absolute;
  left: var(--ws-left);
  top: var(--ws-top);
  width: var(--ws-width);
  height: var(--ws-height);
  min-width: 0;
  min-height: 0;
}

.waende-slot .klapp-media {
  aspect-ratio: var(--ws-aspect);
}

/* Grid Container: 7 Werk-Kacheln mit individuellen aspect-ratios
   mit Sicherheitsabstand zu den schraegen Trapez-Kanten eingepasst.

   ZURUECKGESETZT auf den letzten bestaetigt funktionierenden Stand:
   kein rotateY/perspective mehr. Der Versuch, das Grid live als
   3D-transformiertes CSS-Grid perspektivisch zu verzerren (mehrere
   Iterationen: exakte 4-Ecken-Passung, dann empirisch kalibrierte
   Werte), ist an der nicht vorhersehbaren Wechselwirkung zwischen
   CSS-Grid-Layout und rotateY+perspective gescheitert - Zellgroessen
   und Abstaende verhielten sich nach der Transformation wiederholt
   anders als berechnet. Naechster Versuch fuer die perspektivische
   Verzerrung (nach grid.jpg): fester matrix3d-Wert aus den tatsaech-
   lichen Eckpunkten der Photoshop-Vorlage, nicht rotateY/perspective.

   Sicherheitsabstand zu den schraegen Trapez-Kanten (--tz-clip:
   polygon(0% 78.59%, 0% 32.47%, 100% 0%, 100% 100%)). Rechte Kante ist
   durchgehend vertikal (0-100%) - keine Gefahr dort. Linke Kante dagegen
   nur zwischen y=32.47% und y=78.59% unbeschnitten (46.12% der Trapez-
   hoehe), und diese Zone verengt sich weiter Richtung x=0%.

   Bei left:6% Inset liegt die obere Diagonale bei y=30.52%, die untere
   bei y=79.87% (Geradengleichungen: y_top(x) = 32.47*(1-x), y_bottom(x)
   = 78.59 + 21.41*x, x als Anteil 0-1 der Trapezbreite). top:33% /
   bottom:22% liegen davon nochmal ~2% entfernt als visueller Puffer ->
   45% nutzbare Hoehe, sauber innerhalb der rechnerisch maximal moeglichen
   49.35%.

   WICHTIG: top/bottom/left/right auf einem position:absolute-Element
   loesen sich JEWEILS gegen die passende Achse der Trapez-Box auf
   (top/bottom gegen Hoehe, left/right gegen Breite) - anders als
   padding-top/-bottom, die laut Spec IMMER gegen die Breite des
   Containers aufloesen. Deshalb absolute Positionierung statt Padding.

   Rows bewusst NICHT explizit gesetzt (kein grid-template-rows) - jede
   Reihenhoehe ergibt sich automatisch aus .klapp-media's aspect-ratio:
   16/9 (siehe main.css weiter unten), bei der vollen Spaltenbreite. Das
   ist der einzige Weg, der in dieser Session zuverlaessig echte 16:9-
   Kacheln ergeben hat.

   PERSPEKTIVISCHER WARP: transform+transform-origin unten warpen das
   FERTIGE Rechteck als Ganzes - Photoshop-Free-Transform-Logik (linke
   Kante fix, rechte Kante rausgezogen), keine Aenderung an der
   Grid-internen Struktur (Spalten/Gap-Verhaeltnis) selbst.

   ZIEL-POLYGON ist NICHT das rohe --tz-clip-Polygon, sondern dieses um
   20px (Referenz 1440px, wie der Rest des Systems) SENKRECHT nach innen
   versetzt - sonst laeuft die Grid-Kante exakt auf der Trapez-Kante statt
   parallel mit Abstand (genau der Bug von der ersten Version: oben schien
   der Rand zu passen, wurde nach rechts aber immer schmaler, weil beide
   Kanten nicht parallel waren). 20px = 1.3889vw = 2.16% der (fast
   quadratischen, deshalb fuer beide Achsen gueltigen) Trapezbreite.

   Eingerueckte Eckpunkte (senkrechter Versatz der Kanten, nicht simple
   xy-Verschiebung - siehe Normalenvektor-Rechnung):
     oben-links   (2.16%, 34.04%)   statt (0%,   32.47%)
     oben-rechts  (97.84%, 2.97%)   statt (100%, 0%)
     unten-rechts (97.84%, 97.33%)  statt (100%, 100%)
     unten-links  (2.16%, 76.85%)   statt (0%,   78.59%)

   Linke Kante (Drehpunkt, unveraendert durch Rotation): x=2.16%,
   y=34.04-76.85% (Hoehe 42.81%). Rechte Kante-Ziel: x=97.84%,
   y=2.97-97.33% (Hoehe 94.36%) -> Ziel-Skalierung s = 94.36/42.81 =
   2.2043.

   Bei W=91.84% (Grid-Breite aus left:2.16% + right:6%, UNVERAENDERTE
   Spalten/Gap-Struktur):
     cosθ = (97.84-2.16)/s / W = 43.40/91.84 = 0.4726 -> θ ≈ 61.79deg
     d = (s/(s-1)) * W * sinθ ≈ 1.8304 * 91.84 * 0.8814 ≈ 148.2% der
     Trapezbreite -> als Laenge: 148.2% * 64.3056% ≈ 95.3vw (siehe
     perspective in section-waende.php - `perspective` akzeptiert nur
     <length>, kein %).
     perspective-origin-Y ≈ 59.83%. perspective-origin-X ≈ 2.16%
     (= Drehpunkt-X) - siehe perspective-origin in section-waende.php.

   Vorzeichen von rotateY ist wie immer bei dieser Methode nicht ohne
   Rendering verifizierbar - falls die Verjuengung nach links statt
   rechts passiert (Kanten vertauscht): Vorzeichen umdrehen, mehr nicht.

   column-gap groesser als row-gap: dieselbe Ursache wie bei perspective-
   origin - die Verzerrung staucht horizontal staerker als vertikal
   (Faktor ~1/cosθ ≈ 2.1). Gleicher CSS-Wert fuer beide Achsen (wie beim
   ersten Versuch) sah deshalb nach der Verzerrung ungleich aus, obwohl
   im Code identisch - column-gap muss VOR der Verzerrung groesser sein,
   damit beide NACH der Verzerrung gleich aussehen. Schaetzwert aus der
   Geometrie, keine Live-Messung wie beim vorherigen (verworfenen)
   Ansatz - ggf. in Chrome nachjustieren. */
.waende-grid {
  position: absolute;
  top: 34.04%;
  bottom: 23.15%;
  left: 2.16%;
  right: 6%;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* grid-auto-rows (auto, Default) haette hier weiter zu Overflow gefuehrt:
     .waende-grid hat top+bottom gesetzt, kein height -> Boxhoehe ist
     rechnerisch DEFINIT (42.81%), nicht content-getrieben, obwohl kein
     explizites height im CSS steht. Auto-Rows schrumpfen aber nicht, um
     in eine kleinere Box zu passen, sie behalten ihre aspect-ratio-
     getriebene Groesse und laufen ueber - nachgerechnet ca. 17% zu hoch
     bei 3 Reihen + Gaps. 1fr nutzt stattdessen die tatsaechlich definite
     Boxhoehe und teilt exakt in 3 - kein Overflow mehr moeglich, auch
     wenn sich Rand-/Gap-Werte spaeter nochmal aendern.

     column-gap NICHT mehr groesser als row-gap (Kurskorrektur): bei DIESER
     Transform-Richtung (Drehpunkt links, Skalierung waechst nach rechts)
     wird der Spalten-Abstand progressiv STAERKER VERGROESSERT, je weiter
     rechts er liegt - nicht gleichmaessig gestaucht wie beim frueheren,
     umgekehrten Ansatz (Drehpunkt rechts). Ein grosser Vorab-Wert hat das
     Problem dadurch verstaerkt statt ausgeglichen (sichtbar: Spalte1-2 ok,
     Spalte2-3 zu breit). Da die Vergroesserung POSITIONSABHAENGIG ist
     (nicht konstant), kann ein einzelner column-gap-Wert beide Abstaende
     grundsaetzlich nicht exakt gleich gross machen - row-gap-Niveau ist
     der beste erreichbare Kompromiss ohne Strukturaenderung (echte
     Spacer-Spalten mit individueller Breite statt column-gap waeren die
     exakte Loesung, falls noetig). */
  grid-template-rows: repeat(3, 1fr);
  row-gap: clamp(8px, 1.4%, 18px);
  column-gap: clamp(4px, 0.7%, 10px);
  transform: rotateY(-61.79deg);
  transform-origin: left center;
}

/* .werk-buehne (Grid-Item) wird per align-items:stretch (Default) korrekt
   auf die 1fr-Zeilenhoehe gestreckt - .klapp-media als sein Block-Kind
   erbt das aber NICHT automatisch (nur width:100% ist Block-Default,
   height nicht). Ohne explizite height haette .klapp-media weiterhin
   seine eigene Hoehe aus aspect-ratio:16/9 berechnet und waere innerhalb
   der jetzt korrekt begrenzten Zelle uebergelaufen (unsichtbar mangels
   overflow:hidden) - genau das Symptom "1fr gesetzt, trotzdem kein
   Rand unten". height:100% erzwingt die Zellfuellung, aspect-ratio wird
   dadurch ueberschrieben (beide Achsen definit -> Spec ignoriert die
   Ratio). */
.waende-grid .klapp-media {
  height: 100%;
}

/* Reveal AKTIV (data-grid-reveal sitzt am Wrapper, siehe section-
   waende.php): Grid schwingt beim Reinscrollen wie eine Tuer in die
   finale Warp-Position. Hidden-State ist ein staerker geschlossener
   Winkel derselben Drehrichtung (-82deg statt -61.79deg) - NICHT 0/none,
   sonst waere es nur ein Einblenden ohne Schwing-Effekt. -82deg statt
   z.B. -90deg: echte 90deg-Rotation ist eine Singularitaet der
   Perspektivprojektion (Bounding-Box explodiert Richtung unendlich,
   siehe historischer Bug dazu weiter unten) - 82deg ist deutlich
   geschlossener als der Ruhezustand, bleibt aber rechnerisch sicher
   (W*sinθ=91% < d=148% der Trapezbreite, also noch klar vor der
   Kameraebene). transform-origin wird NICHT hier gesetzt - erbt von der
   Basisregel .waende-grid (left center), identisch fuer Hidden und
   Revealed, nur der Winkel aendert sich. */
.waende-grid.reveal-armed {
  opacity: 0;
  transform: rotateY(-82deg);
  transition: transform 1s var(--ease-default), opacity 0.6s var(--ease-default);
}

/* Zielzustand = identisch mit der Basisregel .waende-grid weiter oben
   (muss synchron gehalten werden, falls dort der Winkel je angepasst
   wird - Basisregel bleibt der No-JS/reduced-motion-Fallback, diese
   hier der animierte Weg dorthin). */
.waende-grid.reveal-armed.is-revealed {
  opacity: 1;
  transform: rotateY(-61.79deg);
}

@media (prefers-reduced-motion: reduce) {
  .waende-grid.reveal-armed {
    opacity: 1;
    /* NICHT none - das wuerde den permanenten Warp entfernen und das
       Grid flach/unverzogen zeigen. Bei reduced-motion soll der
       Ziel-Zustand sofort stehen, nur ohne Animation dorthin. */
    transform: rotateY(-61.79deg);
    transition: none;
  }
}

/* HINWEIS (2026-07-21): .werk-buehne und .waende-slot sind DIESELBE
   Kachel - das Template rendert beide Klassen am selben Element
   (class="werk-buehne waende-slot waende-slot--N"). Historisch gewachsen:
   main.css nutzt durchgehend .werk-buehne, die spaetere waende-slots-
   new.css nutzt .waende-slot. Mehrere Regeln existieren dadurch doppelt
   (position/min-size hier, flex/carousel-armed in den 1279er-Bloecken).
   Die Werte sind identisch, es gibt keinen Konflikt - die Doppelung ist
   bewusst NICHT aufgeraeumt worden (Regressionsrisiko an einer komplexen,
   funktionierenden Sektion > kosmetischer Gewinn). Wer hier aufraeumt:
   .waende-slot in waende-slots-new.css ist der vollstaendigere/aktuellere
   Strang, .werk-buehne in main.css der aeltere. */
.werk-buehne {
  position: relative;
  min-width: 0;
  min-height: 0;
}

/* Basis: nur auf Mobile sichtbar (siehe @media max-width:760px unten) */
.waende-swipe-hint {
  display: none;
}

.klapp-media {
  position: relative;
  overflow: hidden;
  border-radius: 2px;
  /* Rechteck statt Quadrat – passt zu Video-Screenshots als Featured Image */
  aspect-ratio: 16 / 9;
  background-color: var(--indigo);
}

.werk-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* SVG-Icon-Variante am 2026-07-03 getestet (gegen die Unschaerfe in
   Spalte 3, siehe .waende-grid-Kommentar oben) - brachte keine sichtbare
   Verbesserung, zurueckgebaut. Ein zweiter Anlauf ueber ein separates,
   nicht-transformiertes Overlay (waende-play-overlay.js) wurde am
   2026-07-06 ebenfalls zurueckgebaut - Positionierung liess sich trotz
   mehrfach verifizierter Formel nicht zuverlaessig zum Laufen bringen.
   Unschaerfe bleibt ein akzeptierter Trade-off der "ganzes Grid als eine
   Ebene verzogen"-Methode. */
.werk-play {
  position: absolute;
  right: var(--space-xs);
  bottom: var(--space-xs);
  width: clamp(42px, 8%, 66px);
  height: clamp(42px, 8%, 66px);
  border: none;
  border-radius: 50%;
  background-color: var(--honey);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.werk-play::after {
  content: "";
  display: block;
  margin-left: 3px;
  border-left: 13px solid var(--indigo);
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ============================================================
   Lightbox
   Ein gemeinsames Modal für alle Work-Videos (Wände, Baukästen, ...).
   ============================================================ */

.lightbox {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background-color: rgba(20, 10, 40, 0.92);
  z-index: 1000;
  padding: var(--space-m);
}

.lightbox.is-open {
  display: flex;
}

.lightbox__stage {
  width: 100%;
  max-width: 1100px;
  /* NICHT mehr fest aspect-ratio:16/9: Videos sind gemischt Hoch- und
     Querformat. Ein fester 16:9-Rahmen zwang Hochformat in schwarze
     Balken UND konnte auf Mobile hoeher als der Screen werden.
     Stattdessen: passt immer in den Viewport (max-height), das Video
     darin zentriert per object-fit:contain. */
  max-height: 85vh;
  aspect-ratio: 16 / 9;
  /* aspect-ratio bleibt als Startform fuer Querformat/iframe, wird aber
     durch max-height:85vh gedeckelt - auf schmalen Screens gewinnt die
     Hoehenbegrenzung, die Breite passt sich an. */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Video-Format aus dem Work (2026-09-21, Kunden-Screenshot Segmueller):
   lightbox.js setzt .has-ratio + --lb-ratio (Breite/Hoehe als Zahl, z. B.
   0.5625 fuer 9:16), sobald der Player eingesetzt wird. Die Stage nimmt
   dann die Form des Videos an statt 16:9 - keine schwarzen Seitenbalken
   mehr bei Hochkant-Vimeo (iframes kennen kein object-fit).

   Breite = das Kleinere aus verfuegbarer Breite und 85vh * Ratio. Damit
   passt die Stage immer in den Viewport, egal ob Desktop, Handy hoch
   oder quer - die Hoehe folgt per aspect-ratio. max-width:1100px und
   max-height:85vh aus der Basisregel bleiben als Deckel bestehen.
   Querformat-Works bekommen kein Attribut und laufen unveraendert.

   ROLLBACK: diesen Block auskommentieren -> Stage wieder fest 16:9. */
.lightbox__stage.has-ratio {
  aspect-ratio: var(--lb-ratio);
  width: min(100%, calc(85vh * var(--lb-ratio)));
}

.lightbox__video,
.lightbox__iframe {
  width: 100%;
  height: 100%;
  background-color: #000;
  border: none;
  display: block;
}

/* MP4-Video: object-fit:contain zeigt Hochformat korrekt (schmal,
   zentriert) statt es breitzuziehen. Wirkt NUR auf <video> - iframes
   (Vimeo) ignorieren object-fit, dort rendert Vimeo selbst die Balken. */
.lightbox__video {
  object-fit: contain;
  background-color: transparent;
}

.lightbox__close {
  position: absolute;
  top: var(--space-m);
  right: var(--space-m);
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background-color: var(--honey);
  color: var(--indigo);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  /* ueber dem Video/iframe (Stage hat display:flex) und immer anklickbar.
     z-index hebt ihn ueber das randfuellende Video, box-shadow hebt ihn
     optisch vom Videohintergrund ab (sonst auf hellen Frames unsichtbar). */
  z-index: 10;
  box-shadow: 0 2px 12px rgba(20, 10, 40, 0.5);
}

@media (prefers-reduced-motion: reduce) {
  .hero-logo.reveal-flip,
  .hero-logo.reveal-fade {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
   Slide-Reveal
   Wiederverwendbarer Scroll-Reveal per [data-slide-reveal="right|left"].
   Wiederholt sich bei jedem erneuten Rein-/Rausscrollen (siehe reveal.js).
   Klasse "reveal-armed" wird erst per JS gesetzt – ohne JS bleibt der
   Inhalt regär sichtbar statt dauerhaft versteckt.
   ============================================================ */

[data-slide-reveal].reveal-armed {
  opacity: 0;
  transition: transform 0.7s var(--ease-default), opacity 0.7s var(--ease-default);
}

[data-slide-reveal="right"].reveal-armed {
  transform: translateX(clamp(40px, calc(120 / 1440 * 100vw), 160px));
}

[data-slide-reveal="left"].reveal-armed {
  transform: translateX(calc(-1 * clamp(40px, calc(120 / 1440 * 100vw), 160px)));
}

[data-slide-reveal].reveal-armed.is-revealed {
  opacity: 1;
  transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
  [data-slide-reveal].reveal-armed {
    transition: none;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ============================================================
   Sektion: Baukaesten
   Liegt AUSSERHALB von .raster (siehe Kommentar in
   section-baukaesten.php) - eigenes CSS-System, kein --tz-*.

   Scroll-Lock-Prinzip: .baukaesten bekommt per JS eine Hoehe, die
   Platz fuer (Kachel-Paare - 1) Scroll-Schritte reserviert. Waehrend
   dieser Hoehe "konsumiert" wird, bleibt .baukaesten-stage via
   position:sticky im Viewport fixiert; sobald der Container-Boden
   erreicht ist, loest sich sticky von selbst (kein JS noetig) und die
   Seite scrollt normal weiter zur naechsten Sektion ("Kontakt").

   Kachelform ist EIN Parallelogramm fuer alle Kacheln identisch (siehe
   .baukaesten-media clip-path) - anders als die individuell geformten
   Trapeze im .raster-System, deshalb hier deutlich einfacher: kein
   Normalenvektor-Versatz noetig, alle Kanten sind ohnehin parallel. */

.baukaesten {
  position: relative;
  background-color: var(--lavender);
  /* Hoehe wird per JS ueberschrieben (baukaesten-scroll.js) - dieser Wert
     ist nur der No-JS-Fallback (dann kein Scroll-Lock, aber immerhin eine
     nutzbare Flaeche statt 0px Hoehe). */
  min-height: 100vh;
}

/* HINWEIS (2026-07-21 Cleanup): Die frueheren Regeln .baukaesten-stage und
   .baukaesten-track wurden entfernt - das aktuelle Template rendert diese
   Klassen nicht (es rendert .baukaesten-sticky / .baukaesten-row, siehe
   section-baukaesten.php). Die verwaisten Regeln galten fuer einen alten
   Bauzustand. Sticky/Scroll-Layout kommt jetzt aus baukaesten-new.css.

   Ebenfalls entfernt (2026-07-21): .baukaesten-tile (war redundant -
   Layout/Form kommt jetzt vollstaendig aus baukaesten-new.css, die spaeter
   laedt und die main.css-Version ohnehin ueberschrieb) sowie .baukaesten-
   media / .baukaesten-media-inner / .baukaesten-media-inner--intro (das
   Template rendert diese Wrapper-Ebenen nicht mehr - Typo-Klassen sitzen
   direkt im .baukaesten-tile). Die Typo-Styles (.baukaesten-typ/-preis/
   -desc/-fuss/-intro-text) bleiben - sie werden genutzt und existieren nur
   hier. */

.baukaesten-typ {
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: clamp(20px, 1.9vw, 28px);
  line-height: 1.08;
  /* Kundenwunsch 2026-07-09: Headline startet 50px tiefer (Referenz
     1440px, gleiche clamp-Konvention wie sonst im Theme, z.B.
     .baukaesten-stage padding-top: 50/1440 = 3.4722vw). */
  margin-top: clamp(30px, calc(50 / 1440 * 100vw), 50px);
}

.baukaesten-preis {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(14px, 1.1vw, 16px);
  letter-spacing: 0.06em;
  /* Kundenwunsch 2026-07-09 (3. Runde): nochmal mehr Abstand - var(--space-s)
     war immer noch zu eng, jetzt var(--space-m) = 2rem/32px. */
  margin-top: var(--space-m);
}

.baukaesten-desc {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: clamp(20px, calc(20 / 1440 * 100vw), 20px);
	line-height: 1.5;
	/* Kundenwunsch 2026-07-09 (3. Runde): siehe .baukaesten-preis oben,
	   gleiche Vergroesserung auf var(--space-m). */
	margin-top: var(--space-m);
}

/* Fuss: generisch unten rechts, per margin-top:auto an den unteren
   Rand gedrueckt. Alle Tiles haben jetzt dieselbe Form - keine
   per-shape Positionierung mehr noetig. */
.baukaesten-fuss {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(10px, 0.75vw, 12px);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.6;
  margin-top: auto;
  text-align: right;
}

.baukaesten-intro-text {
  font-family: var(--font-body);
  /* Kundenwunsch 2026-07-09 (2. Runde): 400 statt 300, min. 20px statt
     15-19px. */
  font-weight: 400;
  font-size: clamp(20px, calc(20 / 1440 * 100vw), 24px);
  line-height: 1.45;
}

.baukaesten-intro-text strong {
  font-weight: 600;
}

/* ============================================================
   Mobile + Tablet (≤ 1024px)
   Vier-Kontexte-Strategie (Weg 1: "Tablet = grosses Mobile"):
   Ab Tablet Portrait (768px) und darunter wird das Desktop-Raster/
   Trapez-System verlassen - gestapelte Vollbreit-Bloecke im normalen
   Dokumentfluss statt %-Positionierung + clip-path. Tablet Landscape
   (1025-1279px) und breiter behaelt die Desktop-Geometrie.

   Ein einziger Breakpoint bei 1024px deckt Mobile Portrait/Landscape und
   Tablet Portrait/Landscape(<=1024) gemeinsam ab - bewusst KEINE
   getrennten Layouts pro Geraet (das waere Weg 2, deutlich mehr Aufwand
   ohne Mehrwert fuer einen One-Pager). Falls eine einzelne Sektion auf
   Tablet doch mehrspaltig soll, gezielt per eigenem 768px-Query
   nachruesten - nicht pauschal.

   Dekorative Trapeze (ohne Inhalt) werden ausgeblendet, Content-Trapeze
   werden zu einfachen vollbreiten Farbflaechen.
   ============================================================ */

@media (max-width: 1024px) {

  /* Baukaesten: kein Scroll-Lock mobil (wie bei Waende bewusst
     vermieden - natives Touch-Scrollen soll nicht kaputtgehen).
     Normales horizontales Swipe-Karussell stattdessen, JS erkennt die
     Breite selbst und ueberspringt die Scroll-Lock-Logik (siehe
     baukaesten-scroll.js).

     OVERFLOW-STOPP (2026-07-20): overflow-x:clip kappt den horizontalen
     Seiten-Overflow. Die Baukaesten-Tiles ragen mobil ueber die Viewport-
     breite hinaus (scrollWidth ~1060 bei 430px Viewport), weil die alten
     mobilen Swipe-Regeln auf Klassennamen zielen (.baukaesten-stage/
     -track), die das aktuelle Template GAR NICHT rendert (es rendert
     .baukaesten-sticky/.baukaesten-row) - die Regeln greifen also ins
     Leere, die Tiles werden nicht geclippt. Das erzeugte den seitenweiten
     Horizontal-Scroll, der u.a. die position:fixed-Lightbox visuell
     verschob. clip stoppt das sofort.
     ACHTUNG: nur Notnagel - die eigentliche Baukaesten-Mobile-Sektion
     (Swipe zum Laufen bringen, Klassennamen angleichen) steht noch aus. */
  .baukaesten {
    height: auto !important;
    min-height: 0;
    overflow-x: clip;
  }

  /* Baukaesten-Swipe-Karussell mobil: siehe baukaesten-new.css. Die
     frueher hier stehenden .baukaesten-stage / -track / -tile-Regeln
     wurden entfernt (2026-07-21 Cleanup) - stage/track rendert das
     Template nicht, die Tile-Regeln stehen jetzt vollstaendig in
     baukaesten-new.css (aktuelle Klassennamen .baukaesten-row /
     .baukaesten-tile). */

  .raster {
    position: static;
    aspect-ratio: unset;
    height: auto;
  }

  /* Crop-Wrapper ist ein reines Desktop-Konstrukt (gegen die leere
     Scroll-Distanz bei fester aspect-ratio) - mobil stapelt .raster
     ohnehin im normalen Dokumentfluss mit echter, contentabhaengiger
     Hoehe (height:auto oben), da gibt es keinen ungenutzten Rest zum
     Wegschneiden. */
  .raster-crop {
    aspect-ratio: unset;
    height: auto;
    overflow: visible;
  }

  .trapez--decorative {
    display: none;
  }

  .trapez--content,
  .trapez--video,
  .trapez--image {
    /* relative statt static: dient als Positionierungs-Anker fuer
       absolut positionierte Kinder wie .waende-swipe-hint - ohne eigene
       top/left/etc. Angabe hat position:relative KEINEN Effekt auf das
       Layout selbst, daher sicher fuer alle Trapez--content-Vorkommen.

       BUG-FIX: left/top MUESSEN hier explizit zurueckgesetzt werden.
       .trapez setzt unconditional left:var(--tz-left); top:var(--tz-top).
       Bei position:absolute (Desktop) ist das der Positionierungsanker -
       harmlos wenn man's vergisst zu erwaehnen. Bei position:relative
       (hier) wirkt derselbe Wert aber als VERSCHIEBUNG von der eigentlichen
       Fluss-Position aus! Trapeze mit --tz-left:0% (z.B. Handwerk-Text)
       sahen deshalb zufaellig korrekt aus, alle anderen mit nennenswertem
       --tz-left (z.B. 41.7361% bei Erst-das-Wort-Content und Handwerk-
       Video) wurden um genau diesen Prozentsatz nach rechts verschoben -
       das war die Ursache fuer die "lila Luecke links / Inhalt wirkt
       abgeschnitten"-Meldung, nicht ein Breiten-Problem. */
    position: relative;
    left: auto;
    top: auto;
    width: 100%;
    height: auto;
    clip-path: none;
  }

  /* Zickzack-"Raum"-Trennung zwischen mobilen Bloecken. Ersetzt NICHT die
     individuelle Desktop-Vector-Geometrie (waere pro Sektion eigene
     Polygon-Berechnung, siehe die Faelle bei .waende-grid heute - zu
     fragil/aufwendig für den mobilen Kontext) - reproduziert nur die
     WIRKUNG (keine harten Rechtecke) mit einem einzigen wiederverwend-
     baren Muster.

     Versatz als clamp(20px, 2.5vw, 40px) statt fixer 30px: skaliert mit
     der Viewportbreite, damit die Trennkante auf allen vier Kontexten
     (Mobile P/L, Tablet P/L) optisch gleich flach wirkt. Ein fixer
     px-Wert wuerde auf breiten Tablets zu flach, auf schmalen Handys zu
     steil aussehen. Bewusst FLACH gehalten (nicht der steile Desktop-
     Trapez-Winkel) - als Sektions-Trennung ueber die volle Breite waere
     der Desktop-Winkel ein dramatischer Keil; hier soll es nur die harte
     Rechteckkante brechen. margin-top zieht den Block in den Vorgaenger
     rein (kein Spalt an der Kante). down/up alternierend pro Sektion via
     data-diagonal-Attribut in den jeweiligen Templates. */
  /* EINHEITLICHE Schrägrichtung (Kundenwunsch Mica 2026-07-22, 2. Runde):
     Statt alternierendem Zickzack (down/up) fallen jetzt ALLE Trennkanten
     in dieselbe Richtung - linke Ecke tief, rechte Ecke hoch (Kante steigt
     nach rechts an). Beide Attribute liefern damit dieselbe Geometrie; das
     data-diagonal-Attribut bleibt in den Templates erhalten (kein Markup-
     Umbau noetig), erzeugt aber keinen Richtungswechsel mehr. Effekt:
     vollbreite Farbflaechen mit gleichgerichteten schraegen Trennkanten,
     kein Raum-Rahmen (siehe deaktivierten .is-roomed-Block unten).

     Frueheres alternierendes Zickzack (fuer Rollback aufgehoben):
       down: polygon(0 0, 100% SKEW, 100% 100%, 0 100%)  + neg. margin-top
       up:   polygon(0 SKEW, 100% 0, 100% 100%, 0 100%)  + neg. margin-top

     2026-07-22 (3. Runde, Option 1): Richtung auf nach-rechts-ANSTEIGEND
     (Oberkante linke Ecke TIEF bei y=skew, rechte Ecke HOCH bei y=0)
     festgelegt - parallel zur Hero-Band-Unterkante (die ebenfalls nach
     rechts ansteigt, siehe .hero-subline.is-roomed-band). So laufen alle
     Trennkanten und Lavender-Spalten parallel (Kundenwunsch Mica). */
  [data-diagonal="down"],
  [data-diagonal="up"] {
    clip-path: polygon(0 clamp(20px, 2.5vw, 40px), 100% 0, 100% 100%, 0 100%);
    margin-top: calc(-1 * clamp(20px, 2.5vw, 40px));
  }

  /* ── "Raum"-Rahmen (Testlauf, Sektion "Am Anfang war das Wort") ──
     Kundenwunsch 2026-07-22: der Desktop-Raumeindruck (farbige Flaechen
     schwimmen im Lavender-Body) fehlt mobil. Loesung: die betroffenen
     Bloecke werden per margin ringsum eingerueckt, der Body-Lavender
     scheint rundum durch = "Raum". Zusaetzlich (2. Runde) sollen alle
     Trennkanten PARALLEL in dieselbe Richtung geneigt sein, damit der
     Lavender-Spalt zwischen zwei Raeumen ueberall GLEICH BREIT ist.

     Aktiviert ausschliesslich ueber .is-roomed am Element (aktuell die
     zwei Bloecke in section-erst-das-wort.php + das Hero-Band, das die
     Oberkante des ersten Raums fluchten muss).

     ZURUECKSCHALTEN: die Klasse is-roomed aus den Templates nehmen (oder
     diesen Block auskommentieren) - nichts anderes wird beruehrt.

     ── Geometrie ──
     Alle Trennkanten fallen nach RECHTS ab (linke Ecke hoch, rechte Ecke
     tief). Versatz = --room-skew, an EINER Stelle justierbar. Damit zwei
     benachbarte Kanten parallel laufen, muss die Unterkante des oberen
     Blocks denselben Abfall haben wie die Oberkante des unteren:

       Honey-Band:  Unterkante faellt nach rechts ab
       Text-Block:  Oberkante UND Unterkante fallen nach rechts ab (parallel)
       Video-Block: Oberkante faellt nach rechts ab, Unterkante gerade

     Eine nach rechts abfallende Kante heisst: linke Ecke bei y=0 (bzw.
     100%-skew unten), rechte Ecke um --room-skew tiefer (bzw. 100% unten).

     WICHTIG width:auto - der .trapez--content/-video-Mobile-Block oben
     setzt width:100%. Zusammen mit margin-inline liefe das Element rechts
     ueber (100% + Margin) und der rechte Rand wuerde von overflow-x:hidden
     weggeschnitten -> KEIN rechter Lavender-Rand (genau der Bug aus der
     1. Runde). width:auto laesst margin-inline echten Rand bilden.

     WICHTIG !important am clip-path - derselbe Block oben setzt
     clip-path:none fuer .trapez--content/-video. Ohne !important gaebe es
     hier keine Schraege. Die [data-diagonal]-Regeln greifen fuer die
     geroomten Bloecke damit NICHT mehr (bewusst - sie sind das alte
     alternierende Zickzack, das hier durch die parallele Fluchtung
     ersetzt wird). */
  /* ── DEAKTIVIERT (Kundenwunsch Mica 2026-07-22, 2. Runde) ──
     Der "Raum"-Rahmen (margin ringsum + eigene clip-paths) wurde von Mica
     verworfen: er will VOLLBREITE Farbflaechen ohne Seitenrand, nur mit
     schraegen Trennkanten zwischen den Farben (siehe die einheitliche
     [data-diagonal]-Regel oben). Die margin-basierten .is-roomed-Regeln
     sind daher entfernt; die Klassen .is-roomed / .is-roomed-band bleiben
     vorerst in den Templates (section-erst-das-wort.php, section-hero.php),
     matchen aber kein CSS mehr - sie sind funktionslos und koennen bei
     naechster Gelegenheit aus den Templates raus.

     ROLLBACK (falls Mica erneut den Rahmen will) - die entfernten Regeln
     lauteten, jeweils im @media (max-width:1024px):

       .is-roomed {
         --room-skew: clamp(20px, 2.5vw, 40px);
         width: auto;
         margin-inline: clamp(12px, 4vw, 28px);
         margin-block: clamp(12px, 4vw, 28px);
       }
       .trapez--content.is-roomed {
         clip-path: polygon(0 var(--room-skew), 100% 0,
           100% calc(100% - var(--room-skew)), 0 100%) !important;
       }
       .trapez--video.is-roomed {
         clip-path: polygon(0 var(--room-skew), 100% 0, 100% 100%, 0 100%) !important;
         margin-bottom: calc(clamp(12px,4vw,28px) + clamp(20px,2.5vw,40px));
       }
       .hero-subline.is-roomed-band {
         --room-skew: clamp(20px, 2.5vw, 40px);
         clip-path: polygon(0 0, 100% 0,
           100% calc(100% - var(--room-skew)), 0 100%);
       }

     Hinweis fuer den Rollback: damals war die Video-Unterkante GERADE
     (Rahmen-Look). Beim jetzigen Vollbreit-Look ist die Video-OBERkante
     die schraege Trennkante (via [data-diagonal]) - nicht verwechseln. */

  /* ── Hero-Band: schraege Unterkante (Kundenwunsch Mica 2026-07-22,
     IMG_5885-edit) ──
     Die Honey-Flaeche des Hero endet unten NICHT gerade, sondern schraeg
     nach rechts ANSTEIGEND (↗): linke Ecke tief, rechte Ecke hoch. Der
     Lavender-Rand darunter laeuft parallel dazu. Die Subline ist der
     unterste Bandteil, also traegt sie die untere Bandkante - Logo-Wrap
     darueber bleibt ungeschnitten. Klasse .is-roomed-band sitzt schon an
     beiden Hero-Elementen (section-hero.php).

     Polygon: Oberkante gerade, Unterkante steigt nach rechts an.
       unten-links  (0, 100%)             tief
       unten-rechts (100%, 100% - skew)   hoch  -> ansteigend ↗ */
  .hero-subline.is-roomed-band {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 0,
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    );
  }

  /* ── (A) Lavender-Rand zwischen Hero und "Am Anfang" ──
     Kundenwunsch Mica 2026-07-22: sichtbarer Lavender-Streifen zwischen
     Hero-Band und dem ersten Farbblock. Die einheitliche [data-diagonal]-
     Regel oben zieht JEDEN Block per negativem margin-top in den
     Vorgaenger (kein Spalt) - fuer den ersten Block wird das hier gezielt
     ueberschrieben: positiver Abstand statt negativer. NUR dieser eine
     Block (Text-Block = einziges .trapez--content mit data-diagonal=down),
     alle anderen Trennkanten bleiben spaltlos verzahnt. Die schraege
     Oberkante (aus [data-diagonal]) bleibt erhalten - der Lavender-Streifen
     laeuft also parallel zur Schraege.

     KORREKTUR 2026-09-04 (Mica): Der Streifen entsteht NICHT erst durch
     diesen margin. Beide angrenzenden Kanten sind bereits um --room-skew
     angeschraegt (Hero-Subline-Unterkante ↗ + Oberkante dieses Blocks ↗),
     das ergibt von sich aus einen Spalt von --room-skew:

       sichtbare Streifenbreite = --room-skew + margin-top

     Der frueher hier stehende POSITIVE Wert (clamp(10px,1.2vw,20px))
     addierte sich also auf den ohnehin vorhandenen Spalt - Streifen war
     rund doppelt so breit wie gedacht und liess sich nicht feinjustieren
     (0 oder Loeschen sprang zwischen vollem Spalt und gar keinem, weil
     dann der globale negative margin greift). Jetzt NEGATIV: der Wert
     zieht den Block wieder ein Stueck in den Hero hinein und verschmaelert
     den Streifen gezielt.

     Zielbreite: 0.7 x --room-skew (bei 430px Viewport = 14px, in DevTools
     live gegen den Kunden-Screenshot verifiziert). Umgestellt auf einen
     RELATIVEN Faktor statt eines festen px-Werts (2026-09-04): --room-skew
     skaliert von 20px (<=800px Viewport) bis 25.6px (bei 1024px). Ein fixer
     -6px liesse den Streifen dort auf ~19px auseinanderlaufen, waehrend die
     Schraege mitwaechst. Mit dem Faktor bleibt das Verhaeltnis Streifen zu
     Schraege ueber alle Viewports konstant.

       sichtbarer Streifen = --room-skew + margin-top
                           = skew - 0.3*skew = 0.7*skew

     --room-skew hier lokal gesetzt, damit die Regel unabhaengig davon
     funktioniert, ob ein spezifischerer Block den Wert liefert. Andere
     .trapez--content[data-diagonal="down"]-Bloecke (is-handwerk,
     is-fassungen, is-waende, is-waende-video) ueberschreiben margin-top
     ohnehin in eigenen, spezifischeren Regeln - der Faktor trifft sie nicht.

     ROLLBACK: margin-top: 0  -> voller Spalt (= --room-skew).
     Regel ganz loeschen -> globaler negativer margin greift, KEIN Streifen. */
  .trapez--content[data-diagonal="down"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    margin-top: calc(var(--room-skew) * -0.3);
  }

  /* Lila Block UNTERKANTE ebenfalls schraeg ansteigend (Kundenwunsch Mica
     2026-07-22): damit das Video darunter als freistehendes Trapez rundum
     Lavender bekommt, muss die Unterkante des lila Blocks parallel zur
     Video-Oberkante laufen (beide ↗). Sonst waere der Lavender-Spalt
     zwischen lila Block und Video keilfoermig. [data-diagonal] macht nur
     die Oberkante schraeg - hier beide Kanten explizit, daher !important.
       Oberkante  ↗  (0,skew) -> (100%,0)
       Unterkante ↗  (0,100%) -> (100%,100%-skew) */
  .trapez--content.is-roomed[data-diagonal="down"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    ) !important;
  }

  /* ── (B) Eingerahmtes Video-TRAPEZ ("Am Anfang", .is-framed) ──
     Kundenwunsch Mica 2026-07-22 (IMG_5886-edit, finale Fassung): NUR
     dieses eine Video schwebt als freistehendes Trapez mit Lavender auf
     ALLEN VIER Seiten. Sonderfall - kein anderes Video bekommt das.

     Form = TRAPEZ (Ober- und Unterkante GEGENLAEUFIG, oeffnet sich nach
     rechts):
       Oberkante  steigt nach rechts an  (0,skew) -> (100%,0)      ↗
       Unterkante faellt nach rechts ab  (0,100%-skew) -> (100%,100%) ↘
     Die Oberkante (↗) laeuft parallel zur Unterkante des lila Blocks
     darueber (gleicher Lavender-Spalt). Die Unterkante (↘) ist die
     gegenlaeufige Trapez-Kante - ihr Anschluss an "Zwei Gewerke" wird
     separat geloest. !important, weil [data-diagonal] gleiche Spezifitaet
     hat.

     RAND ALLE VIER SEITEN: margin-block (oben/unten) + margin-inline
     (links/rechts). width:auto ist zwingend - der .trapez--video-Mobile-
     Block setzt width:100%; zusammen mit margin-inline liefe das Element
     sonst rechts ueber und overflow-x:hidden wuerde den rechten Rand
     wegschneiden (Bug aus der 1. Session). --room-skew lokal (Rand so
     breit wie die Schraege).

     OBEN/UNTEN SCHMALER (Kundenwunsch Mica 2026-09-04, IMG_5944): die
     beiden waagerechten Raender waren zu breit. Wichtig zum Verstaendnis -
     der sichtbare Rand ist NICHT gleich dem margin:

       oben  = margin-top + --room-skew
               (der clip-path schneidet die Oberkante bereits um skew weg)
       unten = margin-bottom + --room-skew + --room-skew
               (Schnitt der Unterkante PLUS der durchgeklappte margin-top
                von .is-handwerk: .handwerk-section-wrap ist ein block ohne
                Padding/Border, der margin-top seines ersten Kindes klappt
                heraus und schiebt die Honey-Flaeche zusaetzlich um skew
                nach unten -> Margin-Collapsing)

     Deshalb braucht UNTEN einen um genau --room-skew groesseren Negativ-
     betrag als oben, um optisch denselben Rand zu ergeben. Beide auf
     dieselbe Zielbreite gerechnet wie der Hero-Streifen (0.7 x --room-skew,
     = 14px bei 430px Viewport), damit alle Lavender-Spalte der Seite gleich
     breit sind:

       oben:   0.7*skew = skew + margin-top      -> margin-top:    -0.3*skew
       unten:  0.7*skew = 2*skew + margin-bottom -> margin-bottom: -1.3*skew

     Relative Faktoren statt fixer px-Werte, damit die Raender mit der
     Schraege mitskalieren (--room-skew laeuft von 20px bis 25.6px im
     mobilen Bereich).

     SEITLICH ebenfalls auf 0.7 x skew (2026-09-04, gleiche Runde): hier
     schneidet kein clip-path, der margin IST der sichtbare Rand - also
     direkt 0.7*skew statt der frueheren vollen skew-Breite. Damit ist der
     Lavender-Rand rundum gleich breit (Kundenwunsch Mica).

     ROLLBACK (Stand vor 2026-09-04):
       margin-top: clamp(10px, 1.2vw, 20px);
       margin-bottom: var(--room-skew);
       margin-inline: var(--room-skew); */
  .trapez--video.is-framed {
    --room-skew: clamp(20px, 2.5vw, 40px);
    width: auto;
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% 100%,
      0 calc(100% - var(--room-skew))
    ) !important;
    margin-top: calc(var(--room-skew) * -0.3);
    margin-bottom: calc(var(--room-skew) * -1.3);
    margin-inline: calc(var(--room-skew) * 0.7);
  }

  /* ── Handwerk-Wrapper: durchgehender honey-Hintergrund (Kundenwunsch
     Mica 2026-07-22, roter Pfeil) ──
     Wie .waende-section-wrap: mobil eine echte honey-Flaeche, gegen die
     das Showreel-Video mit seiner schraegen ↗-Unterkante abschliesst. Der
     clip-path des Videos legt sonst den lavender .raster-Body als Keil
     frei - mit honey dahinter ist der lavender-Rand strukturell weg,
     ohne fragile negative margins. Desktop: display:contents (oben),
     Wrapper wirkungslos, Trapeze bleiben absolut im .raster. */
  .handwerk-section-wrap {
    display: block;
    background-color: var(--honey);
    /* Oberkante ↘ (parallel zur Unterkante des "Am Anfang"-Video-Trapezes
       darueber, Kundenwunsch Mica 2026-07-22): sonst laeuft der Lavender-
       Streifen zwischen Video-Unterkante (↘) und honey-Oberkante keil-
       foermig - oben schraeg (Video), unten gerade (Wrapper). Mit gleicher
       ↘-Neigung ist der Streifen ueberall gleich breit und folgt der
       Video-Schraege.
         Video-Unterkante ↘:  (0,100%-skew) -> (100%,100%)  links hoch, rechts tief
         Wrapper-Oberkante ↘: (0,0) -> (100%,skew)          gleiche Neigung
       ROLLBACK: clip-path entfernen -> gerade Oberkante wie zuvor. */
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 0,
      100% var(--room-skew),
      100% 100%,
      0 100%
    );
  }

  /* ── "Zwei Gewerke" Honey-Oberkante: Anschluss an das Video-Trapez
     darueber (Kundenwunsch Mica 2026-07-22) ──
     Die Honey-Flaeche von "Zwei Gewerke" (= der Text-Block, mobil das
     erste Element der Sektion) bekommt eine schraege Oberkante, die
     PARALLEL zur Video-UNTERkante darueber laeuft: beide fallen nach
     rechts ab (↘). Dadurch schliesst die Honey-Flaeche das Video-Trapez
     nach unten sauber ab, mit Lavender-Spalt dazwischen.

     Das ueberschreibt die einheitliche [data-diagonal=down]-Oberkante
     (die ↗ ansteigt) - hier bewusst ↘ abfallend, weil sie zur
     gegenlaeufigen Video-Unterkante passen muss, nicht zur allgemeinen
     Trennkanten-Richtung. Nur dieser eine Block (.is-handwerk), daher
     kein Konflikt mit der globalen Regel. !important wegen gleicher
     Spezifitaet.

     Oberkante ↘:  (0,0) -> (100%,skew)   linke Ecke hoch, rechte tief
     margin-top positiv = Lavender-Spalt zum Video (statt des negativen
     [data-diagonal]-margins, der den Block hochzoege). Betrag = --room-skew
     (gleicher schmaler Abstand wie der Video-Rand ringsum). */
  .trapez--content.is-handwerk[data-diagonal="down"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 0,
      100% var(--room-skew),
      100% 100%,
      0 100%
    ) !important;
    margin-top: var(--room-skew);
  }

  /* ── Handwerk-Video (.is-handwerk-video) UNTERKANTE schraeg ansteigend
     (Kundenwunsch Mica 2026-07-22, roter Pfeil im Korrektur-Screenshot) ──
     Das Showreel-Video unter "Zwei Gewerke" hatte mobil eine GERADE
     Unterkante - dadurch schien der lavender .raster-Hintergrund als Rand
     durch. Jetzt beide Kanten ↗ parallel (Parallelogramm), identisch zur
     Form von .is-waende-video. Der honey-BG des Videos stoesst damit
     schraeg an die naechste Sektion, kein lavender-Rand mehr.

     Das Video traegt data-diagonal="up" und fiel bisher auf die globale
     [data-diagonal="up"]-Regel zurueck (Oberkante ↗, Unterkante gerade).
     Eigene Klasse .is-handwerk-video (section-handwerk.php) macht es
     eindeutig targetbar. !important gegen die gleich spezifische
     [data-diagonal]-Regel.

       Oberkante  ↗  (0,skew) -> (100%,0)
       Unterkante ↗  (0,100%) -> (100%,100%-skew)

     ROLLBACK: Diesen Block loeschen + Klasse is-handwerk-video im PHP
     entfernen -> zurueck zur globalen Regel (gerade Unterkante). */
  .trapez--video.is-handwerk-video[data-diagonal="up"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    ) !important;
  }

  /* ── Logo-Loop-Film ("Ein Raum fuer Alle"-Sektion) UNTERKANTE schraeg
     ansteigend (Kundenwunsch Mica 2026-07-22) ──
     Der Logo-Loop-Film hatte mobil eine GERADE Unterkante (fiel auf die
     globale [data-diagonal="up"]-Regel zurueck: Oberkante ↗, Unterkante
     gerade). Jetzt beide Kanten ↗ parallel (Parallelogramm) - Unterkante
     wie die eigene Oberkante. Eindeutige Klasse .trapez--logo-loop, daher
     kein PHP-Eingriff noetig. !important gegen die gleich spezifische
     [data-diagonal]-Regel.

       Oberkante  ↗  (0,skew) -> (100%,0)
       Unterkante ↗  (0,100%) -> (100%,100%-skew)

     ROLLBACK: Diesen Block loeschen -> zurueck zur globalen Regel (gerade
     Unterkante). */
  .trapez--video.trapez--logo-loop[data-diagonal="up"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    ) !important;
  }

  /* ── Elefanten-Block (lime) UNTERKANTE schraeg ansteigend + Lavender-
     Spalt zur Fassungen-Sektion darunter (Kundenwunsch Mica 2026-09-02) ──
     Der lime "Elefanten"-Block hatte mobil oben eine ↗-Kante (aus der
     globalen [data-diagonal="up"]-Regel), unten gerade + negativen
     margin-top am Folgeblock (spaltlos verzahnt). Jetzt soll er UNTEN
     eine gleich geneigte ↗-Kante bekommen, mit sichtbarem Lavender-
     Streifen (= durchscheinender .raster-Body) zum Elefanten-Bild darunter.

     Damit wird der Block zum PARALLELOGRAMM (beide Kanten ↗ parallel),
     der Streifen laeuft parallel zur Oberkante des Bild-Trapezes darunter
     (.trapez--image, ebenfalls ↗) -> gleichmaessig breit, kein Keil.

       Oberkante  ↗  (0,skew) -> (100%,0)
       Unterkante ↗  (0,100%) -> (100%,100%-skew)

     Spalt = margin-bottom var(--room-skew) (Streifenbreite = Schraege).
     Eigene Klasse .is-elefanten (section-elefanten.php) macht den Block
     eindeutig targetbar. !important gegen die gleich spezifische
     [data-diagonal]-Regel.

     WICHTIG: Der Lavender-Streifen bleibt nur stehen, weil das Bild-Trapez
     darunter margin-top:0 hat (aus dem Reset, kein data-diagonal - also
     kein negativer margin, der den Spalt auffraesse). Mobile Fluss-
     Reihenfolge (per DOM verifiziert): lime-Block -> BILD -> mauve
     Fassungs-Text; die Filler [12]/[15]/[16] der Fassungen-Sektion sind
     mobil display:none (.trapez--decorative).

     ROLLBACK: Diesen Block loeschen, Klasse is-elefanten im PHP entfernen
     -> zurueck zur globalen Regel (gerade Unterkante, spaltlos). */
  .trapez--content.is-elefanten[data-diagonal="up"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    ) !important;
    /* Streifenbreite auf dieselbe Zielbreite wie alle anderen Lavender-
       Spalte der Seite: 0.7 x --room-skew (= 14px bei 430px Viewport,
       Kundenwunsch Mica 2026-09-04, Angleich an den Hero-Streifen).

       Wichtig zum Verstaendnis: die Oberkante des Bild-Trapezes darunter
       ist bereits um --room-skew angeschraegt, das ergibt von sich aus
       einen Spalt dieser Breite:

         sichtbarer Streifen = --room-skew + margin-bottom

       Der vorherige POSITIVE Wert (clamp(10px,1.2vw,20px)) addierte sich
       also auf und ergab ~30px statt der gewuenschten 14px. Jetzt negativ,
       als Faktor statt fixem px-Wert, damit der Streifen mit der Schraege
       mitskaliert. Die Schraege selbst (clip-path oben) bleibt --room-skew,
       damit die Kante parallel zur Bild-Oberkante laeuft.
       ROLLBACK: clamp(10px, 1.2vw, 20px) bzw. var(--room-skew). */
    margin-bottom: calc(var(--room-skew) * -0.3);
  }

  /* ── Elefanten-Bild (.trapez--image) als PARALLELOGRAMM + Lavender-Spalt
     nach oben (zum lime-Block) UND unten (zum mauve Fassungs-Text)
     (Kundenwunsch Mica 2026-09-02) ──
     Mobile Fluss-Reihenfolge (per DOM verifiziert, Filler dazwischen sind
     display:none): lime-Block (.is-elefanten) -> BILD (.trapez--image) ->
     mauve Fassungs-Text (.is-fassungen). Das Bild lag als hartes Rechteck
     dazwischen (clip-path:none aus der Reset-Regel oben, keine Schraege).
     Jetzt beide Kanten ↗ parallel - oben fluchtend zur lime-Unterkante,
     unten zur mauve-Oberkante, beide Lavender-Streifen gleich breit.

       Oberkante  ↗  (0,skew) -> (100%,0)
       Unterkante ↗  (0,100%) -> (100%,100%-skew)

     Der obere Streifen entsteht aus dem margin-bottom des lime-Blocks
     (.is-elefanten, Regel oben); das Bild hat margin-top:0 (aus dem
     Reset, kein data-diagonal), fraesse ihn also nicht auf. Der untere
     Streifen entsteht aus margin-bottom hier; er bleibt stehen, weil der
     mauve Block darunter margin-top:0 hat (.is-fassungen-Regel unten).

     .trapez--image kommt nur einmal auf der Seite vor (Elefanten-Bild),
     daher generische Klasse ohne eigene Kennung ausreichend. Werte live
     in DevTools verifiziert (beide Streifen exakt --room-skew, 2026-09-02).
     ROLLBACK: diesen Block loeschen -> Bild wieder gerades Rechteck. */
  .trapez--image {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    );
    /* Untere Streifenbreite auf dieselbe Zielbreite wie oben und wie alle
       anderen Lavender-Spalte der Seite: 0.7 x --room-skew (= 14px bei
       430px Viewport, Kundenwunsch Mica 2026-09-04).

         sichtbarer Streifen = --room-skew + margin-bottom

       Die Unterkante hier ist bereits um --room-skew angeschraegt; der
       vorherige POSITIVE Wert addierte sich darauf (~30px statt 14px).
       Faktor statt fixem px-Wert, damit der Streifen mit der Schraege
       mitskaliert. clip-path bleibt --room-skew fuer Parallelitaet zur
       mauve-Oberkante. ROLLBACK: clamp(10px, 1.2vw, 20px). */
    margin-bottom: calc(var(--room-skew) * -0.3);
  }

  /* Neutralisiert den negativen margin-top der globalen [data-diagonal=
     "down"]-Regel am Fassungs-Text-Block (mauve), damit der Lavender-Spalt
     oberhalb (aus dem margin-bottom des Bildes) stehen bleibt statt wieder
     hochgezogen zu werden. Mobil ist der mauve Block der direkte Nachbar
     UNTER dem Elefanten-Bild - die Filler [12]/[15]/[16] der Fassungen-
     Sektion sind mobil display:none (.trapez--decorative).
     ROLLBACK: diese Regel loeschen. */
  .trapez--content.is-fassungen[data-diagonal="down"] {
    margin-top: 0;
  }

  /* ── Wände-Sektion: lila Block als Trapez auf durchgehendem Honey
     (Kundenwunsch Mica 2026-07-22, IMG_5887-edit + Korrektur-Screenshots) ──
     Der Wrapper .waende-section-wrap traegt mobil den durchgehenden honey-
     Hintergrund. Dadurch ist KEIN lavender mehr sichtbar, egal was die
     clip-paths der inneren Bloecke freilegen - dahinter liegt immer honey.
     Das loest das "lavender scheint durch"-Problem strukturell statt mit
     fragilen negativen margins.

     Auf DESKTOP muss der Wrapper wirkungslos sein: display:contents nimmt
     ihn aus dem Layout, die inneren .trapez-Bloecke bleiben absolut im
     .raster positioniert wie bisher. Nur mobil (hier im Query) wird er zu
     einer echten honey-Flaeche. */
  .waende-section-wrap {
    /* display:contents (Desktop-Default) erzeugt KEINE Box und koennte
       keinen Hintergrund zeigen - mobil daher zurueck auf block, damit
       der honey-BG rendert. */
    display: block;
    background-color: var(--honey);
    --room-skew: clamp(20px, 2.5vw, 40px);
    /* margin-top negativ (Kundenwunsch Mica 2026-07-22): der honey-Wrapper
       begann bisher 20px unter der Handwerk-Video-Unterkante - in dem
       Spalt schien der lavender .raster-Body durch (Fehler-Screenshot:
       lavender Streifen zwischen "Zwei Gewerke"-Video und lila Block).
       Hochziehen um --room-skew laesst die honey-Flaeche direkt an den
       Handwerk-Wrapper anschliessen -> durchgehend honey, kein lavender.
       Der sichtbare schmale Abstand zum lila Block kommt allein aus dessen
       margin-top (unten, auf 10px reduziert). Desktop: display:contents,
       margin wirkungslos. ROLLBACK: margin-top entfernen. */
    margin-top: calc(-1 * clamp(10px, 1.2vw, 20px));
  }

  /* Innerer lila Block: VOLLBREIT (side-to-side, kein seitlicher margin),
     Trapez-Schraege, nur oben/unten honey-Spalt via margin-block. Der
     honey-Spalt zeigt jetzt den Wrapper-BG (durchgehend honey).

     Trapez (Kundenwunsch Mica 2026-07-22, Korrektur): Oberkante ↗,
     Unterkante ↘ - der Block oeffnet sich nach rechts. NICHT mehr
     Parallelogramm (beide ↗). Nur der lila Waende-Block, das Video-
     Karussell darunter bleibt unveraendert.
       Oberkante  ↗  (0,skew) -> (100%,0)         links tief, rechts hoch
       Unterkante ↘  (0,100%-skew) -> (100%,100%)  links hoch, rechts tief

     margin-block asymmetrisch (Kundenwunsch Mica 2026-07-22): oben nur
     ~10px (schmaler honey-Abstand zum "Zwei Gewerke"-Video darueber, jetzt
     honey statt lavender - siehe .waende-section-wrap margin-top), unten
     voller --room-skew. ROLLBACK: zurueck auf margin-block: var(--room-skew).
     ROLLBACK Trapez->Parallelogramm: Unterkante wieder auf
     100% calc(100%-skew), 0 100%. */
  .is-waende .waende-content {
    --room-skew: clamp(20px, 2.5vw, 40px);
    background-color: var(--indigo);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% 100%,
      0 calc(100% - var(--room-skew))
    );
    margin-block: clamp(10px, 1.2vw, 20px) var(--room-skew);
    margin-inline: 0;
    padding-top: var(--space-l);
    padding-bottom: var(--space-l);
  }

  /* Aeussere Bloecke: clip-path + margin zuruecksetzen. Farbe brauchen sie
     nicht mehr (Wrapper traegt honey). Der Text-Block (.is-waende) wird zur
     reinen Huelle fuer den inneren lila Block - transparent, keine Schraege
     (die traegt der innere Block). Der Video-Block (.is-waende-video)
     behaelt seinen honey-BG und bekommt das Parallelogramm (unten). */
  .trapez--content.is-waende {
    background-color: transparent !important;
    clip-path: none !important;
    margin: 0 !important;
  }

  /* Punkt 3 (Korrektur-Screenshot): Wände-Video als PARALLELOGRAMM -
     Unterkante gleiche Neigung wie Oberkante (↗). [data-diagonal] macht
     nur die Oberkante schraeg, Unterkante blieb gerade. Hier beide ↗
     parallel. !important gegen [data-diagonal].

     ACHTUNG: Dieser Block traegt mobil das Grid, das im 1279er-Karussell-
     Breakpoint zu flex/overflow-scroll umgebaut wird. Der clip-path
     maskiert nur die aeussere Box, stoert das Karussell nicht.

     ABSTAND OBEN VERKLEINERT (Kundenwunsch Mica 2026-09-04, IMG_5945):
     der Honey-Abstand zwischen lila Waende-Block und der ersten Video-
     Kachel war deutlich groesser als der darunter. Er setzt sich zusammen
     aus: margin-bottom des lila Blocks (--room-skew) + dem Schrägversatz
     der Oberkante hier (--room-skew) + padding des .waende-grid
     (--space-m); unten steht nur das Grid-Padding.

     Korrigiert wird der Schrägversatz-Anteil, per negativem margin-top an
     DIESEM Block (frueher margin:0 !important). Das ist die unkritische
     Stelle: dahinter liegt .waende-section-wrap mit durchgehendem honey,
     der clip-path legt also nur wieder honey frei - es ueberlappen keine
     Farbflaechen (ein negativer margin-bottom am LILA Block dagegen liesse
     den spaeter im DOM stehenden Video-Block ueber dessen Schraege malen).

     WICHTIG: das Grid-Padding NICHT zusaetzlich reduzieren - dann schneidet
     die Schraege in die Kacheln (in DevTools getestet, 2026-09-04).

     calc(var(--room-skew) * -1) statt fixer -20px, damit der Pull mit der
     Schraege mitskaliert. margin-inline bleibt 0, damit die honey-Video-
     flaeche buendig an den Wrapper-Rand stoesst.
     ROLLBACK: margin: 0 !important; */
  .trapez--content.is-waende-video[data-diagonal="down"] {
    --room-skew: clamp(20px, 2.5vw, 40px);
    clip-path: polygon(
      0 var(--room-skew),
      100% 0,
      100% calc(100% - var(--room-skew)),
      0 100%
    ) !important;
    margin: calc(var(--room-skew) * -1) 0 0 !important;
  }

  /* Video-Wand: groesserer Abstand NACH UNTEN (Kundenwunsch Mica
     2026-09-04, IMG_5945) ──
     Der Abstand ueber der ersten Kachel ist bauartbedingt groesser als der
     darunter:

       oben  = margin-bottom des lila Blocks (--room-skew) + Grid-Padding
       unten = Grid-Padding allein

     Der Versuch, OBEN zu verkleinern, ist gescheitert (negativer margin am
     lila Block laesst den spaeter im DOM stehenden Video-Block ueber dessen
     Schraege malen; Grid-Padding kappen schneidet die Schraege in die
     Kacheln). Entscheidung Mica: stattdessen unten angleichen - beide
     Raender damit etwas breit, aber gleichmaessig.

     Der Zuschlag ist exakt die Differenz von oben (--room-skew), nicht ein
     geschaetzter px-Wert - damit bleiben beide Seiten auch dann gleich,
     wenn --room-skew mit der Viewportbreite waechst (20px bis 25.6px im
     mobilen Bereich). --room-skew wird vom Elternblock
     .is-waende-video geerbt.

     BEWUSST HIER im 1024er-Block, nicht bei .waende-grid im 1279er-Block:
     zwischen 1025 und 1279px laeuft zwar auch das Karussell, dort sind die
     umgebenden Trapeze aber noch absolut im Desktop-Raster positioniert -
     zusaetzliches Padding liefe aus dem Slot.

     SELEKTOR: bewusst mit dem Elternblock qualifiziert. Die .waende-grid-
     Regel im 1279er-Block steht SPAETER in der Datei und setzt padding als
     SHORTHAND - bei gleicher Spezifitaet gewinnt sie und wuerde das
     padding-bottom hier ueberschreiben (erst so getestet, wirkungslos).
     Der zusaetzliche Klassenselektor hebt die Spezifitaet an, damit die
     Reihenfolge egal ist.

     ROLLBACK: diese Regel loeschen -> padding rundum var(--space-m). */
  .is-waende-video .waende-grid {
    padding-bottom: calc(var(--space-m) + var(--room-skew));
  }

  /* ============================================================
     VARIANTE B (vorbereitet, DEAKTIVIERT) - Videowand ohne Schraegen
     ============================================================
     Fuer den Fall, dass Mica die Referenzvideo-Sektion mobil ohne die
     lila Schraege oben und die gruene Schraege unten sehen will.
     Vorbereitet 2026-09-04, kurz aktiviert, auf Wunsch zurueckgerollt -
     aktueller Stand ist Variante A (mit Schraegen, Original-Regeln oben).

     NUR die beiden Kanten direkt UM die Videowand herum werden gerade -
     die Oberkante des lila Blocks (Uebergang vom Handwerk-Video) bleibt
     schraeg, ebenso alle anderen Sektionstrennungen der Seite.

     Der Gewinn: ohne Schraegversatz fliesst nichts mehr in den Abstand
     ein - margin-bottom des lila Blocks und das Grid-Padding SIND dann
     direkt die sichtbaren honey-Raender und lassen sich ohne Verrechnung
     auf die Zielbreite (14px, wie alle Lavender-Spalte der Seite) setzen.

     ACHTUNG bei der letzten Regel: margin-top MUSS auf 0, sonst zieht der
     globale negative margin der [data-diagonal]-Regel den lime-Block ueber
     die honey-Flaeche. Das margin-bottom dort NICHT anfassen - es steuert
     den Lavender-Spalt zum Elefanten-Bild und gehoert nicht zu dieser
     Variante.

     AKTIVIEREN: den Kommentar so aufteilen, dass die vier Regeln als Code
     dastehen - diesen Kommentarblock also direkt vor .is-waende schliessen
     und hinter der letzten Regel wieder oeffnen. Sie stehen bewusst NACH
     den Original-Regeln und gewinnen damit bei gleicher Spezifitaet.
     ROLLBACK: wieder auskommentieren - die Original-Regeln oben bleiben
     unveraendert stehen und greifen sofort wieder.

  .is-waende .waende-content {
    clip-path: polygon(0 var(--room-skew), 100% 0, 100% 100%, 0 100%);
    margin-block: clamp(10px, 1.2vw, 20px) 14px;
  }

  .trapez--content.is-waende-video[data-diagonal="down"] {
    clip-path: none !important;
    margin: 0 !important;
  }

  .is-waende-video .waende-grid {
    padding-bottom: 14px;
  }

  .trapez--content.is-elefanten[data-diagonal="up"] {
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--room-skew)), 0 100%) !important;
    margin-top: 0;
  }

     ==================== Ende Variante B ==================== */

  /* Bild-Trapez mobil: wie die Video-Trapeze vollbreit im Fluss, aber
     ohne den scale(1.35)-Zoom - Bild wie Video liegen mit 1.5:1 bzw.
     1.462:1 fast exakt auf dem Slot-Verhaeltnis (1.486:1), da gibt es
     nichts wegzucroppen.

     2026-09-14: gilt jetzt auch fuer video (der Slot kann wahlweise Bild
     oder muted Loop enthalten, siehe section-elefanten.php). Ohne diese
     Zeile faellt ein <video> mobil auf die Standardgroesse 300x150 zurueck,
     solange die Metadaten nicht geladen sind - das Trapez hat mobil keine
     --tz-height-Bezugshoehe mehr, es gibt also nichts, woraus die Hoehe
     sonst kaeme. Sichtbarer Sprung beim Laden.
     ROLLBACK: video aus dem Selektor entfernen. */
  .trapez--image img,
  .trapez--image video {
    aspect-ratio: 3 / 2;
  }

  .trapez--video video {
    aspect-ratio: 16 / 9;
    /* Zoom + Ankerpunkt rechts: object-fit:cover allein greift nicht,
       wenn das Quellvideo bereits nahe 16:9 ist (kein Spielraum zum
       Croppen). transform-origin:right sorgt dafuer, dass beim Skalieren
       nur die linke Seite (Richtung Wand) waechst und vom overflow:hidden
       am .trapez--video weggeschnitten wird - die rechte Seite (Model)
       bleibt stabil/sichtbar. 1.35 als Startwert, nicht final kalibriert -
       Model in Chrome ansehen und Faktor anpassen (mehr/weniger Wand). */
    transform: scale(1.35);
    transform-origin: right center;
  }

  /* Logo-Loop mobil: volle Breite, 16:9, GANZES Video sichtbar (Kunden-
     wunsch A). Auf Desktop ist das Video absolut+zentriert im Trapez -
     mobil kollabiert das Trapez (keine --tz-height-Bezugshoehe) und das
     absolute Video haengt hoehenlos. Loesung: das Trapez selbst bekommt
     aspect-ratio 16:9 (volle Breite -> definierte Hoehe), das Video wird
     von absolut auf normalen Fluss zurueckgesetzt und fuellt es per
     object-fit:contain (ganzes Logo, kein Crop). Der weisse bg (aus der
     Basisregel) fuellt eventuelle Letterbox-Raender. Der scale(1.35)-Zoom
     der allgemeinen .trapez--video video-Regel oben wird hier
     zurueckgesetzt - beim Logo soll NICHTS weggezoomt werden. */
  .trapez--logo-loop {
    aspect-ratio: 16 / 9;
  }

  .trapez--logo-loop video {
    position: static;
    top: auto;
    left: auto;
    transform: none;
    width: 100%;
    height: 100%;
    aspect-ratio: 16 / 9;
    object-fit: contain;
  }

  .trapez__content {
    padding: var(--space-l) var(--space-m);
  }

  /* Handwerk-Fliesstext mobil auf Normalgroesse: die Desktop-Sonderregel
     (14/1440 statt 16/1440, line-height 1.45 statt 1.55) war NUR eine
     Kaschierung fuer das enge Shape [06] auf Desktop (siehe Kommentar bei
     .handwerk-content). Mobil ist der Block vollbreit, keine Platznot -
     also gleiche Schriftgroesse wie alle anderen Sektionen, sonst faellt
     dieser Text sichtbar kleiner aus (Kunden-Feedback). */
  .handwerk-content {
    font-size: clamp(16px, calc(16 / 1440 * 100vw), 24px);
    line-height: 1.55;
    max-width: none;
  }

  /* Elefanten-Text: Desktop positioniert ihn absolut rechts neben dem
     Bild (left:46%, width:28% - siehe .elefanten-text oben). Mobil ist
     das Bild-Trapez ohnehin vollbreit gestapelt, der Text wird zu einem
     normalen Block im Fluss. */
  .elefanten-text {
    position: static;
    left: auto;
    top: auto;
    width: 100%;
    padding: var(--space-l) var(--space-m);
  }

  /* Hero: Logo + Subline verlassen die absolute %-Positionierung,
     bilden gemeinsam ein durchgehendes Honey-Band (Ersatz für die
     ausgeblendeten Honey-/Lime-Trapeze). Das Band geht VOLLE Breite -
     der honey-bg sitzt am vollbreiten Wrap, nicht am begrenzten Logo,
     sonst schien links/rechts der Lavender-Body durch (fruehere
     "helles Rosa neben dem Logo"-Meldung). Die Groessenbegrenzung sitzt
     jetzt am Logo-SVG selbst (.hero-logo unten), nicht am Band. */
  .hero-logo-wrap,
  .hero-subline {
    position: static;
    left: auto;
    top: auto;
    width: 100%;
    background-color: var(--honey);
  }

  .hero-logo-wrap {
    /* KEIN max-width/margin:auto mehr hier - das Band ist vollbreit.
       padding zentriert das begrenzte Logo optisch. */
    padding: var(--space-l) var(--space-m) var(--space-s);
    text-align: center;
  }

  /* Logo-Groesse skaliert mit dem Kontext: auf Mobile kompakt (max
     420px), auf Tablet groesser (Kundenwunsch) - sonst wirkt ein
     420px-Logo auf einer bis zu 1024px breiten honey-Flaeche verloren.
     Als vw mit clamp: waechst stufenlos mit, statt an einem harten
     Breakpoint zu springen. inline-block + margin:auto zentriert das
     begrenzte SVG im vollbreiten Band. */
  .hero-logo-wrap .hero-logo {
    display: inline-block;
    width: 100%;
    max-width: clamp(320px, 55vw, 640px);
    margin: 0 auto;
  }

  .hero-subline {
    text-align: center;
    padding: 0 var(--space-m) var(--space-l);
  }

  /* HINWEIS: Die Waende-Karussell-Regeln stehen NICHT hier, sondern in
     einem eigenen @media (max-width: 1279px) weiter unten. Grund: der
     Perspektiv-Warp des Grids ist ein reines Desktop-Feature und braucht
     echte Desktop-Breite - auf Tablet-Landscape (iPad Pro 11" = 1194px,
     iPad Air = 1180px, iPad 12.9" = 1366px liegt sogar drueber) kollabiert
     das gewarpte Grid. Alle Tablets bis 1279px bekommen deshalb das
     Swipe-Karussell, der Warp laeuft erst ab 1280px (echtes Desktop). */

  .lightbox__close {
    top: var(--space-s);
    right: var(--space-s);
  }
}

/* ============================================================
   Waende-Grid: eigener, HOEHERER Breakpoint (≤ 1279px)
   Der Perspektiv-Warp (rotateY) braucht echte Desktop-Breite. Auf allen
   Tablet-Kontexten - auch Landscape (1180-1194px) - wird stattdessen das
   horizontale Swipe-Karussell gezeigt. Nur >= 1280px sieht den Warp.
   Alle anderen Sektionen schalten weiterhin bei 1024px (Block oben) -
   deren gestapeltes Layout funktioniert auch auf breiten Tablets.
   ============================================================ */
@media (max-width: 1279px) {

  .waende-grid {
    position: static;
    top: auto;
    right: auto;
    width: 100%;
    height: auto;
    display: flex;
    grid-template-columns: unset;
    /* Desktop-Rotation abschalten – sonst wuerde die perspektivische
       Verzerrung auch im mobilen Horizontal-Scroll mitlaufen. */
    transform: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* scroll-padding-inline synchron mit dem eigenen padding halten -
       sonst snapped der Browser exakt auf den Content-Rand OHNE das
       visuelle Padding zu beruecksichtigen, Kachel 1 kann dann leicht
       unter das Padding rutschen. */
    scroll-padding-inline: var(--space-m);
    gap: var(--space-s);
    padding: var(--space-m);
    -webkit-overflow-scrolling: touch;
    /* Scrollbar nur optisch ausgeblendet, Scroll-Funktion (Touch-Swipe,
       Trackpad, Tastatur) bleibt vollstaendig erhalten. */
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  .waende-grid::-webkit-scrollbar {
    display: none;
  }

  .waende-grid.reveal-armed,
  .waende-grid.reveal-armed.is-revealed {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .waende-grid .werk-buehne {
    /* 90% (Mica-Runde 2026-08-31): Video-Thumbnails deutlich groesser.
       Kunde nimmt bewusst in Kauf, dass die naechste Kachel nur noch als
       schmaler Anschnitt (~10%) sichtbar ist. Historie: 70% -> 60%
       (mehr Peek) -> 90% (grosse Thumbnails, wenig Peek). ROLLBACK-Werte:
       60% (viel Peek) bzw. 70% (Ausgangswert). */
    flex: 0 0 90%;
    scroll-snap-align: start;
  }

  /* Leere Slots (noch kein Video hinterlegt = lila indigo-Flaeche) im
     Karussell ausblenden (Kundenwunsch Mica 2026-07-22): mobil lief als
     zweite Kachel ein leerer lila Kasten mit - sah aus wie ein Fehler.
     Nur die befuellten Slots bleiben im Swipe. Die Kachel-Anzahl reduziert
     sich dadurch mobil; das ist gewollt.

     NUR mobil (dieser 1279er-Karussell-Block): auf Desktop bleiben die
     leeren Slots als indigo-Fuellung im 3x3-Raster erhalten (Kundenwunsch,
     dort sind sie Teil der Komposition). ROLLBACK: diese Regel loeschen. */
  .waende-grid .waende-slot--leer {
    display: none;
  }

  /* KOLLAPS-FIX (2026-07-20): Die Desktop-Regel ".waende-grid .klapp-media
     { height:100% }" gilt UNCONDITIONAL (steht ausserhalb jedes Media-
     Query) und greift damit auch hier im Karussell. Auf Desktop bekommt
     .klapp-media seine Hoehe von der 1fr-Grid-Zeile (definit) - height:100%
     ist dort korrekt. Im Karussell hat die .werk-buehne aber KEINE definite
     Hoehe (flex-item ohne gesetzte Hoehe, Grid ist jetzt flex mit
     height:auto) -> height:100% loest gegen "auto" auf = 0 -> Kachel
     kollabiert, das ganze Grid verschwindet (genau der iPad-Bug: zwischen
     Waende-Text und Elefanten klafft nichts). Zuruecksetzen auf height:auto
     laesst die aspect-ratio:16/9 (ebenfalls aus der Basisregel) wieder
     greifen -> Kachel bekommt Hoehe aus ihrer Breite. */
  .waende-grid .klapp-media {
    height: auto;
  }

  /* HINWEIS (2026-07-21 Cleanup): Die frueheren carousel-armed-Regeln
     (.werk-buehne, Fade+Slide-In pro Kachel) wurden hier entfernt - siehe
     Sammel-Hinweis dazu in waende-slots-new.css und im reveal.js-Header.
     Modul + Attribut + neutralisierte CSS-Bloecke sind komplett raus. */

  /* Swipe-Hinweis: pulsierender Pfeil rechts, zeigt an dass horizontal
     gewischt werden kann. Verschwindet nach der ersten Scroll-Interaktion
     (reveal.js). pointer-events:none, damit er Taps auf die Kachel
     darunter/dahinter nicht blockiert. */
  .waende-swipe-hint {
    display: flex;
    position: absolute;
    top: 50%;
    right: var(--space-s);
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: rgba(78, 53, 128, 0.85);
    align-items: center;
    justify-content: center;
    /* pointer-events:auto (nicht none): der Pfeil ist jetzt klickbar
       (swipt eine Kachel weiter, siehe reveal.js Modul 5). cursor:pointer
       signalisiert das. z-index haelt ihn ueber den Kacheln. */
    pointer-events: auto;
    cursor: pointer;
    z-index: 2;
    animation: waende-swipe-hint-pulse 1.6s ease-in-out infinite;
    transition: opacity 0.4s var(--ease-default);
  }

  .waende-swipe-hint::after {
    content: "";
    width: 10px;
    height: 10px;
    border-top: 2px solid var(--honey);
    border-right: 2px solid var(--honey);
    transform: rotate(45deg) translateX(-2px);
  }

  .waende-swipe-hint.is-dismissed {
    opacity: 0;
  }

  @keyframes waende-swipe-hint-pulse {
    0%, 100% { transform: translateY(-50%) translateX(0); }
    50%      { transform: translateY(-50%) translateX(6px); }
  }

  @media (prefers-reduced-motion: reduce) {
    .waende-swipe-hint {
      animation: none;
    }
  }
}
