/* ============================================================
   THEME — System-CSS (brand-agnostisch)
   ============================================================
   Reset, Anker-System, Baseline-Mechanismus, Layout-Helfer,
   Master-Layout-Regeln und Debug-Hilfslinien.

   Markenspezifische Werte (Farben, Schrift-Familien, Skala,
   Spacing, Quote-Hang) liegen in brands/<brand>/tokens.css.
   Schrift-Dateien (@font-face) in brands/<brand>/fonts.css.
   Beide werden vom Player vor dieser Datei in den Head gehaengt.
   ============================================================ */

/* ---------- System-Tokens ---------- */

:root {
  /* Footer- und Header-Hoehe = slide-pad oben + 1rem Zeile + slide-pad unten.
     Bei slide-pad 1.5rem also 4rem. Die Content-Grenzen folgen automatisch.
     Marken ueberschreiben die Hoehen pro Folie inline (--footer-height /
     --header-height), die Werte hier sind die globalen Defaults. */
  --footer-height: calc(var(--slide-pad-y) * 2 + 1rem);
  --header-height: calc(var(--slide-pad-y) * 2 + 1rem);

  /* Polster und innerer Abstand der Chrome-Balken. Erbfolge wie bei den
     Farb-Rollen: die Marke setzt optional den Rohwert (--bar-pad-x/-y,
     --bar-gap), das System bildet ihn hier ab, und die Verbraucher lesen NUR
     die Abbildung. Ohne Marken-Wert erbt das Polster vom Folienrand und der
     Abstand vom Steg. Damit sind die Balken vom Rand unabhaengig, ohne dass
     eine Marke etwas setzen muss. */
  --chrome-pad-x: var(--bar-pad-x, var(--slide-pad-x));
  --chrome-pad-y: var(--bar-pad-y, var(--slide-pad-y));
  --chrome-gap:   var(--bar-gap,   var(--gutter-x));

  /* Baseline-Korrektur fuer vertikal zentrierten Text:
     verschiebt den Block so weit nach oben, dass der Mittelpunkt
     zwischen erster und letzter Grundlinie auf 50vh liegt.
     Konstante (unabhaengig von Zeilenzahl und Zeilenhoehe),
     bezogen auf die Schriftgroesse. Wird beim Laden aus den
     Font-Metriken gemessen (= (Ascent - Descent) / 2). Der Wert
     hier ist nur der Fallback, bis die Messung greift. */
  --baseline-shift: 0.36em;
  /* Manuelle Feinjustierung, wird zur Messung addiert. */
  --baseline-fudge: 0em;
}

/* ---------- Farb-Rollen ---------- */
/* Die Theme-Klasse waehlt pro Rolle den aktiven Wert (gilt auf Slide und Chrome).
   Die Marke definiert die Rohwerte je Rolle ENTWEDER als Ein-Token --<rolle>
   (eine Farbe fuer beide Themes) ODER als Paar --<rolle>-on-dark/-light
   (differenziert); das Paar gewinnt vor dem Ein-Token. Bewusst
   Erbfolge statt Pflicht-Vollausbau: PFLICHT sind nur bg-black/bg-white,
   das headline-Paar und color1. Jede andere Rolle hat eine deklarierte
   MUTTER und erbt deren Wert, solange die Marke sie nicht setzt (var()-
   Fallback-Kette auf Marken-Werte, wie bei den Linien-Typen; kein Wert ist
   hartkodiert): subhead/body/emphasis/active/quote <- headline,
   inactive/footnote/footer <- body, footnote-bg <- Hintergrund, toc-hover <- active.
   line und link bleiben Umgebungs-Erben (currentColor bzw. Textfarbe). */
.theme-dark {
  --c-headline: var(--headline-on-dark, var(--headline));
  --c-subhead:  var(--subhead-on-dark, var(--subhead, var(--headline-on-dark, var(--headline))));
  --c-body:     var(--body-on-dark, var(--body, var(--headline-on-dark, var(--headline))));
  --c-emphasis: var(--emphasis-on-dark, var(--emphasis, var(--headline-on-dark, var(--headline))));
  --c-quote:    var(--quote-on-dark, var(--quote, var(--headline-on-dark, var(--headline))));
  --c-active:   var(--active-on-dark, var(--active, var(--headline-on-dark, var(--headline))));
  --c-inactive: var(--inactive-on-dark, var(--inactive, var(--body-on-dark, var(--body, var(--headline-on-dark, var(--headline))))));
  --c-footer:   var(--footer-on-dark, var(--footer, var(--body-on-dark, var(--body, var(--headline-on-dark, var(--headline))))));
  /* Optional, mit Fallback: nicht gesetzt -> --c-line bleibt ungueltig und
     die Linien fallen ueber var(--c-line, currentColor) auf die Textfarbe. */
  --c-line:     var(--line-on-dark, var(--line));
  --c-footnote:    var(--footnote-on-dark, var(--footnote, var(--body-on-dark, var(--body, var(--headline-on-dark, var(--headline))))));
  --c-footnote-bg: var(--footnote-bg-on-dark, var(--footnote-bg, var(--bg-black)));
  /* Optional, ohne Fallback: nicht gesetzt -> Link erbt die Textfarbe. */
  --c-link:        var(--link-on-dark, var(--link));
  --c-toc-hover:   var(--toc-hover-on-dark, var(--toc-hover, var(--active-on-dark, var(--active, var(--headline-on-dark, var(--headline))))));
}
.theme-light {
  --c-headline: var(--headline-on-light, var(--headline));
  --c-subhead:  var(--subhead-on-light, var(--subhead, var(--headline-on-light, var(--headline))));
  --c-body:     var(--body-on-light, var(--body, var(--headline-on-light, var(--headline))));
  --c-emphasis: var(--emphasis-on-light, var(--emphasis, var(--headline-on-light, var(--headline))));
  --c-quote:    var(--quote-on-light, var(--quote, var(--headline-on-light, var(--headline))));
  --c-active:   var(--active-on-light, var(--active, var(--headline-on-light, var(--headline))));
  --c-inactive: var(--inactive-on-light, var(--inactive, var(--body-on-light, var(--body, var(--headline-on-light, var(--headline))))));
  --c-footer:   var(--footer-on-light, var(--footer, var(--body-on-light, var(--body, var(--headline-on-light, var(--headline))))));
  --c-line:     var(--line-on-light, var(--line));
  --c-footnote:    var(--footnote-on-light, var(--footnote, var(--body-on-light, var(--body, var(--headline-on-light, var(--headline))))));
  --c-footnote-bg: var(--footnote-bg-on-light, var(--footnote-bg, var(--bg-white)));
  --c-link:        var(--link-on-light, var(--link));
  --c-toc-hover:   var(--toc-hover-on-light, var(--toc-hover, var(--active-on-light, var(--active, var(--headline-on-light, var(--headline))))));
}

/* Headline-Defaults ueber data-headline (alle Master, inkl. quote-text-Farbe).
   Typo aus den Marken-Tokens --headline-*. Diese Regel ist der niedrigste
   Default: YAML-weight, Block-Token und Span-Modifier setzen Inline-Styles und
   stechen sie. quote-text traegt eigene --quote-text-*-Typo (spaeter in der
   Datei, gleiche Spezifitaet) und gewinnt fuer Schrift, Gewicht und Stil. */
[data-headline] {
  color: var(--c-headline);
  font-family: var(--headline-family);
  font-weight: var(--headline-weight);
  font-style: var(--headline-style);
  text-transform: var(--headline-transform);
  font-variant-caps: var(--headline-caps);
}

/* Emphasis: themebare Farbe plus optionale markeneigene Formatierung. Ohne
   Fallback: nicht gesetzt -> erbt vom umgebenden Text (kein Wechsel). */
.emphasis {
  color: var(--c-emphasis);
  font-family: var(--emphasis-family);
  font-weight: var(--emphasis-weight);
  font-style: var(--emphasis-style);
  font-variant-caps: var(--emphasis-smallcaps);
  text-transform: var(--emphasis-transform);
}

/* Inline-Link (//Text//{link:URL}). Optische Rolle wie die Content-Linie:
   ohne Fallback. Farbe nicht gesetzt -> erbt die Textfarbe; Unterstreichung
   nicht gesetzt -> keine. Jede Marke setzt --link-decoration (und optional
   --link-on-dark/-light) in ihrer tokens.css. Reichere Effekte (Hover,
   animierte Unterstreichung) leben spaeter frei in der Marke. */
.link {
  color: var(--c-link);
  text-decoration-line: var(--link-decoration);
}

/* Byline / Autorenzeile (Name + Rolle): gemeinsame, brand-gesteuerte
   Typografie fuer quote-Autor und cover-letter-Absender. Familie und Gewicht
   als optionale Hooks ohne Fallback: nicht gesetzt erbt vom umgebenden Text
   (praktisch --font-main im Umgebungsgewicht). */
.byline-name { font-family: var(--byline-name-family); font-weight: var(--byline-name-weight); }
.byline-role { font-family: var(--byline-role-family); font-weight: var(--byline-role-weight); }

/* Ohne Footer/Header faellt die jeweilige Content-Grenze auf das Slide-Padding. */
.slide.no-footer {
  --chrome-bottom: var(--slide-pad-y);
}
.slide.no-header {
  --content-top: var(--slide-pad-y);
}

/* ---------- Typo-Utilities (fs + lh + ls in einer Klasse) ---------- */

/* ---------- Akzent-Schrift ueber //Text// ---------- */
.accent {
  font-family: var(--font-accent);
  font-size: var(--accent-size); /* optischer Ausgleich, nur fuer den Akzent */
}
/* Alternate-Schrift (//Text//{alternateN}): font-family kommt inline aus dem
   Slot, die Groesse bleibt die Textgroesse. --accent-size beruehrt sie nicht. */

/* line-height:0 haelt Akzent und Alternate aus der Zeilenhoehe heraus:
   groessere Glyphen ragen optisch ueber die Zeile, ohne den Zeilenabstand oder
   die vertikale Zentrierung (z.B. in big-type) zu veraendern. */
.accent,
.accent-alt {
  line-height: 0;
}
/* Optionale Farbe ueber {colorX}, gleiche Quelle wie die Marker, fuer beide. */
.accent[data-color="color1"], .accent-alt[data-color="color1"] { color: var(--color1); }
.accent[data-color="color2"], .accent-alt[data-color="color2"] { color: var(--color2); }
.accent[data-color="color3"], .accent-alt[data-color="color3"] { color: var(--color3); }

/* ---------- Title-Untertitel (Fliesstext) ----------
   Groesse fest auf der 1x-Stufe (Pflicht-Basis jeder Marke; nacktes Erben
   wuerde die Headline-Groesse des .title-block erwischen). Abweichung ist
   eine Deck-Entscheidung per Block-Token ({fontsizeN|accent|alternateN|
   colorN}): das innere Element gewinnt in der Kaskade. Typografie als
   optionale, vererbende Rollen-Hooks wie .emphasis: nicht gesetzt ->
   erbt vom umgebenden Text. Farbe aus der Rolle --c-subhead. */
.title-sub {
  font-family: var(--title-sub-family);
  font-weight: var(--title-sub-weight);
  font-style: var(--title-sub-style);
  font-variant-caps: var(--title-sub-smallcaps);
  text-transform: var(--title-sub-transform);
  font-size: var(--fs-1);
  line-height: var(--lh-1);
  letter-spacing: calc(var(--ls-1) * 1ch);
  color: var(--c-subhead);
  white-space: pre-line;
}

/* ---------- Vertikale Baseline-Zentrierung ---------- */
/* Auf das zentrierte Text-Element setzen. Hebt den Block um
   --baseline-shift an (em bezogen auf die Schriftgroesse des
   Elements), damit die Grundlinien-Mitte auf 50vh sitzt. */
.v-center-baseline {
  position: relative;
  top: calc(-1 * (var(--baseline-shift) + var(--baseline-fudge)));
}

/* ---------- Fussnotenzone (am unteren Rand des Bereichs) ---------- */
/* Sitzt an der unteren Buehnengrenze (--chrome-bottom = Footer-Oberkante bzw.
   slide-pad ohne Footer). Ihre gemessene Hoehe steht als --footnote-height auf
   dem Bereich und hebt --content-bottom an. Fussnoten stapeln, links buendig. */
.footnote-zone {
  /* Nur Struktur: Verankerung am unteren Bereichsrand. Der slide-pad oben steckt
     in der gemessenen Zonenhoehe und fliesst so in --content-bottom; unten sitzt
     die Zone buendig an --chrome-bottom. Ausrichtung erbt das Plaettchen ueber
     text-align (Markenwert), nichts erzwungen. */
  position: absolute;
  left: var(--slide-pad-x);
  right: var(--slide-pad-x);
  bottom: var(--chrome-bottom);
  padding-top: var(--slide-pad-y);
  z-index: 1;
}

/* ---------- Fussnote (Block-Token {footnote}) ---------- */
/* Kleiner Block mit eigener Farbe und halbdeckendem Hintergrund in der
   Theme-Farbe: ohne Hintergrundbild unsichtbar, auf einem Bild ein Plaettchen.
   Farbe/Hintergrund/Transparenz/Groesse kommen aus der Marke (ohne Fallback).
   Die Platzierung am Folienfuss uebernimmt der jeweilige Master. */
.footnote {
  /* Plaettchen umschliesst den Text. Groesse, Farbe, Hintergrund, Transparenz
     und Padding aus Marken-Tokens. Die Schrift-Eigenschaften sind optionale
     Hooks (var ohne Fallback): setzt die Marke ein --footnote-*-Token, greift
     es, sonst erbt die Eigenschaft vom umgebenden Text (body). */
  display: inline-block;
  font-family: var(--footnote-family);
  font-weight: var(--footnote-weight);
  font-style: var(--footnote-style);
  text-transform: var(--footnote-transform);
  font-variant-caps: var(--footnote-caps);
  font-size: var(--footnote-size);
  color: var(--c-footnote);
  background: color-mix(in srgb, var(--c-footnote-bg) calc(var(--footnote-bg-alpha) * 100%), transparent);
  padding: var(--footnote-pad);
  white-space: pre-line;
}

/* ---------- Debug-Hilfslinien (per guide: true oder Taste G) ---------- */
.debug-guides {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 11;
}
.debug-guides .dg-h {        /* horizontale Mittellinie (50vh) */
  position: absolute; left: 0; right: 0; top: 50vh;
  border-top: 1px dashed #00e5ff; transform: translateY(-0.5px);
}
.debug-guides .dg-v {        /* vertikale Mittellinie (50vw) */
  position: absolute; top: 0; bottom: 0; left: 50vw;
  border-left: 1px dashed #00e5ff; transform: translateX(-0.5px);
}
.dg-box {      /* Content-Box: oben/unten an den Content-Grenzen, links/rechts im slide-pad.
                  Folienweit (in .debug-guides) ODER pro Bereich (in einem
                  [data-content-region]-Element, z.B. split-Seite, zoom-Stopp),
                  damit die Box die --content-bottom IHRES Bereichs liest. */
  position: absolute;
  top: var(--content-top); left: var(--slide-pad-x); right: var(--slide-pad-x);
  bottom: var(--content-bottom);
  border: 1px dashed #ff2d9b;
  z-index: 11;
  pointer-events: none;
}
.debug-guides .dg-footer {   /* Oberkante des Footers */
  position: absolute; left: 0; right: 0; bottom: var(--footer-height);
  border-top: 1px dashed #ffd400; transform: translateY(-0.5px);
}
.debug-guides .dg-header {   /* Unterkante des Headers */
  position: absolute; left: 0; right: 0; top: var(--header-height);
  border-top: 1px dashed #ffd400; transform: translateY(-0.5px);
}

/* DEBUG (temporaer): gruene Umrandung der echten Text-Boxen, um Box-Kante vs.
   Safety-Area vs. sichtbaren Text zu pruefen. Outline -> kein Layout-Einfluss. */
.guides-on .ht-half,
.guides-on .ht-stack,
.guides-on .ht-body,
.guides-on .ht-headline,
.guides-on .cols-col,
.guides-on .cols-text,
.guides-on .tbl-cell { outline: 1px solid #00ff00; }

/* ---------- Reset / Basis ---------- */

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

/* Die Liquid-Basisgroesse (html { font-size }) setzt der Brand in
   tokens.css. So kann jeder Brand seine eigene Zielgroesse waehlen. */

body {
  font-family: var(--font-main);
  /* Gewicht des Fliesstexts als optionaler, vererbender Hook wie bei den
     uebrigen Rollen (headline, emphasis, quote, list, footnote, title-sub):
     nicht gesetzt heisst normal, wie bisher. Marken, deren Lesegewicht nicht
     die 400 der Familie ist, setzen ihn. */
  font-weight: var(--body-weight);
  font-size: var(--fs-1);
  line-height: var(--lh-1);
  letter-spacing: calc(var(--ls-1) * 1ch);
  color: var(--body-on-dark, var(--body, var(--headline-on-dark, var(--headline))));
  background: var(--bg-black);
  overflow: hidden;
}

/* ---------- Stage ---------- */

#stage {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

/* ---------- Aspect-Lock (Letterbox-Huelle) ---------- */
/* Nur der aeussere Standalone-Player bei gesetztem `aspect` (player.js). #stage
   wird zur Letterbox: Marken-Hintergrund ringsum (--letterbox-bg), zentriert die
   Box im festen Verhaeltnis (Groesse setzt der Player inline: aspect-ratio +
   width min()). Der innere iframe ist ein eigener Viewport, das Liquid-Layout
   fuellt ihn unveraendert. Ohne Sperre existiert nichts davon. */
#stage.is-locked {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--letterbox-bg, var(--bg-black));
}
.letterbox-box { display: block; overflow: hidden; }
.letterbox-frame { width: 100%; height: 100%; border: 0; display: block; background: transparent; }

.slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: var(--slide-pad-y) var(--slide-pad-x);
  /* Eigener Stacking-Context: die Slide-internen z-index (inkl. Slam z-index 8)
     bleiben damit unter dem stage-weiten Fader (z-index 2). */
  z-index: 1;
  /* Content-Grenzen aus den (pro Folie inline gesetzten) Balken-Hoehen.
     Hier auf .slide deklariert, nicht auf :root, damit var() die
     tatsaechliche --footer-height / --header-height dieser Folie nimmt. */
  --footnote-height: 0px;
  --chrome-bottom: var(--footer-height);
  --content-bottom: calc(var(--chrome-bottom) + var(--footnote-height));
  --content-top: var(--header-height);
}

/* Navigationshinweis (core/nav-hint.js): dezenter Hinweis auf der ersten Folie,
   wenn keine Navigation erfolgt. Unten zentriert ueber der Footer-Safety-Area
   (--footer-height sitzt auf #stage). Markenschrift und Textfarbe der Rolle; die
   Theme-Klasse am Element liefert --c-body. bodyIn animiert opacity/transform,
   die horizontale Zentrierung laeuft ueber left/right + text-align (kein
   transform-Konflikt). pointer-events:none haelt Maus und Links frei. */
.nav-hint {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(var(--footer-height) + var(--slide-pad-y));
  z-index: 4;
  text-align: center;
  font-family: var(--font-main);
  font-size: var(--fs-1);
  color: var(--c-body);
  pointer-events: none;
}

/* Generisches Hintergrundbild (YAML bg/bgh/bganchor/bgx/bgy/bgalpha). Echtes
   <img> als unterste Schicht, ueber der Theme-Hintergrundfarbe, hinter Inhalt
   und Chrome. Anker-Modell: height (bgh% der Folie), width auto (natives
   Seitenverhaeltnis), left/top (bgx/bgy in %) und transform (Anker-Versatz)
   setzt der Player inline. Ueberstand clippt #stage (overflow: hidden). */
.slide-bg {
  position: absolute;
  z-index: 0;
}

/* Generisches Bild (YAML img/...): zweite Bildebene, ein echtes <img> direkt
   ueber dem Hintergrund (.slide-bg) und unter dem Master-Inhalt (DOM-Reihenfolge
   bg < img < Inhalt). Position/Groesse/Transform setzt der Player inline (Anker-
   Modell wie .slide-bg). Verdeckt keinen Text. Ueberstand clippt #stage. */
.slide-img {
  position: absolute;
  z-index: 0;
  width: auto;
}
/* Inneres Bild fuellt den Wrapper; nur dieses Element wird animiert (Eintritt). */
.slide-img > img {
  display: block;
  height: 100%;
  width: auto;
}

/* Theme-Varianten (vom Master gesetzt) */
.slide.theme-dark { background: var(--bg-black); }
.slide.theme-light { background: var(--bg-white); }
.slide { color: var(--c-body); }

/* ---------- Standard-Uebergang: Fader-Deckflaeche ---------- */
/* Liegt ueber dem Folieninhalt und dem Slam (Slide ist z-index 1), aber unter
   der Chrome-Schicht (z-index 3). Farbe (Zielfolien-Hintergrund), Opacity und
   display steuert transition.js inline. */
.fader {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
}

/* ---------- Persistente Chrome-Schicht (Header + Footer) ---------- */
/* Ueber dem Fader, damit Header/Footer beim Uebergang sichtbar bleiben und
   unabhaengig ein-/ausfahren. Die Schicht selbst faengt keine Klicks (damit
   der Stage-Klick zum Weiterblaettern durchkommt); nur die Balken sind
   interaktiv (z.B. Breadcrumb-Krumen). Theme-Klasse liefert die Erbfarbe der
   Balken (vormals vom Slide). */
.chrome-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}
.chrome-layer .header,
.chrome-layer .footer {
  pointer-events: auto;
}
.chrome-layer { color: var(--c-footer); }

/* ---------- Anchor-System ---------- */
/* Elemente werden absolut positioniert. Anchor-Klasse legt Eckpunkt fest. */

.anchor {
  position: absolute;
}

/* Top-Reihe: sitzt unterhalb des Headers (Content-Grenze oben) */
.anchor-top-left      { top: var(--content-top);   left: var(--slide-pad-x);   text-align: left;   }
.anchor-top-center    { top: var(--content-top);   left: 50%; transform: translateX(-50%); text-align: center; }
.anchor-top-right     { top: var(--content-top);   right: var(--slide-pad-x);  text-align: right;  }

/* Mittel-Reihe: vertikales Zentrum immer 50vh (unabhaengig vom Footer) */
.anchor-mid-left      { top: 50%; left: var(--slide-pad-x);  transform: translateY(-50%); text-align: left;   }
.anchor-center        { top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; }
.anchor-mid-right     { top: 50%; right: var(--slide-pad-x); transform: translateY(-50%); text-align: right;  }

/* Bottom-Reihe: sitzt oberhalb des Footers */
.anchor-bottom-left   { bottom: var(--content-bottom); left: var(--slide-pad-x);  text-align: left;   }
.anchor-bottom-center { bottom: var(--content-bottom); left: 50%; transform: translateX(-50%); text-align: center; }
.anchor-bottom-right  { bottom: var(--content-bottom); right: var(--slide-pad-x); text-align: right;  }

/* ---------- Cover-Master ---------- */

.cover-row {
  display: inline-flex;
  /* baseline: die Slot-Grundlinie (Hoehe 0) liegt auf der Textgrundlinie des
     Namens; das Logo ist damit exakt wie inline verankert. Der Slot bläht die
     Zeilenbox nicht auf, deshalb bleibt v-center-baseline gueltig. */
  align-items: baseline;
  gap: 0.35em;
  white-space: nowrap;
}

.cover-logo {
  /* Inline-Platzhalter wie {logo}: Hoehe 0 an der Grundlinie, reserviert nur
     die Breite; das Bild sitzt absolut darin. So bleibt die Namenszeile eine
     reine Textzeile (v-center-baseline unberuehrt).
     --cover-dx (rem, vom Master gemessen) zentriert das Logo optisch, --reveal
     (0..1, GSAP) blendet den Versatz beim Reveal aus. */
  position: relative;
  display: inline-block;
  vertical-align: baseline;
  height: 0;
  transform: translateX(calc(var(--cover-dx, 0rem) * (1 - var(--reveal, 0))));
}
.cover-logo > img {
  position: absolute;
  width: auto;
}

/* ---------- Quote-Master ---------- */

/* Spalte: vom Slide-Padding der Aussenkante bis zur horizontalen Mitte (50vw). */
.quote-col {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  padding-top: var(--slide-pad-y);
  padding-bottom: var(--slide-pad-y);
  display: flex;
  flex-direction: column;
  justify-content: center; /* ohne Textblock: Zitat auf 50vh */
  text-align: left;
}
.quote-col.quote-left  { left: 0;    right: 50%; padding-left:  var(--slide-pad-x); padding-right: calc(var(--gutter-x) / 2); }
.quote-col.quote-right { left: 50%;  right: 0;   padding-right: var(--slide-pad-x); padding-left: calc(var(--gutter-x) / 2); }

/* Mit Textblock: oben slide-pad, unten Content-Grenze, Textblock unten,
   Zitat im Freiraum darueber zentriert. */
.quote-col.has-text {
  top: var(--content-top);
  bottom: var(--content-bottom);
  padding-top: 0;
  padding-bottom: 0;
  justify-content: flex-start;
}
.quote-region {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.quote-textblock { flex: 0 0 auto; }

/* Zitat-Block: Autor/Position haengen absolut darunter (wie Subheadline) */
.quote-block { position: relative; }

.quote-text {
  /* Eigene Farb-Rolle (Erbfolge: Mutter headline); gewinnt wie die Typo-
     Zeilen darunter ueber den data-headline-Default (gleiche Spezifitaet,
     spaeter in der Datei). */
  color: var(--c-quote);
  font-family: var(--quote-text-family);
  font-weight: var(--quote-text-weight);
  font-style: var(--quote-text-style);
  white-space: pre-line;
  /* Haengende Interpunktion nativ (Safari): das „ haengt in das eigene
     linke Padding des Zitats (innerhalb des Elements, daher kein Clipping).
     Der Text rueckt um dieses Padding ein, das „ landet an der Kante. */
  hanging-punctuation: first;
  padding-left: var(--quote-hang);
}

/* Chrome/Firefox kennen hanging-punctuation nicht. Dort das „ ueber einen
   negativen Erstzeilen-Einzug zurueck ins Padding ziehen (gleiches Ergebnis,
   das „ bleibt im Element). In Safari greift dieser Block nicht. */
@supports not (hanging-punctuation: first) {
  .quote-text { text-indent: calc(-1 * var(--quote-advance)); }
}

.quote-author-wrap {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: calc(var(--space-after) * 1lh);
  max-width: 100%;
}
.quote-author {
  font-family: var(--font-main);
  /* Groesse als t-*-Klasse vom Master (Default t-1, ueber Block-Token aenderbar) */
}
.quote-textblock {
  font-family: var(--font-main);
  font-weight: var(--body-weight);
}

/* ---------- Trennlinie (*** im Textblock, via renderBody) ---------- */
/* ---------- Fliesstext-Absaetze (renderBody) ----------
   Bloecke werden an Leerzeilen getrennt und je in ein <p.body-para> verpackt.
   Der Absatzabstand kommt aus margin (skaliert mit der Textgroesse des Absatzes),
   da die trennende Leerzeile beim Parsen wegfaellt. */
.body-para {
  margin: 0;
  white-space: pre-line;
}
.body-para:not(:last-child) {
  margin-bottom: calc(var(--space-after) * 1lh);
}

/* ---------- Leerzeile {linegap} (systemweit, ueber renderInline) ----------
   Leeres Block-Element, an die Fluss-Einheit --space-after gekoppelt:
   Hoehe = --linegap-factor (Default 1) * --space-after * 1lh. Eine Durchschuss-
   zeile entspricht so genau einem Absatzabstand; --linegap-factor skaliert sie
   relativ dazu, ohne die Kopplung aufzugeben. */
.linegap {
  display: block;
  height: calc(var(--linegap-factor, 1) * var(--space-after) * 1lh);
}

.rule {
  border: 0;
  /* color:inherit, damit currentColor die Theme-Schriftfarbe nimmt
     (Browser setzen sonst eine eigene graue Default-Farbe auf <hr>). */
  color: inherit;
  /* Stil ueber optionales --line-style (Fallback solid), Farbe ueber die
     optionale Rolle --c-line (Fallback currentColor = Textfarbe). Breite als
     Marken-Token --line-width (Default-Marke setzt 0.1rem). */
  border-top: var(--line-width) var(--line-style, solid) var(--c-line, currentColor);
  width: 100%;
}
/* Vier Linien-Typen: Abstand davor/danach je Typ, Fallback auf die Basis
   (--line-space-before/-after). Das * 1lh loest gegen die Groessenklasse der
   Linie auf, das Spacing skaliert also mit dem zugehoerigen Block. */
.rule--start { margin: calc(var(--line-start-before, var(--line-space-before)) * 1lh) 0 calc(var(--line-start-after, var(--line-space-after)) * 1lh); }
.rule--end   { margin: calc(var(--line-end-before,   var(--line-space-before)) * 1lh) 0 calc(var(--line-end-after,   var(--line-space-after)) * 1lh); }
.rule--separator { margin: calc(var(--line-separator-before, var(--line-space-before)) * 1lh) 0 calc(var(--line-separator-after, var(--line-space-after)) * 1lh); }
/* Erstes Element seines Containers: kein Abstand davor (Text wie Spalten). */
.rule:first-child { margin-top: 0; }

/* ---------- Listen ({list} + {bulletN}, via renderBody) ----------
   Ein Block mit End-Token {listN} wird zur Liste: jede Zeile ein <li>.
   Die Bullet-Glyphe kommt aus --bullet (vom Block gesetzt, Default
   --bullet1 = markeneigen) und haengt links, umbrechende Zeilen ruecken
   unter den Text ein (padding-left = --bullet-gap, Bullet absolut bei 0).
   Listen-Typografie ueber die optionalen --list-*-Rollen: nicht gesetzt
   erbt sie vom umgebenden Text (kein Fallback, wie bei toc). */
.body-list {
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--list-family);
  font-weight: var(--list-weight);
  font-style: var(--list-style);
  text-transform: var(--list-transform);
  font-variant-caps: var(--list-caps);
}
/* Nach-Abstand zum naechsten Block wie bei .body-para: jede Liste traegt
   eine Fluss-Luecke, ausser sie ist letztes Kind (Blockende bzw. einzige
   in einer Tabellenzelle). Wert aus --space-after der Stufe, * 1lh. */
.body-list:not(:last-child) { margin-bottom: calc(var(--space-after) * 1lh); }
.body-list > li {
  position: relative;
  white-space: pre-line;
}
/* Haengende Einrueckung nur, wenn ein Marker da ist (Bullet/Nummer). Ohne
   Marker keine Einrueckung der ersten Ebene. */
.body-list.is-marked > li {
  padding-left: var(--bullet-gap);
}
.body-list > li + li {
  /* Eintragsabstand: PFLICHT-Token --list-gap-factor der Marke, als FAKTOR auf
     den Absatzabstand der Stufe (1 = ein Absatzabstand). Die Formel steht hier
     beim Verbraucher, nicht im Token: --space-after gibt es nur auf den
     Skalenklassen, ein calc() im :root-Token waere dort ungueltig. Kein
     Rueckfall, eine Marke ohne den Token rendert sichtbar falsch. */
  margin-top: calc(var(--list-gap-factor) * var(--space-after) * 1lh);
}
/* Listen-Stil-Varianten ({listN}): vollstaendig markenseitig definiert
   (.body-list.list-N in der tokens.css je Marke, ueber --list-gap-factor).
   Das System setzt KEINEN Variantenwert, kein Hartcode. */
/* Marker (opt-in): --marker traegt entweder eine Bullet-Glyphe oder einen
   Nummern-Zaehler-Ausdruck (beides aus der Marke). Nicht gesetzt -> die Regel
   ist ungueltig -> kein Marker. Kein System-Default. */
.body-list > li::before {
  content: var(--marker);
  position: absolute;
  left: 0;
  top: 0;
}
/* Nummerierte Liste ({numberN}): das System liefert nur den Zaehler li
   (Struktur); Stil und Format stehen im Marken-Token --numberN. */
.body-list.is-numbered { counter-reset: li; }
.body-list.is-numbered > li { counter-increment: li; }

/* Listen-Kopfzeile ({listheader}): ein <li> IM Listenfluss und bekommt damit die
   normalen li-Abstaende (li + li). Kein Marker, kein Marker-Einzug, zaehlt nicht
   in der Nummerierung mit. Typografie ueber optionale, vererbende Marken-Hooks
   --listheader-* (ohne Fallback, wie emphasis/--list-*): nicht gesetzt erbt vom Umfeld. */
.list-header {
  font-family: var(--listheader-family);
  font-weight: var(--listheader-weight);
  font-style: var(--listheader-style);
  text-transform: var(--listheader-transform);
  font-variant-caps: var(--listheader-caps);
}
.body-list > li.list-header::before { content: none; }                 /* kein Marker am Header */
.body-list.is-marked > li.list-header { padding-left: 0; }             /* buendig, kein Marker-Einzug */
.body-list.is-numbered > li.list-header { counter-increment: none; }   /* zaehlt nicht in der Nummerierung mit */

/* ---------- Tabelle ({table: true} auf der headline-text-Textseite) ----------
   Reihen stapeln vertikal; jede Reihe ist ein Grid ueber --tbl-units Einheiten
   (aus textwidth, 25/50/75/100 -> 3/6/9/12). Zellen spannen per inline
   grid-column. Ein ***-Block wird zur reihenbreiten Linie (--line-width).
   Ausrichtung je Zelle folgt spaeter ueber ein {textalign:...}-Token. */
.tbl {
  display: flex;
  flex-direction: column;
}
.tbl-row {
  display: grid;
  grid-template-columns: repeat(var(--tbl-units), minmax(0, 1fr));
  column-gap: var(--gutter-x);
  row-gap: 0;
  align-items: start;
}

/* Prozent-Tabelle (tablepercent): 100 Spuren, ein Gap zwischen JEDER Spur
   waere 99x --gutter-x und sprengt den Container. Abstand daher aus; Spacing
   regelt der Autor ueber die Span-Werte (Luecken im 100er-Raster). */
.tbl--percent .tbl-row { column-gap: 0; }
/* Tabelle ist ein strukturelles Raster: Reihen OHNE fuehrende Linie trennt
   --gutter-y. Reihen MIT Linie (.tbl-row--ruled) bekommen den Abstand von der
   Linie selbst, dort greift der Gutter nicht. Kein --space-after in Tabellen. */
.tbl-row:not(:first-child):not(.tbl-row--ruled) { margin-top: var(--gutter-y, var(--gutter-x)); }
.tbl-cell { min-width: 0; }

/* Inline-Spacer fester Breite (rem) ueber {hspace:N}. */
.hspace { display: inline-block; }
/* Linie verhaelt sich wie im Text: Abstand davor und danach (Marken-Faktor * 1lh).
   Die fuehrende Linie einer Reihe besitzt damit den Reihenabstand. */
.tbl-rule {
  grid-column: 1 / -1;
  border-top: var(--line-width) var(--line-style, solid) var(--c-line, currentColor);
  margin: calc(var(--line-table-before, var(--line-space-before)) * 1lh) 0 calc(var(--line-table-after, var(--line-space-after)) * 1lh);
}
/* Erste Reihe: fuehrende Linie ohne Vor-Abstand (sitzt buendig oben). */
.tbl-row:first-child .tbl-rule { margin-top: 0; }

/* ---------- Columns-Master ---------- */

.cols-headline {
  /* bis 75vw begrenzt (von der linken Kante), minus Aussenrand und halbe
     Naht: die 75vw-Kante ist eine Rasterfuge, kein freier Rand. */
  max-width: calc(75vw - var(--slide-pad-x) - var(--gutter-x) / 2);
  font-family: var(--font-main);
}

/* Stack der Spalten-Reihen, unten verankert. */
.cols-stack {
  position: absolute;
  left: var(--slide-pad-x);
  right: var(--slide-pad-x);
  bottom: var(--content-bottom);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-y, var(--gutter-x));
}

/* Eine Reihe: festes 4-Einheiten-Raster, Spalten unten ausgerichtet.
   Breite und Startspalte jeder Spalte setzt der Master per grid-column. */
.cols-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gutter-x);
  /* Reihe ist ueber den Stack unten verankert (Unterkante = Content-Grenze).
     Die Spalten richten sich INNERHALB der Reihe oben aus: kuerzere Bloecke
     haengen oben (Oberkanten und ***-Linien fluchten), nur der hoechste
     Block reicht bis zur unteren Kante. */
  align-items: start;
}

/* Eine Spalte. Breite und Startspalte setzt der Master per grid-column.
   Bei flow setzt der Master column-count auf dem inneren .cols-text,
   damit die ***-Linie darueber die volle Spaltenbreite behaelt. */
.cols-col {
  font-family: var(--font-main);
}

/* Dekorative Linie oben in der Spalte (per *** im Body). Sie spannt die
   volle Spaltenbreite (Element-Breite der Spalte), sitzt oben buendig und
   haelt nur nach unten Abstand zum Text. */
/* Die fuehrende Spaltenlinie (.rule--start) sitzt oben buendig ueber die
   allgemeine .rule:first-child-Regel; keine columns-Sonderregel mehr noetig. */

/* Grosse Zahl ueber der Spalte (numbering: true, nur erste Reihe). Groesse
   ueber die Skalenklasse (t-*), die der Master setzt. */
.cols-number {
  font-family: var(--font-main);
  line-height: 1;
  margin-bottom: calc(var(--space-after) * 1lh / 2);
}

/* ---------- Split-Master (zweiseitig) ---------- */

.split-stage {
  position: absolute;
  top: 0;
  left: 0;
  width: 200vw;
  height: 100%;
  display: flex;
}

.split-page {
  position: relative;
  flex: 0 0 100vw;
  width: 100vw;
  height: 100%;
  z-index: 1; /* Content ueber dem durchgehenden Nahtbild */
}

.split-bg {
  position: absolute;
  left: 50%; /* = Naht (Mitte der 200vw-Buehne) */
  width: auto;
  z-index: 0; /* hinter dem Content, ein durchgehendes Stueck */
  /* top setzt der Master inline (visualy); height + transform (Anker, Offset) per GSAP */
}

/* Content auf die aeussere Haelfte begrenzen, damit er nicht auf dem
   Nahtbild liegt. */
/* Beide Content-Boxen haben eine feste Breite (Default = halbe Flaeche,
   50vw - 1.5 slide-pad). Ohne feste Breite schrumpfte eine Box auf ihren Inhalt
   und text-align haette keinen Spielraum. Die YAML-Option contentwidth
   ueberschreibt die Breite pro Folie inline. */
.split-headline,
.split-text {
  width: calc(50vw - var(--slide-pad-x) - var(--gutter-x) / 2);
}
.split-text { font-family: var(--font-main); }

/* ---------- Slam-Objekt ---------- */

.slam-obj {
  position: absolute;
  top: 50%;
  left: 50%;
  width: auto;
  z-index: 8; /* ueber Inhalt und Footer */
  pointer-events: none;
  transform-origin: center center;
  /* height inline, Zentrierung + Skalierung per GSAP */
}

/* ---------- Zoom-Master ---------- */

.zoom-bg {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  transform-origin: center center;
  z-index: 0;
}

.zoom-stop {
  position: absolute;
  inset: 0;
  z-index: 1; /* Content ueber dem Bild */
}

/* Breite wie in den Halbflaechen-Mastern: bis zur Mitte, minus Aussenrand und
   halbe Naht (split, headline-text, cover-letter, quote rechnen identisch). */
.zoom-headline { max-width: calc(50vw - var(--slide-pad-x) - var(--gutter-x) / 2); }
.zoom-text { max-width: calc(50vw - var(--slide-pad-x) - var(--gutter-x) / 2); font-family: var(--font-main); }

/* ---------- Lottie-Master (Animation als Hintergrund) ---------- */
/* Vollflaechige Animation als unterste Schicht (analog zoom-bg). Lottie haengt
   ein <svg> ein, das den Container fuellt; bei fit "cover" (slice) ragt es ueber
   den Rand, deshalb overflow: hidden. Die .lottie-stop-Anker sind der
   Nachruest-Haken fuer spaeteren Inhalt je Stopp (v1 leer, ueber dem Bild). */
.lottie-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
}
.lottie-bg svg { display: block; }

/* fit: width/height passen eine Kante exakt an (SVG-Stil setzt der Master nach
   dem Laden). Hier nur die Zentrierung des ueberstehenden/kuerzeren SVG; der
   Ueberstand wird vom overflow: hidden des .lottie-bg beschnitten. */
.lottie-bg.fit-width,
.lottie-bg.fit-height {
  display: flex;
  align-items: center;
  justify-content: center;
}

.lottie-stop {
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* ---------- Video-Master (Video als Hintergrund) ---------- */
/* Vollflaechiges Video als unterste Schicht (analog .lottie-bg). cover/contain
   ueber object-fit; width/height passen eine Kante exakt an und zentrieren das
   ueberstehende/kuerzere Video (Ueberstand vom overflow: hidden beschnitten). */
.video-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
}
.video-bg video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.video-bg.fit-contain video { object-fit: contain; }
.video-bg.fit-width,
.video-bg.fit-height {
  display: flex;
  align-items: center;
  justify-content: center;
}
.video-bg.fit-width video  { width: 100%; height: auto; object-fit: fill; }
.video-bg.fit-height video { height: 100%; width: auto; object-fit: fill; }

/* ---------- Marker (Strike / Highlight) ---------- */
/* Inline-Rollen `highlight` (==Text==) und `strike` (~~Text~~). Wenn
   die Brand einen Renderer fuer die Rolle hat, zeichnet er auf eine
   eigene Canvas-Schicht ueber dem Span. Fehlt der Renderer, kennzeichnet
   der Player den Span per .mark-fallback und das System zeigt eine
   einfache CSS-Auszeichnung (unten). */

.marker-canvas {
  position: absolute;
  pointer-events: none;
}

.marker-highlight {
  z-index: 3;
  mix-blend-mode: multiply;
}

.marker-strike {
  z-index: 4;
}

/* System-Fallback ohne Brand-Renderer: text-decoration. Bleibt unsichtbar,
   bis der Player den zugehoerigen Schritt erreicht (Klasse .mark-shown). */
.mark-shown.mark-strike    { text-decoration: line-through; }
.mark-shown.mark-highlight { text-decoration: underline; }

/* ---------- TOC-Master (Inhaltsverzeichnis) ---------- */
/* Zwei Bloecke (TOC-Tabelle + Headline/Textblock) werden vom Master inline
   in ihre Ecke positioniert (linke/rechte Spalte an 50vw +/- slide-pad/2,
   oben an --content-top bzw. unten an --content-bottom). Hier nur die
   Innengestaltung; Schriftgroessen kommen ueber die Skalenklassen (t-*). */
/* Echte verschachtelte <ol>. theme.css liefert nur den strukturellen Default
   (Listen-Reset, CSS-Zaehler fuer die Nummern, Einrueckung, Klickbarkeit);
   die eigentliche Listen-Optik gestaltet die Marke spaeter. */
.toc {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--list-gap-factor) * var(--space-after) * 1lh);
  text-align: left;
  font-family: var(--list-family);
  font-weight: var(--list-weight);
  font-style: var(--list-style);
  text-transform: var(--list-transform);
  font-variant-caps: var(--list-caps);
  counter-reset: li;
}
.toc-chapter { counter-increment: li; }

/* Verschachtelte Abschnittsliste: eingerueckt, eigener Zaehler */
.toc-sub {
  list-style: none;
  margin: calc(var(--list-gap-factor) * var(--space-after) * 1lh) 0;
  padding-left: var(--bullet-gap);   /* Verschachtelung steppt in der Marker-Einheit: Ebene n = n x --bullet-gap, Nummer buendig unter dem Text der Ebene darueber */
  display: flex;
  flex-direction: column;
  gap: calc(var(--list-gap-factor) * var(--space-after) * 1lh);
  counter-reset: li;
}
.toc-section { counter-increment: li; }

/* Klickbares Label */
.toc-link {
  position: relative;
  display: inline-block;
  cursor: pointer;
  width: fit-content;
}
/* Hover als Marken-Sache (wie --link-decoration): das System konsumiert nur
   die Tokens ohne Fallback. Marke ohne Definition -> kein Hover-Effekt. */
.toc-link:hover { color: var(--c-toc-hover); text-decoration-line: var(--toc-hover-decoration); }

/* Marker (opt-in, --marker; counters(li, ".", ...) erzeugt 1, 1.1 ... je
   Verschachtelung). Haengt wie bei .body-list: der Marker sitzt absolut bei
   left:0, der Text rueckt nur bei gesetztem Marker (.toc.is-marked) um
   --bullet-gap ein. Ohne --marker keine Regel -> kein Marker, kein Einzug. */
.toc.is-marked .toc-link { padding-left: var(--bullet-gap); }
.toc-link::before {
  content: var(--marker);
  position: absolute;
  left: 0;
  top: 0;
}

/* Headline + Textblock (diagonal gegenueber der Tabelle) */
.toc-content {
  display: flex;
  flex-direction: column;
  text-align: left;
  font-family: var(--font-main);
}
.toc-content > :not(:last-child) { margin-bottom: calc(var(--space-after) * 1lh); }
.toc-textblock { color: inherit; white-space: pre-line; }

/* ---------- Cover-Letter-Master ---------- */
/* Zwei Halbflaechen: Textspalte (Textkoerper oben, Absender unten an der
   Content-Grenze) und Headline-Spalte gegenueber. Aussenkante 1x slide-pad,
   zur Mitte hin 1/2 slide-pad (gilt fuer beide Spalten). */
.cl-half {
  position: absolute;
  top: var(--content-top);
  bottom: var(--content-bottom);
  z-index: 1;
  display: flex;
  flex-direction: column;
}
.cl-half.cl-on-left  { left: 0;   right: 50%; padding-left:  var(--slide-pad-x); padding-right: calc(var(--gutter-x) / 2); }
.cl-half.cl-on-right { left: 50%; right: 0;   padding-right: var(--slide-pad-x); padding-left:  calc(var(--gutter-x) / 2); }

/* Textspalte: Textkoerper oben, Absender unten */
.cl-text   { justify-content: space-between; text-align: left; }
.cl-body   { font-family: var(--font-main); }
.cl-sender { flex: 0 0 auto; font-family: var(--font-main); }   /* Groesse als t-*-Klasse vom Master */
.cl-sig    { display: block; width: auto; margin-bottom: calc(var(--space-after) * 1lh); }
.cl-name   { white-space: pre-line; }
.cl-pos    { white-space: pre-line; }

/* Headline-Spalte: oben oder unten, an der Aussenkante der Spalte ausgerichtet */
.cl-headcol.cl-h-top    { justify-content: flex-start; }
.cl-headcol.cl-h-bottom { justify-content: flex-end; }
/* Die Spalte sitzt bereits per Position auf ihrer Seite (.cl-half.cl-on-*).
   align-items:stretch laesst die Headline die volle Spaltenbreite fuellen,
   damit text-align:left (an .cl-headline) den Inhalt innen links ausrichtet,
   auch wenn er die Breite nicht ausnutzt. */
.cl-headcol.cl-on-left  { align-items: stretch; }
.cl-headcol.cl-on-right { align-items: stretch; }

/* Headline-Breite: 50 (Default = halbe Folie), 75, 100 Prozent.
   75 schiebt nur die innere Kante (/2 slide-pad bleibt); 100 spannt voll,
   die innere Kante wird zur Aussenkante (volles slide-pad). */
.cl-headcol.cl-on-right.cl-hw-75  { left: 25%; }
.cl-headcol.cl-on-left.cl-hw-75   { right: 25%; }
.cl-headcol.cl-on-right.cl-hw-100 { left: 0;  padding-left:  var(--slide-pad-x); }
.cl-headcol.cl-on-left.cl-hw-100  { right: 0; padding-right: var(--slide-pad-x); }
.cl-headline { font-family: var(--font-main); white-space: pre-line; text-align: left; }

/* ---------- Headline-Text-Master ---------- */
/* Aufbau wie cover-letter (zwei Halbflaechen, gleiche Variablen), aber ohne
   Absender/Signatur. Die Textspalte steht oben oder unten buendig (textalign
   ueber justify-content). Eigene .ht-*-Klassen, damit der Master unabhaengig
   von cover-letter bleibt. */
.ht-half {
  position: absolute;
  top: var(--content-top);
  bottom: var(--content-bottom);
  z-index: 1;
  display: flex;
  flex-direction: column;
}
.ht-half.ht-on-left  { left: 0;   right: 50%; padding-left:  var(--slide-pad-x); padding-right: calc(var(--gutter-x) / 2); }
.ht-half.ht-on-right { left: 50%; right: 0;   padding-right: var(--slide-pad-x); padding-left:  calc(var(--gutter-x) / 2); }

/* Textspalte: oben oder unten buendig */
.ht-text { text-align: left; }
.ht-text.ht-t-top    { justify-content: flex-start; }
.ht-text.ht-t-bottom { justify-content: flex-end; }
/* Auto-Hoehe statt voller Content-Hoehe: die Textbox umschliesst ihren Inhalt
   und wird nur an die gewaehlte Kante gepinnt (wie der columns-Stack). Sonst
   zieht ein mehrspaltiger .ht-body (columns: true) die Box auf die volle Hoehe,
   die Spalten fuellen von oben und unten bleibt Leerraum. */
.ht-text.ht-t-top    { bottom: auto; }
.ht-text.ht-t-bottom { top: auto; }
.ht-body { font-family: var(--font-main); }

/* Mehrspaltiger Text: eine FUEHRENDE ***-Linie spannt ueber alle Spalten (volle
   Container-Breite), eine Linie mitten im Text bleibt in Spaltenbreite.
   Standard-column-span, kein Sonderfall im Markup. Ohne columns wirkungslos. */
.ht-body > hr.rule:first-child { column-span: all; }

/* Textbreite: 25/50/75/100 %, gemessen von der Aussenkante der Textseite.
   25/75 verschieben nur die innere Kante (innen bleibt slide-pad/2), 50 ist
   die Basis (halbe Folie), 100 spannt voll, innere Kante wird Aussenkante
   (volles slide-pad). Analog zu headlinewidth, plus dem schmaleren 25. */
.ht-text.ht-tw-25.ht-on-left   { right: 75%; }
.ht-text.ht-tw-25.ht-on-right  { left: 75%; }
.ht-text.ht-tw-75.ht-on-left   { right: 25%; }
.ht-text.ht-tw-75.ht-on-right  { left: 25%; }
.ht-text.ht-tw-100.ht-on-left  { right: 0; padding-right: var(--slide-pad-x); }
.ht-text.ht-tw-100.ht-on-right { left: 0;  padding-left:  var(--slide-pad-x); }

/* Headline-Spalte: oben oder unten, an der Aussenkante der Spalte ausgerichtet */
.ht-headcol.ht-h-top    { justify-content: flex-start; }
.ht-headcol.ht-h-bottom { justify-content: flex-end; }
/* Die Spalte sitzt bereits per Position auf ihrer Seite (.ht-half.ht-on-*).
   align-items:stretch laesst die Headline die volle Spaltenbreite fuellen,
   damit text-align:left (an .ht-headline) den Inhalt innen links ausrichtet,
   auch wenn er die Breite nicht ausnutzt. */
.ht-headcol.ht-on-left  { align-items: stretch; }
.ht-headcol.ht-on-right { align-items: stretch; }
.ht-headcol.ht-on-right.ht-hw-75  { left: 25%; }
.ht-headcol.ht-on-left.ht-hw-75   { right: 25%; }
.ht-headcol.ht-on-right.ht-hw-100 { left: 0;  padding-left:  var(--slide-pad-x); }
.ht-headcol.ht-on-left.ht-hw-100  { right: 0; padding-right: var(--slide-pad-x); }
.ht-headline { font-family: var(--font-main); white-space: pre-line; text-align: left; }

/* stacked: Headline und Text in einer Spalte auf side (X-Position der
   Headline). Volle Folienbreite mit slide-pad aussen; align-items haengt die
   Bloecke an die Headline-Seite, die Breite begrenzt der Master per max-width
   inline. Vertikale ueber .ht-v-* (unabhaengig gepinnt). */
.ht-stack {
  position: absolute;
  top: var(--content-top);
  bottom: var(--content-bottom);
  left: 0;
  right: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  padding-left: var(--slide-pad-x);
  padding-right: var(--slide-pad-x);
  /* Inhalt bleibt linksbuendig, unabhaengig von der Block-Seite. */
  text-align: left;
}
/* align-items haengt die Bloecke an die Headline-Seite; der Text INNEN bleibt
   linksbuendig (kein text-align hier). */
.ht-stack.ht-side-left  { align-items: flex-start; }
.ht-stack.ht-side-right { align-items: flex-end; }
/* contained (Panel): der Stack ist nicht mehr absolut/folienbreit, sondern
   fuellt seinen Eltern-Container (ein Panel von headline-text-panels). Das
   Panel selbst (.ht-half) positioniert und padded; hier nur fuellen. */
.ht-stack--contained {
  position: static;
  top: auto; bottom: auto; left: auto; right: auto;
  width: 100%;
  height: 100%;
  padding: 0;
}
/* Vertikaler Abstand der gestapelten Bloecke (Headline<->Text bei .ht-stack,
   Headline<->Intro bei .ht-headcol mit Intro). Eine Quelle fuer beide Stapel.
   Der Abstand ist das Absatzformat des OBEREN Blocks (--space-after seiner
   Stufe), nicht ein Container-gap: eine groessere Headline reserviert so mehr
   Freiraum nach unten. Nur im Gleich-Kanten-Fall (tt/bb) noetig; bei
   space-between (tb/bt) schiebt die Verteilung die Bloecke an die Kanten. */
.ht-v-tt { justify-content: flex-start; }
.ht-v-bb { justify-content: flex-end; }
.ht-v-tb { justify-content: space-between; }
.ht-v-bt { justify-content: space-between; flex-direction: column-reverse; }
.ht-v-tt > :not(:last-child),
.ht-v-bb > :not(:last-child) { margin-bottom: calc(var(--space-after) * 1lh); }

/* ---------- Takeaway (headline-text-Familie) ---------- */
/* Letzter Body-Block als eigenes Element, ausserhalb von columns/table, Breite
   inline (% des Containers). Die Optik (Kasten, Farbe, Typo) ist Marken-Sache
   ueber .ht-takeaway; hier nur die Struktur. ht-has-takeaway macht Spalte bzw.
   Textseite zur Flex-Spalte von oben mit Absatzabstand, ht-push-bottom schiebt
   den betreffenden Block per auto-Margin an die Unterkante. */
.ht-stack.ht-has-takeaway,
.ht-text.ht-has-takeaway { justify-content: flex-start; }
.ht-has-takeaway > :not(:last-child) { margin-bottom: calc(var(--space-after) * 1lh); }
.ht-push-bottom { margin-top: auto; }

/* Horizontale Ausrichtung des Takeaway-Containers (align:...-left/-right, bare =
   center). Ohne align keine Klasse: der Block fliesst natuerlich (links). Die
   Spalten sind Flex-Columns, daher greift align-self auf der Querachse. */
.ht-ta-h-left   { align-self: flex-start; }
.ht-ta-h-center { align-self: center; }
.ht-ta-h-right  { align-self: flex-end; }

/* Verankerter Takeaway (align:bottom / bottom-left / bottom-right): eigene,
   deckungsgleiche Box auf der Textseite (.ht-half.ht-text bzw. .ht-stack),
   volle Content-Hoehe, Kind unten gepinnt. Aus dem Fluss heraus: der Body
   schiebt ihn nicht, ein zu hoher Body ueberlappt ihn (Autoren-Verantwortung).
   Transparent, nur der Takeaway faengt Klicks. Horizontal wie im Fluss ueber
   .ht-ta-h-* (align-self). */
.ht-ta-anchor { justify-content: flex-end; pointer-events: none; }
.ht-ta-anchor > .ht-takeaway { pointer-events: auto; }

/* Optionaler Marken-Marker hinter dem Takeaway. Das Bild haengt der Player als
   <img class="ht-takeaway-marker"> ein (setupTakeawayMarker); Quelle und
   Platzierung kommen aus brand.takeaway und laufen ueber den Asset-Resolver wie
   jedes andere Asset. Hier nur die Struktur; ohne brand.takeaway kein Marker. */
.ht-takeaway { position: relative; isolation: isolate; }
.ht-takeaway-marker { position: absolute; pointer-events: none; }

/* ---------- Breadcrumb — System-Default ---------- */
/* Fallback fuer Marken ohne eigenes brands/<id>/chrome.css. Marken mit
   eigenem Chrome-CSS ueberschreiben das komplett (chrome.css laedt nach
   theme.css). Bewusst getrennt von den Marken, nichts Geteiltes. */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}
.crumb {
  font-family: var(--font-main);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1;
  color: var(--c-inactive); /* inaktiv */
  cursor: pointer;
}
.crumb.is-active {
  color: var(--c-active);  /* aktiv */
}
.crumb-sep {
  color: var(--c-inactive);
}
.crumb-sep::before {
  content: " // ";
  white-space: pre;
}

/* ---------- Header / Footer (Chrome-Balken) ---------- */
/* Footer und Header teilen Optik und Innen-Layout; sie unterscheiden
   sich nur in der vertikalen Position und der Hoehen-Variable. Die
   inneren Elemente nutzen neutrale bar-*-Klassen, damit beide Balken
   dieselbe Optik tragen. */

.header,
.footer {
  position: absolute;
  left: 0;
  right: 0;
  padding: 0 var(--chrome-pad-x);   /* vertikal 0, Inhalt mittig ueber align-items */
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 5;
}

.footer { bottom: 0; height: var(--footer-height); }
.header { top: 0;    height: var(--header-height); }

.bar-left {
  display: flex;
  align-items: center;
  gap: var(--chrome-gap);
}

.bar-logo {
  /* Hoehe setzt der Footer-Render aus brand.logo.size (em auf die 1rem Balken-Schrift). */
  font-size: 1rem;
  width: auto;
  display: block;
}

/* Bar-Text: 1rem auf 1rem Zeilenhoehe, mittig im Balken */
.bar-name,
.bar-desc,
.bar-page {
  line-height: 1;
}

.bar-name {
  /* erbt color vom Slide-Theme (weiss auf dark, schwarz auf light) */
  color: inherit;
}

.bar-desc,
.bar-page {
  color: var(--c-footer);
}

/* ---------- Fehleranzeige ---------- */

.error-screen {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 2rem;
  background: var(--bg-black);
  color: var(--headline-on-dark, var(--headline));
  font-family: var(--font-main);
  font-size: var(--fs-1);
  text-align: center;
  white-space: pre-wrap;
}

/* ============================================================
   Mobil-Ausschluss (System-Ebene, markenunabhaengig)
   Hinweis-Screen fuer Telefone. Neutrale, feste Werte, weil dieser
   Screen rendert, bevor eine Marke geladen ist (Player bricht vorher ab).
   ============================================================ */
.mobile-block {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 32px;
  box-sizing: border-box;
  background: #0e0e0e;
  color: #f2f2f2;
  text-align: center;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
.mobile-block-icon { width: 88px; height: auto; display: block; }
.mobile-block-head { margin: 0; font-size: 25px; line-height: 1.25; font-weight: 600; }
.mobile-block-text { margin: 0; max-width: 34ch; font-size: 16px; line-height: 1.55; color: #bdbdbd; }
