/* ============================================================
   Bock Maschinenbau GmbH – Main CSS
   ============================================================
   Mobile-first, responsive, accessible.
   Importiert variables.css (immer zuerst laden).
   ============================================================ */

/* ── Reset & Base ─────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  /* Anker-Sprünge landen UNTER dem fixen Header-Stack. DIESE Deklaration ist die
     eine Quelle für den Landepunkt: der JS-Anker-Klick und der Scroll-Spy LESEN
     sie (bmAnchorOffset in main.js), statt sie nachzurechnen. --header-offset
     enthält den Sprachvorschlag-Banner; Seiten mit Prozess-Schiene erweitern
     die Regel in components/sticky-cards.css um deren Höhe. */
  scroll-padding-top: var(--header-offset);
  -webkit-text-size-adjust: 100%;
}

html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

body {
  font-family: var(--font-base);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background: var(--color-bg);
  overflow-x: hidden;
  /* Der Header ist fix & immer solide → er darf nichts überdecken. Der Body
     reserviert global die Höhe des Header-Stacks (Banner + Navbar), sodass JEDE
     Seite sauber DARUNTER beginnt — auch wenn der Sprachbanner oben einblendet. */
  padding-top: var(--header-offset);
  /* Trenn-Limit EINMAL an der Wurzel: `hyphenate-limit-chars` VERERBT sich, also
     gilt es damit fuer jedes Element, das irgendwo `hyphens: auto` bekommt — auch
     fuer solche, die nicht in der Prosa-Regel unten stehen. Ohne das hier trennte
     z.B. `.gallery-item-label-text` (ein span) weiter unlimitiert; gemessen 21
     Bildunterschriften mit computed limit `auto`. Selektoren aufzuzaehlen waere
     Whack-a-Mole — vererben ist die kategorische Variante. */
  -webkit-hyphenate-limit-before: 4;   /* Safari < 17 kennt kein Shorthand */
  -webkit-hyphenate-limit-after: 4;
  hyphenate-limit-chars: 8 4 4;
}

img, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { cursor: pointer; border: none; background: transparent; font: inherit; }
ul, ol { list-style: none; }
address { font-style: normal; }

/* Abkürzung mit Klartext-Auflösung (SSOT-Komponente): dezente gepunktete
   Akzent-Unterlinie + Hilfe-Cursor, damit Fachkürzel (EXC3, MT, PT, VT, WPS …)
   ihre Langform per title-Tooltip preisgeben — barrierefrei (Screenreader &
   Suchmaschinen lesen das title-Attribut) und ohne eigenes Markup. Greift NUR
   bei gesetztem title, damit unerklärte Kürzel nicht markiert werden. */
abbr[title] {
  text-decoration: underline dotted;
  text-decoration-thickness: from-font;
  text-decoration-color: var(--color-accent-text);
  text-underline-offset: 0.18em;
  cursor: help;
}

/* Globaler Schutz gegen Text-Überlauf: ein unbrechbares Wort (lange Komposita
   wie „Qualitätsmanagementsystem", griechische/ungarische Wörter, URLs) darf
   NIE aus seiner Box laufen und den Nachbarinhalt überdecken. `anywhere`
   reduziert zusätzlich die Min-Content-Breite in Grid-/Flex-Layouts; genau dort
   entstehen mobile Rechts-Ausbrüche trotz 100%-Containern. Das schließt die
   „Überschneidung"-Klasse kategorisch für ALLE Sprachen aus. Geprüft von
   seo_engine/layout_checks (LAYOUT_TEXT_OVERFLOW). */
h1, h2, h3, h4, h5, h6,
p, li, dt, dd, th, td, figcaption, blockquote, summary, label,
.section-label, .section-title, .page-hero-title,
/* Komponenten-Titel und -Beschriftungen tragen echte Prosa, sind aber oft
   <strong>/<span> statt <h*> — z.B. .usp-title („Schweisskonstruktionen bis
   50 t") oder .gallery-item-label-text. Sie einzeln aufzuzaehlen waere
   Whack-a-Mole (gemessen: 25 weitere *-title/-heading-Klassen); der
   Substring-Selektor nimmt jede kuenftige Komponente automatisch mit.
   Ohne `-label` blieben die Galerie-Bildunterschriften auf `hyphens: manual`
   und brachen in ihrer 139px-Spalte HART mitten im Wort („Sondermaschinenb|au",
   „Vibrationsentspann|en"). Kurze UI-Labels trennt das Limit 8/4/4 ohnehin nie. */
[class*="-title"], [class*="-heading"], [class*="-label"] {
  overflow-wrap: anywhere;
  -webkit-hyphens: auto;   /* Safari < 17 kennt NUR die gepraefixte Form — ohne */
  hyphens: auto;           /* diese Zeile trennt iOS gar nicht und Titel laufen ueber */
  /* Nur ECHTE Komposita trennen: Wort >= 8 Zeichen, >= 4 davor, >= 4 danach.
     Ohne Limit trennt der Browser ab 2 Zeichen — gemessen auf 18 Seiten/18 Sprachen
     bei 390px: 750 Trennungen, davon 214 haesslich („La-ckieren", „ei-nem",
     „Bautei-le"). Mit 8/4/4: 440 Trennungen, 0 haesslich. Geprueft von
     seo_engine/layout_checks --check linebreak (LAYOUT_BAD_HYPHENATION) und
     tests/styling/test_hyphenation_ssot.py. */
  -webkit-hyphenate-limit-before: 4;   /* Safari < 17: Einzel-Properties statt Shorthand */
  -webkit-hyphenate-limit-after: 4;
  hyphenate-limit-chars: 8 4 4;
}

/* Chinesisch kennt keine Silbentrennung — CJK bricht korrekt pro Zeichen. Ein
   Trennwoerterbuch gibt es dort nicht, `hyphens: auto` waere bestenfalls wirkungslos.
   Explizit abschalten, damit die Absicht im Code steht (und der Guard sie sieht). */
:lang(zh), :lang(zh) * {
  -webkit-hyphens: none;
  hyphens: none;
}

/* Zeilenausgleich statt „Schusterjunge": ohne Ausgleich endet fast jede zweite
   mehrzeilige Ueberschrift mit einem einzelnen Wort auf der letzten Zeile.
   Progressive Enhancement — Browser ohne Unterstuetzung ignorieren es folgenlos.

   ACHTUNG, teuer gelernt: `text-wrap: balance` darf NICHT breitflaechig auf
   Komponenten-Titel. Chromiums Balancer bricht ein Wort notfalls HART, um die
   Zeilen auszugleichen — gemessen wurde aus „Schweisskonstruktionen bis 50 t"
   ein „Schweisskonstrukt / ionen bis 50 t" (ohne Trennstrich!). Das haengt NICHT
   an overflow-wrap: mit `anywhere`, `break-word` UND `normal` identisch; nur das
   Abschalten von balance liefert den sauberen Umbruch. Deutsche Komposita fuellen
   eine schmale Kartenzeile fast vollstaendig, genau dort schlaegt es zu.

   Deshalb zweistufig:
     · Komponenten-Titel + Fliesstext → `pretty` (optimiert nur die LETZTE Zeile,
       kann darum kein Wort hart brechen; gemessen sauberer Umbruch)
     · grosse Ueberschriften          → `balance` (dort messbar besser:
       50 statt 63 Wort-Umbrueche und 66 % statt 75 % Widows)
   Die balance-Regel steht ABSICHTLICH nach der pretty-Regel: beide haben
   Spezifitaet (0,1,0), die Quellreihenfolge entscheidet. */
[class*="-title"], [class*="-heading"],
p, li, dd, figcaption, blockquote {
  text-wrap: pretty;
}

h1, h2, h3,
.section-title, .page-hero-title, .hero-title, .service-card-title {
  text-wrap: balance;
}

/* ── Accessibility ────────────────────────────────────────── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
:focus-visible {
  outline: 3px solid var(--color-accent-text);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ── Layout: Container ────────────────────────────────────── */
.section-container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--space-6);
}
@media (min-width: 768px) {
  .section-container { padding: 0 var(--space-8); }
}
@media (min-width: 1280px) {
  .section-container { padding: 0 var(--space-12); }
}

/* ── Section Media: Text + Inline Bild ───────────────────── */
.section-media {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-10);
  align-items: center;
}
@media (min-width: 768px) {
  .section-media {
    grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid);
    gap: var(--space-16);
  }
}
/* spec_table-Variante: die Datentabelle ist primär und darf auf Tablet nicht in
   eine halbe Spalte neben die Maschinen-Galerie gequetscht werden. Darum bleibt
   `--spec` bis 1024px einspaltig (Tabelle volle Breite, Galerie darunter) und
   splittet erst auf großen Screens neben die Galerie.
   WICHTIG: `minmax(0, 1fr)` statt eines nackten `1fr` (dessen automatisches
   Minimum = min-content ist) + `min-width: 0` auf den Grid-Kindern — sonst reißt
   die `min-width` der Tabelle die Grid-Spalte auf und die Seite bekommt einen
   horizontalen Overflow, statt dass der `__scroll`-Container die Tabelle kappt. */
.section-media--spec {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-10);
}
.section-media--spec > * { min-width: 0; }
@media (min-width: 1024px) {
  .section-media--spec {
    grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid);
    gap: var(--space-16);
  }
}
.section-media__figure {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 6px 32px rgb(var(--c-shadow) / 0.18);
  order: 1;
}
@media (min-width: 768px) {
  .section-media__figure { order: unset; }
}
.section-media__picture {
  display: block;
  width: 100%;
}
.section-media__img {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
/* Portrait sources must NOT be squeezed into the landscape 4:3 box (that crops
   the top/bottom). `data-orientation` is stamped data-driven from the image's
   real intrinsic pixels by picture_html_v2 — so a hochformat photo renders in
   its own aspect ratio automatically, no per-image override in templates.
   Capped so an unusually tall image can't dominate the column. */
.section-media__img[data-orientation="portrait"] {
  aspect-ratio: auto;
  object-fit: contain;
  max-height: 78vh;
  width: auto;
  max-width: 100%;
  margin-inline: auto;
}
/* …und die GERAHMTE Fläche muss dann das Bild sein, nicht die Spalte daneben.
   `object-fit: contain` stellt das <img> zwar exakt auf die gemalte Fläche, aber
   `figure`/`picture` blieben auf voller Spaltenbreite — Radius und Schatten
   umrandeten also eine LEERE Box. Gemessen (Desktop 1280, /leistungen/
   cnc-horizontal-bohrwerk/): figure 560px vs. gemaltes Bild 311px = 249px Leerrand,
   Rundung unsichtbar. Betraf site-weit 164 Hochformat-Bilder; die 783 Querformat-
   Bilder messen gap_x=0 und bleiben unberührt (nur der Hochformat-Zweig wird
   angefasst). Gleiche SSOT-Quelle wie die Regel darüber: `data-orientation`, aus
   den echten Pixeln gestempelt — kein neues Attribut, keine Template-Ausnahme.
   Nachweis/Ratsche: seo_engine/layout_checks/media_frame_audit.py */
.section-media__figure:has(.section-media__img[data-orientation="portrait"]),
.section-media__picture:has(.section-media__img[data-orientation="portrait"]) {
  width: fit-content;
  margin-inline: auto;
}
.dark-section .section-media__figure {
  box-shadow: 0 6px 32px rgb(var(--c-shadow) / 0.45);
}

/* ── Klickbare Karten-Fläche (wiederverwendbar) ─────────────
   Gemeinsame Karten-OBERFLÄCHE für Text+Bild-Blöcke: `.section-media--card`
   (leistung_detail) und `.mpk-recruit--card` (Maschinenpark-Recruiting).
   Interaktion (Glow/Lift/Bild-Zoom) kommt zentral aus `.u-card`
   (components/effects.css), der Pfeil-Reveal aus `.card-reveal-cta`
   (components/buttons.css). Die Karte liegt jeweils IN `.section-container`,
   d.h. die zentralen Rand-Abstände bleiben; die Karte trägt nur Innen-Padding. */
.section-media--card,
.mpk-recruit--card,
.machinery-teaser__card {
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
@media (min-width: 768px) {
  .section-media--card,
  .mpk-recruit--card,
  .machinery-teaser__card { padding: var(--space-12); }
}
/* Bild-Zoom (`.u-card [data-card-img]`) im Bild-Wrapper clippen, damit der
   Zoom die abgerundeten Ecken nicht überläuft (Gallery-Pattern). */
.machinery-teaser__card .two-col-image {
  overflow: hidden;
  border-radius: var(--radius-xl);
}
/* Auf dem Handy hat die `.mpk-envelope`-Kachelreihe im Karten-Innenraum
   (Card-Padding) zu wenig Breite für 2 Spalten → lange Werte/Labels würden
   clippen. Darum EINE Spalte: die Zahlen bekommen volle Breite und knallen. */
@media (max-width: 560px) {
  .machinery-teaser__card .mpk-envelope { grid-template-columns: 1fr; }
}
/* Mobil: Bild nach oben in die Karte (statt ganz unten) → wirkt interessanter.
   Desktop bleibt Text-links / Bild-rechts (natürliche Quell-Reihenfolge).
   (`.mpk-recruit__media` bringt sein `order:-1` mobil bereits selbst mit.) */
.section-media--card .section-media__figure { order: -1; }
@media (min-width: 768px) {
  .section-media--card .section-media__figure { order: 0; }
}
@media (hover: hover) {
  .section-media--card:is(:hover, :focus-within),
  .mpk-recruit--card:is(:hover, :focus-within),
  .machinery-teaser__card:is(:hover, :focus-within) {
    border-color: var(--card-border-hover);
  }
}
/* Auf dunklen Sektionen: transluzente Glas-Fläche, damit die hellen
   dark-section-Textfarben lesbar bleiben. */
.dark-section .section-media--card,
.dark-section .mpk-recruit--card,
.dark-section .machinery-teaser__card {
  background-color: var(--glass-on-dark-bg);
  border-color: var(--glass-on-dark-border);
}
@media (hover: hover) {
  .dark-section .section-media--card:is(:hover, :focus-within),
  .dark-section .mpk-recruit--card:is(:hover, :focus-within),
  .dark-section .machinery-teaser__card:is(:hover, :focus-within) {
    border-color: var(--card-border-hover-dark);
  }
}
/* Reveal-CTA-Abstand innerhalb der Karte (ersetzt .section-link-wrap).
   `.mpk-recruit__cta` braucht das NICHT: `.mpk-recruit__actions` bringt den
   Abstand bereits mit (margin-top). */
.section-media__cta { margin-top: var(--space-6); }

/* ── Recruiting-Bridge Layout (Dispatcher-Typ `recruit`) ───────────────────
   GLOBAL hier (nicht in machinery.css): `recruit` ist ein zentraler
   render_sections-Typ und kann auf JEDER Seite stehen (z.B. /standort/, das
   machinery.css nicht lädt). Die Karten-Fläche `.mpk-recruit--card` liegt
   bereits oben; hier das Grid-Layout, damit die Card überall 2-spaltig greift. */
.mpk-recruit {
  display: grid;
  gap: var(--space-10);
  align-items: center;
}
@media (min-width: 860px) {
  .mpk-recruit { grid-template-columns: 1.05fr 0.95fr; }
}
.mpk-recruit__media {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
}
.mpk-recruit__media img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
@media (max-width: 860px) {
  .mpk-recruit__media { order: -1; }
}

/* ── Sections ─────────────────────────────────────────────── */
.section {
  padding: var(--section-py) 0;
  background: var(--color-bg);
}
.dark-section {
  background: var(--color-bg-dark);
  color: var(--color-text-inverse);
}

.section-header {
  text-align: center;
  margin-bottom: var(--space-16);
}
.section-header.text-left { text-align: left; }

.section-label {
  display: inline-block;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-accent-text);
  margin-bottom: var(--space-3);
}
.dark-section .section-label,
.karriere-banner .section-label { color: var(--color-accent-text); }

.section-title {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--leading-tight);
  color: var(--color-text);
  margin-bottom: var(--space-4);
}
.dark-section .section-title,
.karriere-banner .section-title { color: var(--color-text-inverse); }

@media (min-width: 768px) {
  .section-title { font-size: var(--text-4xl); }
}
@media (min-width: 1024px) {
  .section-title { font-size: var(--text-5xl); }
}

.section-subtitle {
  font-size: var(--text-lg);
  color: var(--color-text-muted);
  max-width: 640px;
  margin: 0 auto;
  line-height: var(--leading-relaxed);
}
.dark-section .section-subtitle { color: var(--color-text-muted); }

/* In-flow sub-heading INSIDE a section's running text (e.g. `quality`-type
   zfp_h3) — unlike .section-subtitle (a centered lead under the section h2),
   this sits between left-aligned paragraphs and needs its own vertical
   rhythm; the global `* { margin: 0 }` reset leaves headings with none. */
.section-subhead {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--leading-tight);
  color: var(--color-text);
  margin: var(--space-8) 0 var(--space-3);
}
.dark-section .section-subhead { color: var(--color-text-inverse); }

.section-text {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  line-height: var(--leading-relaxed);
  margin-bottom: var(--space-4);
}
.dark-section .section-text { color: var(--color-text-muted); }

.text-center { text-align: center; }

/* ── Two-Column Layout ────────────────────────────────────── */
.two-col {
  display: grid;
  gap: var(--space-12);
  align-items: center;
}
@media (min-width: 768px) {
  .two-col {
    grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid);
    gap: var(--space-16);
  }
  .two-col-reverse { direction: rtl; }
  .two-col-reverse > * { direction: ltr; }
}

.section-img {
  width: 100%;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  object-fit: cover;
  aspect-ratio: 4/3;
}

.image-badge {
  position: absolute;
  bottom: -var(--space-4);
  right: -var(--space-4);
  background: var(--color-accent);
  color: var(--color-text-inverse);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  text-align: center;
  box-shadow: var(--shadow-lg);
}
.two-col-image { position: relative; }
.image-badge-number {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--font-weight-black);
  line-height: 1;
}
.image-badge-label { font-size: var(--text-xs); opacity: 0.85; }

/* ── Check List ───────────────────────────────────────────── */
.check-list {
  margin: var(--space-6) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.check-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
}
.check-list__text { flex: 1 1 auto; min-width: 0; }
.check-list li > .bm-icon {
  flex-shrink: 0;
  color: var(--color-accent-text);
  font-size: 1.3em;          /* +30% ggü. Text — kräftigere Anfahrts-/Fakten-Icons */
  margin-top: 0.05em;
}
.dark-section .check-list li { color: var(--color-text-muted); }

/* ── Zentrierter Section-Kopf (Eyebrow + Title + Lead) ──────────────────────
   Wiederverwendbarer Standard für vollbreite Abschnitte (z.B. process_list-
   Header über einem Card-Raster). Lead bekommt lesbare Zeilenlänge + Auto-Rand. */
.section-head--center { text-align: center; }
.section-head--center > .section-text,
.section-head--center > .section-subtitle {
  margin-left: auto;
  margin-right: auto;
  max-width: 62ch;
}

/* ── Breadcrumb ───────────────────────────────────────────────────────────────
   Der Breadcrumb sitzt auf ZWEI Flächen: dem dunklen Hero-Scrim (.page-hero, in
   BEIDEN Themes dunkel) und der hellen Rechtsseite (.legal-page — /impressum/,
   /datenschutz/, /agb/, /technische-lieferbedingungen/, × 20 Sprachen). Die Basis
   war fix --on-dark-* und damit nur für den Hero richtig: auf der Rechtsseite
   rendern Trenner und aktuelle Seite weiss-auf-weiss (gemessen 1.00:1), sichtbar
   blieb nur der rote "Start"-Link. Basis daher FLIPPEND; die on-dark-Tinte wird
   auf die dunkle Fläche gescopt, wo sie hingehört. */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}
.breadcrumb a {
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color var(--transition-fast);
}
.breadcrumb a:hover { color: var(--color-text); }
.breadcrumb span:last-child { color: var(--color-text); }

/* Dunkle Fläche (Hero-Scrim / dunkles Band) → fixe on-dark-Tinte. */
:is(.page-hero, .dark-section) .breadcrumb,
:is(.page-hero, .dark-section) .breadcrumb a { color: var(--on-dark-text-muted); }
:is(.page-hero, .dark-section) .breadcrumb a:hover,
:is(.page-hero, .dark-section) .breadcrumb span:last-child { color: var(--on-dark-text); }

/* ── Navigation ───────────────────────────────────────────── */
.navbar {
  position: fixed;
  /* Sitzt UNTER dem Sprachbanner (dessen Höhe in --ls-banner-h steckt, sonst 0).
     So überdeckt der Banner die Navbar nie — beide stapeln sich. */
  top: var(--ls-banner-h); left: 0; right: 0;
  height: var(--nav-height);
  /* IMMER solide & frosted – nie transparent. Weiß-auf-Graphit ist dadurch über
     jedem Hero-Bild/Video lesbar, ohne Moduswechsel beim Scrollen. */
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(var(--nav-blur));
  backdrop-filter: blur(var(--nav-blur));
  border-bottom: 1px solid var(--nav-border);
  transition: top var(--transition-base), background var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
  z-index: var(--z-nav);
}
/* Beim Scrollen vom Top gelöst: Fläche minimal dichter + Schatten (Elevation). */
.navbar.scrolled {
  background: var(--nav-bg-scrolled);
  border-bottom-color: var(--nav-border-scrolled);
  box-shadow: var(--nav-shadow-scrolled);
}

.nav-container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--space-6);
  height: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.nav-logo { flex-shrink: 0; }
.logo-img { height: 40px; width: auto; }

/* ── Header-Zeile auf Mobil (≤1023px) — darf NIE überlaufen ──────────────────
   Unter 1024px teilen sich Logo · Theme-Toggle · Sprach-Trigger · Burger EINE
   Zeile. Mit dem Desktop-Rhythmus (24px Padding, 24px Gap, 40px Logo) summierten
   sie sich bei 360px Viewport auf 391px — die Zeile lief 25px über. Sichtbar
   wurde das nicht als Scrollbar (body{overflow-x:hidden} kappt sie), sondern als
   Schaden an den Bedienelementen: Flexbox schrumpfte den Theme-Toggle von 34px
   auf 20px (gequetschte Sonne) und schob den Burger hinter den rechten Rand.
   Auf /hr/ (Trigger mit drei Flaggen HR/RS/BA, 118px) waren es 77px Überlauf —
   der Burger stand bei x=399 auf einem 360px-Schirm, die Mobil-Navigation war
   damit komplett unerreichbar.
   Fix in drei Teilen: (1) mobiler Rhythmus statt Desktop-Rhythmus, (2) die
   Bedienelemente sind flex-shrink:0 — nachgeben darf nur noch das Logo, und
   zwar proportional (object-fit) statt gequetscht, (3) der Trigger zeigt auf
   Mobil nur die ERSTE Flagge, damit eine Mehrflaggen-Sprache die Zeile nicht
   sprengen kann; die volle Flaggen-Reihe steht weiter in jeder Menü-Zeile. */
@media (max-width: 1023px) {
  .nav-container {
    padding: 0 var(--space-4);
    gap: var(--space-2);
  }
  .nav-logo { flex-shrink: 1; min-width: 0; }
  .logo-img { height: 34px; max-width: 100%; object-fit: contain; }
  .theme-toggle,
  .nav-toggle { flex-shrink: 0; }
  .lang-current .lang-flag ~ .lang-flag { display: none; }
  /* Achtung Kaskade: Größe/Abstand von .theme-toggle NICHT hier setzen — dieser
     Block steht VOR der Basisregel .theme-toggle, und ein Media-Query erhöht die
     Spezifität nicht, die spätere Quelle gewinnt also. Die Touch-Ziel-Maße
     stehen deshalb im ≤1023px-Block hinter der Basisregel (Suche „Touch-Ziel"). */
}
/* Sehr schmale Telefone (≤380px): Rhythmus noch eine Stufe enger, damit auch
   bei 320px alle vier Elemente innerhalb des Paddings bleiben. */
@media (max-width: 380px) {
  .nav-container {
    padding: 0 var(--space-3);
    gap: var(--space-1);
  }
}

/* ── Desktop Nav Links ──────────────────────────────────── */
.nav-links {
  display: none;
  align-items: center;
  gap: var(--space-1);
  margin-left: auto;
}
@media (min-width: 1024px) {
  .nav-links { display: flex; }
}

.nav-link {
  display: block;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--on-dark-text-soft);
  text-decoration: none;
  border-radius: 0;
  position: relative;
  transition: color var(--transition-fast);
}

/* Elegant underline animation */
.nav-link::after {
  content: '';
  position: absolute;
  bottom: 6px;
  left: var(--space-3);
  right: var(--space-3);
  height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.3s var(--ease-standard);
  border-radius: 2px;
}

.nav-link:is(:hover, :focus-visible) {
  color: var(--color-accent-text);
}
.nav-link:is(:hover, :focus-visible)::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* Active state: heller, gut lesbarer Text + persistenter ROTER Unterstrich als
   Marken-/Aktiv-Signal. Marken-Rot als TEXT erreicht auf der dunklen Navbar nur
   2.57:1 (unter AA); der rote Unterstrich trägt den Akzent (WCAG 1.4.1: nicht nur
   Farbe), der Text bleibt on-dark = klar lesbar. */
.nav-link.active {
  color: var(--on-dark-text);
}
.nav-link.active::after {
  transform: scaleX(1);
  background: var(--color-accent-light);
}

/* ── Mega-Menü (Header-Dropdown: Leistungen, Maschinenpark) ────────────
   Top-Level-Link navigiert weiter zur Übersicht; Hover/Fokus/Tap öffnet ein
   Panel mit den Einzelzielen. Flächen/Borders/Radien stammen aus der zentralen
   --menu-*-Token-Familie (Pendant zum Sprachumschalter), damit jedes Nav-Dropdown
   identisch „graphit-frosted, kantig-technisch" wirkt. */
.nav-item.has-mega {
  display: flex;
  align-items: center;
  position: relative;
}
.nav-item.has-mega > .nav-link {
  padding-right: var(--space-1);
}
/* Extend underline slightly past the link text to visually balance with the caret. */
.nav-item.has-mega > .nav-link::after {
  right: 0;
}

/* Caret-Button: separat vom Link, damit Tastatur/Touch das Panel toggeln können,
   während ein Klick auf den Text weiterhin zur Übersicht navigiert. */
.mega-caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-right: calc(-1 * var(--space-1));
  padding: 0;
  color: var(--on-dark-text-subtle);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--transition-fast), background var(--transition-fast), transform var(--transition-fast);
}
.mega-caret:hover,
.mega-caret:focus-visible {
  color: var(--color-accent-text);
  background: var(--on-dark-surface-soft);
  outline: none;
}
/* Icon-Größe IMMER über font-size steuern, NIE über width/height: die SSOT-
   Basisregel .bm-icon{width:1em;height:1em} (icons.css) bindet die Kantenlänge
   an die eigene font-size. font-size kollidiert mit keiner .bm-icon-Regel →
   kein Spezifitäts-/Ladereihenfolgen-Kampf. Das ist der vom Icon-System
   vorgesehene Hebel (siehe icons.css / content/icons.yaml). */
.mega-caret__icon {
  font-size: 26px;
  transition: transform var(--transition-base);
}
/* Geschlossen zeigt der Chevron nach UNTEN (dir="down" = rotate 90° ab der
   rechts-orientierten Basis-Glyphe). Offen zeigt er nach OBEN — das ist
   rotate(-90°), NICHT 180° (180° ergäbe „links", der alte Bug). Verhält sich
   damit exakt wie der FAQ-Akkordeon-Pfeil: zu ⌄ / offen ⌃. */
.has-mega.is-open .mega-caret__icon { transform: rotate(-90deg); }
/* Top-Level-Link färbt mit, wenn das Panel offen ist (Zustands-Feedback) */
.has-mega.is-open > .nav-link { color: var(--color-accent-text); }

/* ── Panel ── */
.mega-panel {
  /* Sichtbarkeit zentral; Positionierung je Breakpoint unten. Standard: zu. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

@media (min-width: 1024px) {
  .mega-panel {
    position: absolute;
    top: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%) translateY(-6px);
    z-index: var(--z-dropdown);
    width: min(860px, calc(100vw - 2rem));
    padding: var(--space-3);
    /* Darf NIE über den Viewport hinauslaufen: hart auf den Platz unter dem
       Header-Stack kappen; nur falls es dann noch überläuft, sanft scrollen. */
    max-height: calc(100dvh - var(--header-offset) - var(--space-6));
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--menu-surface);
    -webkit-backdrop-filter: blur(var(--blur-lg));
    backdrop-filter: blur(var(--blur-lg));
    border: 1px solid var(--menu-border);
    border-radius: var(--menu-radius);
    box-shadow: var(--menu-shadow);
    transition: opacity 180ms var(--ease-standard), transform 180ms var(--ease-standard), visibility 0s linear 180ms;
  }
  /* Mehrspaltiges Leistungs-Mega: die 10 Prozess-Gruppen balanciert über bis zu
     4 Spalten fließen lassen (CSS-Columns) statt zeilenweise 3-Spalten-Grid mit
     ausgefransten Lücken → kompakter & deutlich flacher. `flat` (Maschinenpark/
     Über-uns) bleibt einspaltig. Datengetrieben: skaliert mit der Gruppenzahl. */
  .mega-panel:not(.mega-panel--flat) .mega-grid {
    display: block;
    column-count: 4;
    column-gap: var(--space-5);
  }
  .mega-panel:not(.mega-panel--flat) .mega-col {
    break-inside: avoid;
    margin-bottom: var(--space-3);
  }
  /* Schmales Panel (flat = Maschinenpark, nur Anker-Liste) */
  .mega-panel--flat { width: min(320px, calc(100vw - 2rem)); }

  /* Reveal — EINE Quelle der Wahrheit: die .is-open-Klasse (JS steuert sie per
     Caret-Klick / Außenklick / Esc). KEIN :hover/:focus-within-Reveal mehr —
     sonst hielte :hover das Panel offen, während der 2. Klick es zu schalten
     versucht, und beides kämpft. Reines Klick-Disclosure wie der FAQ-Pfeil. */
  .has-mega.is-open > .mega-panel {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
    pointer-events: auto;
    transition: opacity 180ms var(--ease-standard), transform 180ms var(--ease-standard), visibility 0s;
  }
}

/* ── Grid + Spalten ── */
.mega-grid {
  display: grid;
  grid-template-columns: repeat(3, var(--grid-track-fluid));
  gap: var(--space-3) var(--space-5);
}
.mega-panel--flat .mega-grid { grid-template-columns: 1fr; gap: 0; }

.mega-col__title {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin: 0 0 var(--space-1);
  padding-bottom: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-accent-text);
  border-bottom: 1px solid var(--on-dark-border-faint);
}
/* Kategorie-Motiv vor dem Spalten-Titel (navigation.yaml col.icon). Bewusst
   KLEINER + DÜNNER als die Card-/USP-Icons: stroke-width überschreibt hier nur
   fürs Header das Präsentations-Attribut (SSOT default_stroke_width 1.6 bleibt
   global unberührt). Ruhezustand gedämpft in der Titelfarbe (accent-light),
   Hover über die Spalte → volles Bock-Rot. Rein optisch, keine zweite Quelle. */
.mega-col__icon {
  font-size: 1.9em;   /* Kantenlänge via .bm-icon{width:1em} = 1.9× Titelgröße */
  stroke-width: 1.2;
  align-self: center;      /* im baseline-Flex des Titels sauber mittig */
  opacity: 0.65;
  transition: opacity var(--transition-fast), color var(--transition-fast);
}
.mega-col:hover .mega-col__icon,
.mega-panel--flat .mega-col:hover .mega-col__icon {
  opacity: 1;
  color: var(--color-accent-text);
}
/* Item-Motiv der FLACHEN Dropdowns (Über uns/Maschinenpark/Karriere).
   Gleiche Doktrin wie die Spalten-Icons: dünner + gedämpft, Bock-Rot bei
   Hover/aktueller Seite. Leistungen-Items tragen bewusst kein Icon. */
.mega-link__icon {
  font-size: 1.7em;   /* Kantenlänge via .bm-icon{width:1em} = 1.7× Zeilengröße */
  stroke-width: 1.2;
  margin-right: 9px;
  opacity: 0.55;
  color: var(--menu-item-color);
  transition: opacity var(--transition-fast), color var(--transition-fast);
}
.mega-link:hover .mega-link__icon,
.mega-link.is-current .mega-link__icon {
  opacity: 1;
  color: var(--color-accent-text);
}
/* Prozess-Schritt-Nummer — SSOT aus navigation.yaml (build-berechnet). Mono +
   tabellenziffern, damit 01/02/… wie auf /leistungen/ + /maschinenpark/ wirken. */
.mega-num {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  color: var(--color-accent-text);
}
/* Item-Ebene (Maschinenpark flat): dezenter, feste Breite für saubere Flucht. */
.mega-num--sm {
  min-width: 1.6em;
  margin-right: 6px;
  font-size: var(--text-xs);
  color: var(--color-accent-text);
}
.mega-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* ── Einträge ── */
.mega-link {
  display: flex;
  align-items: center;
  padding: 5px 10px;
  border-radius: var(--menu-item-radius);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  color: var(--menu-item-color);
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast), padding-left var(--transition-fast);
}
.mega-link:hover,
.mega-link:focus-visible {
  color: var(--menu-item-hover-color);
  background: var(--menu-item-hover-bg);
  padding-left: 13px;
  outline: none;
}
/* aktuelle Detailseite: dauerhaft markiert (Akzentschrift + roter Balken).
   Der Marker ist ein Akzent-Balken GANZ LINKS am Eintrag — nicht mehr ein Punkt
   direkt vor dem Text: der saß bei left:-10px und lag damit genau auf dem
   Item-Icon der flachen Dropdowns (Über-uns/Maschinenpark/Karriere) → sah nach
   Bug aus. Der Balken sitzt am linken Rand des ganzen .mega-link, also immer
   frei von Icon und Text. */
.mega-link.is-current {
  position: relative;
  color: var(--on-dark-text);
  background: var(--menu-item-active-bg);
  font-weight: var(--font-weight-semibold);
}
.mega-link.is-current::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 3px; height: 58%;
  transform: translateY(-50%);
  border-radius: 0 3px 3px 0;
  background: var(--color-accent-light);
  box-shadow: 0 0 8px var(--color-accent-light);
}

/* ── Fuß: „Alle … ansehen" ── */
.mega-foot {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
  text-decoration: none;
  border-top: 1px solid var(--on-dark-border-faint);
  width: 100%;
  transition: gap var(--transition-fast);
}
.mega-foot svg { transition: transform var(--transition-fast); }
.mega-foot:hover svg,
.mega-foot:focus-visible svg { transform: translateX(3px); }
.mega-foot:focus-visible { outline: none; color: var(--on-dark-text); }

@media (prefers-reduced-motion: reduce) {
  .mega-panel,
  .mega-caret__icon,
  .mega-link,
  .mega-foot,
  .mega-foot svg { transition: none; }
}

/* ── Language Switch — Dropdown (champions-league) ──────────
   A disclosure (<details>) holding the full language list, so even a
   double-digit number of languages stays a compact, polished control
   instead of an overflowing flag row. Works without JS; main.js adds
   outside-click / Escape / arrow-key niceties. */
.lang-switch {
  display: flex;
  align-items: center;
  margin-left: var(--space-3);
}
.lang-dd {
  position: relative;
}

/* ── Dark-Mode-Toggle (Sonne↔Mond) — im dunklen Header, Icon on-dark in beiden
     Modi (der Nav bleibt dunkel). Sichtbarkeit sun/moon via [data-theme]; Engine
     assets/js/theme-toggle.js. Kompound-Selektoren, damit die Show/Hide-Regeln die
     später geladene components/icons.css sicher überstimmen. ── */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  margin-left: var(--space-3);
  border-radius: var(--menu-trigger-radius);
  color: var(--on-dark-text-soft);
  background: var(--menu-trigger-bg);
  border: 1px solid var(--menu-trigger-border);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.theme-toggle:hover,
.theme-toggle:focus-visible {
  color: var(--on-dark-text);
  background: var(--menu-trigger-hover-bg);
}
.theme-toggle:focus-visible {
  outline: 2px solid var(--color-accent-text);
  outline-offset: 2px;
}
.theme-toggle .theme-toggle__i { display: block; width: 1.15rem; height: 1.15rem; }
.theme-toggle .theme-toggle__moon { display: none; }
:root[data-theme="dark"] .theme-toggle .theme-toggle__sun { display: none; }
:root[data-theme="dark"] .theme-toggle .theme-toggle__moon { display: block; }

/* ── Foto-Abdunklung im Dark ─────────────────────────────────────────────────
   Helle Raster-Fotos wirken gegen die dunkle UI grell. --media-dim (SSOT: hell=none →
   zero-visual, dunkel=sanftes brightness/contrast) dämpft sie. NUR Raster: SVG (Logos/
   Flaggen/Icons) via [src$=".svg"] ausgenommen, Icon-Fonts/inline-<svg> sind kein <img>.
   Opt-out je Element mit .no-media-dim. Eigene :hover-filter (Galerie/Spec) sind spezi-
   fischer und überschreiben bewusst. ── */
:root[data-theme="dark"] :is(img:not([src$=".svg"]), video):not(.no-media-dim) {
  filter: var(--media-dim);
}

/* Shared flag chip */
.lang-flag {
  display: block;
  width: 20px;
  height: 15px;
  object-fit: cover;
  border-radius: var(--menu-flag-radius);
  flex-shrink: 0;
  box-shadow: var(--menu-flag-ring);
}

/* ── Trigger (current language) ── */
.lang-current {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px 10px;
  border-radius: var(--menu-trigger-radius);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--on-dark-text-soft);
  background: var(--menu-trigger-bg);
  border: 1px solid var(--menu-trigger-border);
  cursor: pointer;
  user-select: none;
  list-style: none;
  white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.lang-current::-webkit-details-marker { display: none; }
.lang-current::marker { content: ""; }
.lang-current:hover,
.lang-current:focus-visible {
  color: var(--on-dark-text);
  background: var(--menu-trigger-hover-bg);
  border-color: var(--menu-trigger-hover-border);
  outline: none;
}
.lang-dd[open] .lang-current {
  color: var(--color-text-inverse);
  background: var(--menu-trigger-open-bg);
  border-color: var(--menu-trigger-open-border);
}
/* Größe via font-size (SSOT-Hebel, siehe .mega-caret__icon). */
.lang-caret {
  font-size: 22px;
  transition: transform var(--transition-fast);
  opacity: 0.7;
  flex-shrink: 0;
}
/* Offen zeigt der Chevron nach OBEN — rotate(-90°) ab rechts-orientierter Basis
   (NICHT 180° = links). Identisch zum Header-Mega-Caret. */
.lang-dd[open] .lang-caret { transform: rotate(-90deg); }

/* ── Menu panel ── */
.lang-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: var(--z-dropdown);
  /* Two columns so a long language list (15+) stays fully visible at a glance
     instead of hiding the lower entries behind a scroll. Collapses to one column
     on very narrow phones (see media query below). */
  display: grid;
  grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid);
  grid-auto-rows: max-content;
  gap: 2px;
  width: min(420px, calc(100vw - 1.5rem));
  /* Safety net: cap to the viewport and scroll only if it still overflows
     (e.g. landscape phones). dvh tracks the real mobile viewport; vh is the fallback. */
  max-height: min(80vh, 620px);
  max-height: min(80dvh, 620px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
  background: var(--menu-surface);
  -webkit-backdrop-filter: blur(var(--blur-lg));
  backdrop-filter: blur(var(--blur-lg));
  border: 1px solid var(--menu-border);
  border-radius: var(--menu-radius);
  box-shadow: var(--menu-shadow);
  animation: lang-menu-in 160ms ease;
}
@keyframes lang-menu-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .lang-menu { animation: none; }
  .lang-caret { transition: none; }
}

/* ── Menu items ── */
.lang-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px var(--space-3);
  border-radius: var(--menu-item-radius);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  color: var(--menu-item-color);
  transition: background var(--transition-fast), color var(--transition-fast);
}
a.lang-option:hover,
a.lang-option:focus-visible {
  color: var(--menu-item-hover-color);
  background: var(--menu-item-hover-bg);
  outline: none;
}
.lang-option-flags {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex-shrink: 0;
}
.lang-option-name {
  flex: 1 1 auto;
  white-space: nowrap;
}
.lang-option--active {
  color: var(--color-text-inverse);
  background: var(--menu-item-active-bg);
  font-weight: var(--font-weight-semibold);
  cursor: default;
}
.lang-check {
  color: var(--color-accent-text);
  flex-shrink: 0;
}

/* Below 1024px the nav collapses to the hamburger, so the language trigger sits
   mid-header — NOT at the right edge. A trigger-anchored (absolute; right:0) wide
   menu would then run off the LEFT screen edge. Re-anchor the panel to the VIEWPORT:
   fixed, right-aligned with a screen margin, just under the fixed header, capped
   width — so it can never overflow regardless of where the trigger sits. */
@media (max-width: 1023px) {
  /* The desktop nav-links carried `margin-left:auto`; below 1024px it becomes a
     fixed overlay and leaves the flow, so nothing pushes the remaining header
     items apart. Re-introduce the auto-margin on the language switch so logo
     sits left and lang-switch + hamburger ride the right edge — full width used,
     and the trigger now sits directly above its right-anchored menu. */
  .lang-switch {
    margin-left: auto;
  }
  /* Touch-Ziel (Gegenstück zum Geometrie-Block oben bei .logo-img): 34px lagen
     unter der 40px-Daumenmarke. Steht bewusst HIER, hinter den Basisregeln von
     .theme-toggle/.lang-current — ein Media-Query erhöht die Spezifität nicht,
     weiter oben hätte die spätere Basisregel (width:34px) gewonnen. */
  .theme-toggle { width: 40px; height: 40px; margin-left: var(--space-1); }
  .lang-current { min-height: 40px; }
  /* Symmetrisch am Viewport statt am Trigger: gleicher Rand links wie rechts,
     volle nutzbare Breite. `left` + `right` statt `right` + fester `width` —
     so ist der Rand per Konstruktion gleich, egal wie breit der Schirm ist. */
  .lang-menu {
    position: fixed;
    top: calc(var(--header-offset) + 8px);
    left: var(--space-3);
    right: var(--space-3);
    width: auto;
    padding: var(--space-2);
    grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid);
    max-height: min(80dvh, calc(100dvh - var(--header-offset) - 1.5rem));
  }
  /* Auf Mobil ist jede Zeile ein Touch-Ziel, kein Hover-Ziel: 44px Mindesthöhe
     (Apple/Android-Daumenmaß) statt der ~35px, die aus Desktop-Padding fielen —
     20 Sprachen in zwei Spalten waren sonst ein Trefferspiel. Flaggen dürfen
     mitwachsen: 24×18 statt 20×15 ist auf Telefonabstand erst unterscheidbar. */
  .lang-option {
    min-height: 44px;
    padding: var(--space-2) var(--space-3);
  }
  .lang-menu .lang-flag { width: 24px; height: 18px; }
}

/* On small mobile: trim the trigger label, keep flag + caret + compact rows. */
@media (max-width: 480px) {
  .lang-current-label { display: none; }
  .lang-current { padding: 6px 8px; gap: 6px; }
  .lang-option { padding: var(--space-2) var(--space-2); gap: var(--space-2); }
}

/* Ultra-narrow phones (<340px): two columns would get cramped → single column.
   Breite bleibt viewport-symmetrisch (left/right aus dem ≤1023px-Block) — nur
   die Spaltenzahl fällt, damit lange Endonyme („Slovenščina") nicht umbrechen. */
@media (max-width: 340px) {
  .lang-menu {
    grid-template-columns: 1fr;
  }
}

/* ── Hamburger Toggle Button ────────────────────────────── */
.nav-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  margin-left: var(--space-2);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  flex-shrink: 0;
  transition: background var(--transition-fast);
}
.nav-toggle:hover { background: var(--on-dark-surface); }
@media (min-width: 1024px) {
  .nav-toggle { display: none; }
}

.toggle-bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--on-dark-text);
  border-radius: 2px;
  transform-origin: center;
  transition:
    transform 0.42s cubic-bezier(0.23, 1, 0.32, 1),
    opacity   0.28s ease,
    width     0.28s ease;
}
/* Stagger closing (base → hamburger) */
.toggle-bar:nth-child(1) { transition-delay: 0s; }
.toggle-bar:nth-child(2) { transition-delay: 0.06s; }
.toggle-bar:nth-child(3) { transition-delay: 0.12s; }

/* Morphed X state (opening stagger reversed) */
.nav-toggle[aria-expanded="true"] .toggle-bar:nth-child(1) {
  transform: translateY(8px) rotate(45deg);
  transition-delay: 0.06s;
}
.nav-toggle[aria-expanded="true"] .toggle-bar:nth-child(2) {
  opacity: 0;
  width: 0;
  transition-delay: 0s;
}
.nav-toggle[aria-expanded="true"] .toggle-bar:nth-child(3) {
  transform: translateY(-8px) rotate(-45deg);
  transition-delay: 0.12s;
}

/* ── Mobile Menu Backdrop (click-to-close overlay) ────────── */
.nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--scrim-overlay-strong);
  backdrop-filter: blur(var(--blur-sm));
  -webkit-backdrop-filter: blur(var(--blur-sm));
  z-index: calc(var(--z-nav) - 2); /* nav-backdrop: below menu and navbar */
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.nav-backdrop.is-active {
  display: block;
  opacity: 1;
  pointer-events: auto;
}

/* ── Mobile Menu – Dropdown Overlay (Nike-style) ──────────── */
@media (max-width: 1023px) {
  .nav-links {
    /* Override: always in DOM for smooth animation */
    display: flex !important;
    flex-direction: column;
    align-items: flex-start;
    position: fixed;
    top: var(--header-offset);
    left: 0;
    right: 0;
    z-index: calc(var(--z-nav) - 1); /* mobile menu: above backdrop, below navbar */
    padding: var(--space-6) var(--space-6) var(--space-8);
    gap: var(--space-2);
    margin-left: 0;
    /* An den ECHTEN sichtbaren Viewport koppeln (dvh), nicht an den statischen
       100vh-Large-Viewport — sonst reicht das Menü hinter die Mobile-Browser-
       Leiste und der untere Teil wird abgeschnitten. vh bleibt als Fallback. */
    max-height: calc(100vh - var(--header-offset));
    max-height: calc(100dvh - var(--header-offset));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    background: rgb(var(--c-scrim) / 0.98);
    backdrop-filter: blur(var(--blur-xl));
    -webkit-backdrop-filter: blur(var(--blur-xl));
    box-shadow: 0 10px 40px rgb(var(--c-black) / 0.3);
    /* Hidden state: scaled down + invisible */
    visibility: hidden;
    opacity: 0;
    transform: translateY(-20px) scale(0.96);
    transform-origin: top center;
    pointer-events: none;
    transition:
      visibility 0s linear 0.35s,
      opacity    0.35s var(--ease-standard),
      transform  0.35s var(--ease-standard);
  }
  .nav-links.is-open {
    visibility: visible;
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
    transition:
      visibility 0s linear 0s,
      opacity    0.35s var(--ease-standard),
      transform  0.35s cubic-bezier(0.23, 1, 0.32, 1); /* Spring easing */
  }

  /* Nav items: slide in from left with stagger */
  .nav-links li {
    opacity: 0;
    transform: translateX(-32px);
    transition:
      opacity   0.32s ease,
      transform 0.32s var(--ease-standard);
    transition-delay: 0s; /* Reset when closing */
  }
  .nav-links.is-open li {
    opacity: 1;
    transform: translateX(0);
  }
  .nav-links.is-open li:nth-child(1) { transition-delay: 0.06s; }
  .nav-links.is-open li:nth-child(2) { transition-delay: 0.10s; }
  .nav-links.is-open li:nth-child(3) { transition-delay: 0.14s; }
  .nav-links.is-open li:nth-child(4) { transition-delay: 0.18s; }
  .nav-links.is-open li:nth-child(5) { transition-delay: 0.22s; }
  .nav-links.is-open li:nth-child(6) { transition-delay: 0.26s; }

  /* Big bold nav links in overlay */
  .nav-links .nav-link {
    font-size: clamp(1.25rem, 5vw, 1.75rem);
    font-weight: var(--font-weight-bold);
    padding: var(--space-3) var(--space-2);
    color: var(--on-dark-text-high);
    border-bottom: 1px solid var(--on-dark-border-faint);
    width: 100%;
    border-radius: 0;
    letter-spacing: var(--tracking-tight);
    position: relative;
    transition: color 0.25s ease, border-color 0.25s ease, padding-left 0.25s var(--ease-standard);
  }
  .nav-links .nav-link::after {
    /* No underline in mobile — border-bottom is the indicator */
    display: none;
  }
  .nav-links .nav-link:is(:hover, :focus-visible) {
    color: var(--color-accent-text);
    background: transparent;
    border-bottom-color: var(--color-accent-light);
    padding-left: var(--space-3); /* Subtle slide-in */
  }
  .nav-links .nav-link.active {
    color: var(--color-accent-text);
    border-bottom-color: var(--color-accent-light);
    border-bottom-width: 2px;
    padding-left: var(--space-3);
  }
  /* Active state dot indicator */
  .nav-links .nav-link.active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 4px;
    background: var(--color-accent-light);
    border-radius: 50%;
    box-shadow: 0 0 8px var(--color-accent-light);
  }
}

/* Prevent body scroll while mobile menu is open */
body.nav-open { overflow: hidden; }

/* ── Mega-Menü im Mobile-Overlay → Akkordeon ──────────────── */
@media (max-width: 1023px) {
  .nav-item.has-mega {
    flex-wrap: wrap;
    width: 100%;
    border-bottom: 1px solid var(--on-dark-border-faint);
  }
  /* Der Punkt-Link trägt im Overlay keine eigene Trennlinie mehr (das <li> tut es),
     und teilt sich die Zeile mit dem Caret. */
  .nav-item.has-mega > .nav-link {
    flex: 1 1 auto;
    width: auto;
    border-bottom: 0;
  }
  .nav-item.has-mega .mega-caret {
    width: 52px;
    height: 52px;
    margin: 0;
    color: var(--on-dark-text-muted);
    flex-shrink: 0;
  }

  /* Panel klappt per max-height auf/zu; visibility verzögert geschaltet, damit
     zusammengeklappte Links nicht per Tab fokussierbar sind. */
  .mega-panel {
    position: static;
    transform: none;
    width: 100%;
    flex-basis: 100%;
    overflow: hidden;
    max-height: 0;
    opacity: 1;
    visibility: hidden;
    pointer-events: none;
    transition: max-height 0.34s var(--ease-standard), visibility 0s linear 0.34s;
  }
  .has-mega.is-open > .mega-panel {
    max-height: 1600px;
    visibility: visible;
    pointer-events: auto;
    transition: max-height 0.40s var(--ease-standard), visibility 0s linear 0s;
  }
  .mega-grid {
    grid-template-columns: 1fr;
    gap: var(--space-2);
    padding: var(--space-1) 0 var(--space-3) var(--space-4);
  }
  .mega-col__title {
    margin-bottom: var(--space-1);
    border-bottom: 0;
    padding-bottom: 0;
  }
  .mega-link {
    font-size: var(--text-sm);
    padding: 6px 10px;
  }
  .mega-foot {
    margin: 0 0 var(--space-4) var(--space-4);
    padding-top: var(--space-2);
    border-top: 0;
    width: auto;
  }
  @media (prefers-reduced-motion: reduce) {
    .mega-panel { transition: visibility 0s; }
  }
}

/* ── Hero ─────────────────────────────────────────────────── */
.hero {
  position: relative;
  /* Body reserviert bereits die Header-Stack-Höhe → der Hero füllt exakt den
     REST des Viewports darunter (kein Überlauf, kein Überdecken durch die Leiste). */
  height: calc(100svh - var(--header-offset));
  min-height: var(--hero-min-height);
  display: flex;
  align-items: center;
  overflow: hidden;
}

/* ── Hero Media: Poster-Bild + Video-Background (SSOT) ─────── */
/* Eine Architektur für BEIDE Hero-Typen (homepage .hero UND subpage
   .page-hero), gerendert vom hero_video()-Macro aus content/videos.yaml:
   - poster (<img class="bm-hero-poster">) ist IMMER sichtbar → LCP-Kandidat.
   - video (<video class="bm-hero-video js-lazy-video">) legt sich drüber,
     sobald es abspielt. Bytes laden erst per JS (data-src → src).
   Mobile-Strategie zentral je Video über `mobile: video|poster`:
     video  → auch auf Mobil (Standard); Smart-Fallback auf Poster bei
              Save-Data / langsamem Netz / reduced-motion (im JS) → 0
              Video-Bytes für eingeschränkte Geräte.
     poster → .bm-hero-video--mobile-off → Video <768px komplett aus. */
.hero-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
}

/* Shared hero-media primitives — genutzt von .hero UND .page-hero.
   Der Poster ist ein <picture> (picture_html_v2 → AVIF/WebP/responsive + alt),
   das Video legt sich beim Abspielen mit Crossfade darüber. */
.bm-hero-poster {                 /* das <picture>-Element */
  position: absolute;
  inset: 0;
  display: block;
  z-index: 0;
}
.bm-hero-poster img,
.bm-hero-poster-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.bm-hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 1;
  opacity: 0;
  transition: opacity var(--hero-video-fade) ease;
  will-change: opacity;
}
.bm-hero-video.is-playing { opacity: 1; }

/* Neutraler Marken-Hintergrund hinter JEDEM Video-Hero. Bei Vollbild-Crop
   (object-fit:cover) komplett verdeckt → 0 Effekt; sichtbar nur dort, wo das
   Video sein Seitenverhältnis hält (Pillarbox bei Hochformat / Letterbox auf
   Mobil). Zentral via --hero-media-backdrop (variables.css). */
.hero-bg,
.page-hero-bg--video { background: var(--hero-media-backdrop); }
/* Hochformat-Fit (contain/Pillarbox) wird im gestackten Desktop-Block weiter
   unten gesetzt; auf Mobil füllt das Band ohnehin das eigene Seitenverhältnis. */

/* Homepage-Poster Fokuspunkt (token-gesteuert) */
.hero-poster img { object-position: var(--hero-poster-position); }

/* Accessible Pause/Play-Control (WCAG 2.2.2). 44×44 Touch-Target, über dem
   Overlay (z-index), unten rechts. Icon wechselt per data-state (JS). */
.bm-hero-pause {
  position: absolute;
  bottom: var(--space-4);
  right: var(--space-4);
  z-index: 4;
  width: var(--hero-control-size);
  height: var(--hero-control-size);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--scrim-overlay);
  color: var(--on-dark-text);
  cursor: pointer;
  -webkit-backdrop-filter: blur(var(--blur-sm));
  backdrop-filter: blur(var(--blur-sm));
  transition: background 0.2s ease, opacity 0.2s ease;
}
.bm-hero-pause:hover { background: var(--scrim-control-hover); }
.bm-hero-pause:focus-visible { outline: 2px solid var(--on-dark-text); outline-offset: 2px; }
.bm-hero-pause__icon { width: 22px; height: 22px; fill: currentColor; }
/* Default (pausiert / noch nicht gestartet) → Play-Icon; spielt → Pause-Icon.
   Descendant-Selektor (0,2,0) ist Pflicht: components/icons.css laedt NACH
   main.css und setzt .bm-icon{display:inline-block} (0,1,0). Ein flaches
   .bm-hero-pause__pause{display:none} (auch 0,1,0) verloere den Tie auf
   Quell-Reihenfolge → beide Icons sichtbar. Die [data-state="playing"]-Regeln
   unten sind bereits (0,2,0); diese zwei muessen es spiegeln. */
.bm-hero-pause .bm-hero-pause__pause { display: none; }
.bm-hero-pause .bm-hero-pause__play { display: block; }
.bm-hero-pause[data-state="playing"] .bm-hero-pause__pause { display: block; }
.bm-hero-pause[data-state="playing"] .bm-hero-pause__play { display: none; }
/* Kein JS / reduced-motion: ohne data-state ist nur das Play-Icon sichtbar; der
   Button bleibt nutzbar (lädt das Video on demand). */
@media (prefers-reduced-motion: reduce) {
  .bm-hero-pause { opacity: 0.85; }
}

/* ── Cursor-folgender Pause-Button (NUR Desktop, via JS aktiviert) ─────────
   Auf Desktop „hängt" der Pause-Button am Mauszeiger: man kann an JEDER Stelle
   der Hero-Fläche pausieren. JS (main.js) setzt --bm-pause-x/y (Position im
   Hero, rAF-gedrosselt) und togglet den Klick flächenweit; der Button selbst ist
   pointer-events:none, damit er Links/CTAs nie blockiert.
   PERFORMANCE: Position läuft über GPU-`transform` (compositor-only, KEIN Layout-
   Reflow) → kein Lag. Nur die Sichtbarkeit (opacity) wird weich überblendet.
   Über echten Buttons/Links blendet das JS den Button per `.is-visible` ganz aus. */
.bm-hero-pause--follow {
  left: 0;
  top: 0;
  right: auto;
  bottom: auto;
  transform: translate3d(calc(var(--bm-pause-x, 0px) - 50%), calc(var(--bm-pause-y, 0px) - 50%), 0);
  pointer-events: none;          /* Klick geht durch → main.js togglet flächig */
  opacity: 0;
  z-index: var(--z-overlay); /* schwebt über Text & Overlay */
  transition: opacity 0.15s ease;
  will-change: transform;
}
.bm-hero-pause--follow.is-visible { opacity: 1; }
/* Tastatur-Fokus ohne Maus: zurück in die statische Ecke unten rechts (A11y). */
.bm-hero-pause--follow:focus-visible:not(.is-visible) {
  left: auto;
  top: auto;
  right: var(--space-4);
  bottom: var(--space-4);
  transform: none;
  opacity: 1;
}

/* ── Hero Text-Schutz über Video (zentral via variables.css) ──────────────
   Farbwechselnde Videos machen weißen Text oft unlesbar. Lösung (alles über
   Tokens steuerbar, reines CSS = 0 PageSpeed-Kosten):
   1) stärkerer Scrim NUR bei Video-Heroes, 2) Textschatten. */
.hero-title, .hero-subtitle,
.page-hero-title, .page-hero-subtitle { text-shadow: var(--hero-text-shadow); }

/* Startseite .hero ist immer Video; Subpages nur mit .page-hero--video. */
.hero .hero-overlay,
.page-hero--video .page-hero-overlay { background: var(--hero-scrim); }

/* Smart Mobile Fallback (spiegelt das JS-Gate in main.js):
   poster-only je Video → Video <768px und bei reduced-data aus.
   reduced-motion → bewegter Hero NIE (Poster bleibt) für ALLE Videos. */
@media (max-width: 767px) {
  .bm-hero-video--mobile-off { display: none !important; }
}
@media (prefers-reduced-data: reduce) {
  .bm-hero-video--mobile-off { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .bm-hero-video { display: none !important; }
}

/* Mobil/Tablet GESTACKTER Video-Hero (≤1024px): siehe Block NACH den
   .page-hero-Basisregeln (bewusst dort platziert, damit er per Source-Order
   sowohl .hero als auch .page-hero überschreibt — gleiche Spezifität). */

/* Legacy: hero-slider bleibt im CSS (andere Seiten) */
.hero-slider {
  position: absolute;
  inset: 0;
}
.hero-slide {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.hero-slide.active { opacity: 1; }

.hero-overlay {
  position: absolute;
  inset: 0;
  background: var(--media-hero-overlay);
  z-index: 1;
}

.hero-content {
  position: relative;
  z-index: 2;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--space-6);
  width: 100%;
}
@media (min-width: 768px) { .hero-content { padding: 0 var(--space-8); } }
@media (min-width: 1280px) { .hero-content { padding: 0 var(--space-12); } }

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--on-dark-surface-glass);
  backdrop-filter: blur(var(--blur-md));
  border: 1px solid var(--on-dark-border-strong);
  border-radius: var(--badge-radius);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--on-dark-text-high);
  margin-bottom: var(--space-6);
}
.badge-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--color-accent);
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.7; transform: scale(1.3); }
}

.hero-title {
  font-family: var(--font-display);
  font-size: clamp(var(--text-4xl), 7vw, var(--text-7xl));
  font-weight: var(--font-weight-black);
  line-height: var(--leading-tight);
  color: var(--on-dark-text);
  margin-bottom: var(--space-6);
  letter-spacing: var(--tracking-tight);
}
.text-highlight {
  color: var(--color-accent-text);
  position: relative;
}

.hero-subtitle {
  font-size: clamp(var(--text-base), 2vw, var(--text-xl));
  color: var(--on-dark-text-soft);
  line-height: var(--leading-relaxed);
  max-width: 640px;
  margin-bottom: var(--space-8);
}

.hero-stats {
  display: flex;
  gap: var(--space-8);
  margin-bottom: var(--space-10);
  flex-wrap: wrap;
}
.hero-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.stat-value {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: var(--font-weight-black);
  color: var(--on-dark-text);
  line-height: 1;
}
.stat-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--on-dark-text-subtle);
}

/* ── Home-Hero Conversion-Layout (Lead + Trust-Panel) ─────────────────────
   HYBRID: .hero-lead trägt die Conversion-Essentials (Badge + kurze H1 + die
   zwei CTAs). Auf Mobil unter dem Video gestackt; auf Desktop als minimaler
   Overlay UNTEN im Video-Banner (klassischer Hero-Look). .hero-trust = Nutzen-
   Subtitle + Kennzahlen, IMMER als ruhiges Panel unter dem Video.
   Primär-CTA = „Projekt anfragen" (Geld-Aktion), Sekundär = Leistungen. */
.hero-lead {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-10) var(--space-6) 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-6);
}
.hero-lead .hero-badge { margin-bottom: 0; }
.hero-lead .hero-title { margin-bottom: 0; }
.hero-trust .hero-subtitle { margin-bottom: var(--space-8); }
.hero-trust .hero-stats { margin-bottom: 0; }
@media (min-width: 768px) {
  .hero-lead { padding-left: var(--space-8); padding-right: var(--space-8); }
}
@media (min-width: 1280px) {
  .hero-lead { padding-left: var(--space-12); padding-right: var(--space-12); }
}

/* Desktop: Lead als Overlay unten im „Cinematic Banner". Full-width Scrim am
   Bandboden (über .hero-bg::after) sichert Lesbarkeit über dem farbwechselnden
   Video; der Lead bleibt pointer-events:none, damit die Cursor-Pause auf dem
   Video aktiv bleibt — nur Badge/H1/CTAs sind wieder klickbar. */
@media (min-width: 1025px) {
  .hero-bg::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 72%;
    background: linear-gradient(
      to top,
      rgb(var(--c-shadow-deep) / 0.82) 0%,
      rgb(var(--c-shadow-deep) / 0.42) 36%,
      rgb(var(--c-shadow-deep) / 0) 72%);
    pointer-events: none;
    z-index: 2;
  }
  .hero-lead {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: var(--hero-band-height);
    justify-content: flex-end;
    padding-top: var(--space-12);
    padding-bottom: var(--space-12);
    pointer-events: none;
  }
  .hero-lead > * { pointer-events: auto; }
}

.hero-dots {
  position: absolute;
  bottom: var(--space-8);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--space-2);
  z-index: 3;
}
.hero-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--on-dark-text-faint);
  transition: all var(--transition-base);
}
.hero-dot.active {
  background: var(--color-accent);
  width: 24px;
  border-radius: 4px;
}

/* ── Scroll-to-top Button ─────────────────────────────────── */
.scroll-to-top {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: calc(var(--z-toast) - 1); /* scroll-to-top: above content/modal, below toasts */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  min-width: 3.5rem;
  min-height: 3.5rem;
  padding: 0 !important;
  font-size: 0;
  line-height: 1;
  box-sizing: border-box;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(20px);
  transition:
    opacity 0.3s ease,
    transform 0.3s ease,
    visibility 0.3s ease;
  /* Roter Chevron: der Button traegt font-size:0 (Whitespace killen), also
     bekommt das Icon seine Groesse per rem (Regel unten) und seine Farbe
     hier. currentColor faerbt den stroke-Chevron rot. */
  color: var(--color-accent-text);
}
/* Groesse MUSS .bm-icon{width:1em} aus icons.css schlagen (laedt spaeter,
   und 1em == 0 wegen font-size:0 → Icon sonst unsichtbar). Zwei Klassen
   → hoehere Spezifitaet, gewinnt zuverlaessig. */
.scroll-to-top .scroll-to-top__icon {
  display: block;
  width: 1.35rem;
  height: 1.35rem;
  flex: 0 0 auto;
  overflow: visible;
}
.scroll-to-top--visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
@media (max-width: 768px) {
  .scroll-to-top {
    right: 1rem;
    bottom: 4.5rem;
  }
}

/* ── Services Grid ────────────────────────────────────────── */
.services-grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}
/* minmax(0,…) statt 1fr: Tracks dürfen UNTER ihre Content-min-width schrumpfen,
   sonst sprengen lange Wörter / nowrap-CTAs (je nach Sprache) das Grid nach rechts. */
@media (min-width: 640px) { .services-grid { grid-template-columns: repeat(2, var(--grid-track-fluid)); } }
@media (min-width: 1024px) { .services-grid { grid-template-columns: repeat(4, var(--grid-track-fluid)); } }

.service-card {
  display: flex;
  flex-direction: column;
  min-width: 0;                 /* darf im Grid schrumpfen → kein Rechts-Überlauf */
  background-color: var(--color-bg);
  /* konstruktive Akzent-Linie oben: ruht unsichtbar, fährt bei Hover rot von links auf */
  background-image: linear-gradient(90deg, var(--color-accent), var(--color-accent-light));
  background-repeat: no-repeat;
  background-position: top left;
  background-size: 0% 2px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  transition:
    transform var(--transition-base),
    box-shadow var(--glow-speed) var(--glow-ease),
    border-color var(--glow-speed) var(--glow-ease),
    background-size var(--glow-speed) var(--glow-ease),
    background-color var(--glow-speed) var(--glow-ease);
  box-shadow: var(--shadow-sm);
}
.service-card:has(a.service-card-link[href]:not(.service-card-link--disabled)):is(:hover, :focus-within) {
  /* Lift + Glow zentral (Interactive Card System / @media hover). */
  border-color: var(--card-border-hover);
  background-size: 100% 2px;     /* Akzent-Linie voll ausgefahren */
}

/* Laufende Spec-Nummer (01–04) als technischer Index — als Eyebrow ÜBER dem
   Titel (Normalfluss, daher robust gegen die position:relative-Kind-Regel des
   Interactive Card System). Industrieller Spec-Sheet-Charakter. */
.services-grid { counter-reset: svc-card; }
.service-card { counter-increment: svc-card; }
.service-card-title::before {
  content: counter(svc-card, decimal-leading-zero);
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-widest);
  color: var(--color-border);
  margin-bottom: var(--space-1);
  transition: color var(--glow-speed) var(--glow-ease);
}
.service-card:is(:hover, :focus-within) .service-card-title::before {
  color: var(--color-accent-text);
}

.service-card-icon {
  position: relative;
  width: 56px; height: 56px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-light));
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-2xl);
  color: var(--color-text-inverse);
  margin-bottom: var(--space-5);
  box-shadow: 0 6px 18px rgb(var(--c-red) / 0.22);
  transition: transform var(--glow-speed) var(--glow-ease), box-shadow var(--glow-speed) var(--glow-ease);
}
.service-card:is(:hover, :focus-within) .service-card-icon {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 10px 26px rgb(var(--c-red) / 0.30);
}
.service-card-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin-bottom: var(--space-3);
  overflow-wrap: break-word;
  -webkit-hyphens: auto;       /* Safari < 17 */
  hyphens: auto;               /* lange Komposita umbrechen statt überlaufen */
}
.service-card-text {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  line-height: var(--leading-relaxed);
  margin-bottom: var(--space-6);
  overflow-wrap: break-word;
  -webkit-hyphens: auto;       /* Safari < 17 */
  hyphens: auto;
}
/* ── Machinery Grid ───────────────────────────────────────── */
.machinery-grid {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
}
@media (min-width: 768px) { .machinery-grid { grid-template-columns: repeat(2, var(--grid-track-fluid)); } }
@media (min-width: 1024px) { .machinery-grid { grid-template-columns: repeat(3, var(--grid-track-fluid)); } }

.machinery-card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  transition: all var(--transition-base);
}
/* machinery-card hover: Lift + Glow + Bild-Zoom zentral (Interactive Card System). */
.machinery-card-img img {
  width: 100%;
  aspect-ratio: 3/2;
  object-fit: cover;
}
.machinery-card-body {
  padding: var(--space-6);
}
.machinery-card-body h3 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  margin-bottom: var(--space-3);
}
.machinery-card-body p {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  line-height: var(--leading-relaxed);
}
.spec-list {
  list-style: none;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.spec-list li { display: flex; gap: var(--space-2); }
.spec-list strong { color: var(--color-text); min-width: 160px; flex-shrink: 0; }


/* ── Jobs List (Karriere) ─────────────────────────────────── */
.jobs-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-12);
}
.job-card {
  position: relative;
  isolation: isolate;
  background: var(--on-dark-surface-soft);
  border: 1px solid var(--on-dark-border-soft);
  border-radius: var(--radius-xl);
  padding: var(--space-6) var(--space-8);
  transition: all var(--transition-base);
}
.job-card {
  cursor: pointer;
}
.job-card:is(:hover, :focus-within) {
  background: var(--on-dark-surface);
  /* Lift + Glow zentral (Interactive Card System / @media hover). */
}
.job-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
  flex-wrap: wrap;
}
.job-title { font-family: var(--font-display); font-size: var(--text-xl); font-weight: var(--font-weight-bold); color: var(--on-dark-text); margin-bottom: var(--space-2); }
.job-meta { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.job-meta span { font-size: var(--text-sm); color: var(--color-gray-400); display: flex; align-items: center; gap: var(--space-2); }
.job-desc { font-size: var(--text-sm); color: var(--color-gray-400); line-height: var(--leading-relaxed); }
.jobs-open-application {
  margin-top: var(--space-10);
  background: rgb(var(--c-ember) / 0.15);
  border: 1px solid rgb(var(--c-ember) / 0.3);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  text-align: center;
}
@media (min-width: 768px) {
  .jobs-open-application {
    margin-top: var(--space-14);
  }
}
.jobs-open-application h3 { color: var(--color-text-inverse); font-size: var(--text-2xl); font-weight: var(--font-weight-bold); margin-bottom: var(--space-2); }
.jobs-open-application p { color: var(--color-text-muted); margin-bottom: var(--space-6); }

/* ── Evergreen: definierte, aktuell nicht ausgeschriebene Berufe ──────────────
   Bleiben als Seiten online & indexiert (SEO) und hier intern verlinkt (kein Orphan),
   ohne als aktuelle Ausschreibung dargestellt zu werden. */
/* Open-roles quick-jump tags above the carousel — same pill component as the
   not-open list below, just spaced from the section header/badge. SSOT reuse. */
.jobs-openlist { margin-top: var(--space-8); }
.jobs-evergreen { margin-top: var(--space-10); text-align: center; }
.jobs-evergreen-title { color: var(--color-text-inverse); font-size: var(--text-xl); font-weight: var(--font-weight-bold); margin-bottom: var(--space-2); }
.jobs-evergreen-lead { color: var(--color-text-muted); margin-bottom: var(--space-5); }
.jobs-evergreen-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center;
}
.jobs-evergreen-list a {
  display: inline-block;
  padding: var(--space-2) var(--space-4);
  border: 1px solid rgb(var(--c-ember) / 0.3);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.jobs-evergreen-list a:hover,
.jobs-evergreen-list a:focus-visible {
  color: var(--color-text-inverse);
  border-color: rgb(var(--c-ember) / 0.6);
  background: rgb(var(--c-ember) / 0.12);
}

/* ── Image-capable job card modifier ─────────────────────── */
.job-card--with-image { padding: 0; overflow: hidden; }
.job-card-img { overflow: hidden; }
.job-card-img picture,
.job-card-img img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
/* Bild-Zoom zentral (Interactive Card System / var(--card-img-zoom)). */
.job-card-body { padding: var(--space-6) var(--space-8); }
.job-card-type {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent-text);
  margin-bottom: var(--space-2);
}
/* Job detail meta row */
.job-detail-meta { display: flex; flex-direction: column; gap: var(--space-3); }
.job-meta-item { display: flex; align-items: center; gap: var(--space-2); color: var(--color-text-muted); }
.job-meta-item i { color: var(--color-accent-text); width: 1.1em; }
/* Read-only form field (position display) */
.form-readonly {
  background: var(--color-gray-800);
  cursor: default;
  user-select: none;
  color: var(--color-gray-200);
}


/* ── Check-list two-column variant ───────────────────────── */
.check-list--cols {
  columns: 2;
  column-gap: var(--space-10);
}
@media (max-width: 640px) {
  .check-list--cols { columns: 1; }
}

/* ── Regional location box (job detail pages) ─────────────── */
.job-location-box {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  background: var(--color-gray-100);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  margin: var(--space-5) 0;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
.job-location-box i { color: var(--color-accent-text); margin-top: 0.15em; flex-shrink: 0; }
.job-location-box strong { color: var(--color-text); }

/* ── Compensation note (neutral salary disclaimer on job detail pages) ── */
.compensation-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-style: italic;
  margin-top: var(--space-3);
  line-height: var(--leading-normal);
}
.compensation-note i { color: var(--color-text-light); flex-shrink: 0; margin-top: 0.18em; }

/* ── Conversion box (above application form) ──────────────────────────────
   Champions-League-CTA vor dem Bewerbungsformular — einladend, KEIN Alarm-Look.
   Schwebendes helles Panel (weiche Tiefe via --shadow-lg) mit dezentem Akzent-
   Schimmer in der Ecke, kräftigem Akzent-Gradient-Icon-Chip (weißes Icon) und
   klarer Typo-Hierarchie (Display-Headline). Alle Werte über zentrale Tokens
   (SSOT) — Farb-Schimmer via --c-ember-Kanal, Schatten via --shadow-*. */
.conversion-box {
  padding: var(--space-10) 0;
}
.conversion-box-inner {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
  padding: var(--space-7) var(--space-8);
  background:
    radial-gradient(130% 150% at 0% 0%, rgb(var(--c-ember) / 0.06), transparent 55%),
    var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-lg);
}
/* Icon-Chip — kräftiger Akzent-Gradient (weißes Icon), gleiche Gradient-Bildsprache
   wie andere Akzent-Flächen der Seite. */
.conversion-box-icon {
  flex-shrink: 0;
  width: var(--space-16);
  height: var(--space-16);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-light));
  color: var(--color-text-inverse);
  font-size: var(--text-2xl);
}
.conversion-box-text {
  flex: 1;
  min-width: 240px;
  color: var(--color-text-muted);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}
.conversion-box-text strong {
  color: var(--color-text);
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
}
.conversion-box .btn { flex-shrink: 0; }
@media (max-width: 640px) {
  .conversion-box-inner {
    flex-direction: column;
    align-items: flex-start;
    padding: var(--space-6);
  }
}

/* ── Status-Tag (SSOT) ────────────────────────────────────────────────────
   EIN wiederverwendbares Job-Status-Chip: grün 'Offene Stelle' vs. neutral-grau
   'Aktuell nicht ausgeschrieben'. Quelle ist immer job.open (open_positions.yaml,
   SSOT). Verwendet zentrale Tokens: theme-unabhängiges --color-success* + Neutral-
   Tokens + --badge-radius. Genutzt via Makro job_status_tag() auf Hub-Carousel-
   Karten, Ausbildung-Cards und in der Sticky-Bewerben-Leiste. Helle Chips, damit
   sie sowohl auf hellen Karten als auch über dunklen Karussell-Bildern lesen. */
.status-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--tracking-wide);
  line-height: 1;
  padding: 0.34rem 0.62rem;
  border-radius: var(--badge-radius);
  border: 1px solid transparent;
  white-space: nowrap;
}
.status-tag__dot {
  width: 0.48rem;
  height: 0.48rem;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
/* OFFEN: dezentes Mint-Grün (wie ursprünglich) — der pochende Punkt (geteilter
   badge-pulse-Keyframe, SSOT) bringt die Aufmerksamkeit, nicht die Flächenfarbe. */
.status-tag--open {
  color: var(--color-success-dark);
  background: var(--color-success-bg);
  border-color: var(--color-success-border);
}
.status-tag--open .status-tag__dot {
  background: var(--color-success);
  --pulse-ring: rgb(var(--c-success) / 0.5);
  box-shadow: 0 0 0 0 var(--pulse-ring);
  animation: badge-pulse 2.4s ease-out infinite;
}
.status-tag--closed {
  color: var(--color-gray-600); /* AA-sicher auf --color-bg-alt (~6.9:1), bleibt neutral-grau */
  background: var(--color-bg-alt);
  border-color: var(--color-border);
}
@media (prefers-reduced-motion: reduce) {
  .status-tag--open .status-tag__dot { animation: none; }
}
/* Overlay-Variante: Eck-Ribbon über einem Kartenbild (relative Elternfläche).
   Über Bildern ist der Untergrund unbekannt (blau/schwarz/weiß) — deshalb bringt
   das Overlay seine EIGENE deckende Fläche mit, statt die halbtransparente
   Chip-Fläche der Basisvariante durchscheinen zu lassen. Deckendes Surface-Token
   + Kontrastring + kräftigerer Schatten lösen das Chip vom Bild ab; backdrop-blur
   ist reine Zugabe für Browser, die es können. */
.status-tag--overlay {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 3;
  background: var(--color-bg);
  border-color: var(--color-border);
  box-shadow:
    0 0 0 1px rgb(var(--c-white) / 0.65),
    var(--shadow-md);
  backdrop-filter: blur(var(--blur-sm));
}
.status-tag--overlay.status-tag--open {
  color: var(--color-success-dark);
}
.status-tag--overlay.status-tag--closed {
  color: var(--color-gray-600);
}
/* Ausbildung-Cards: Bildfläche als Positionierungskontext für das Overlay-Tag. */
.service-card-img { position: relative; }

/* ── Sticky Bewerben-Leiste (nur Job-Detailseiten, bei offener Stelle) ─────
   Schlanke, wegklickbare Leiste unter dem Header, die beim Scrollen erscheint.
   Fixiert unter der Navbar via --header-offset (folgt automatisch dem Sprach-
   Banner). z-index unter --z-nav, damit Navbar/Dropdown gewinnen. Dismiss via
   sessionStorage (siehe partials/job-apply-bar.html.jinja). */
.job-apply-bar {
  position: fixed;
  top: var(--header-offset);
  left: 0;
  right: 0;
  z-index: var(--z-overlay);
  background: var(--color-bg);
  backdrop-filter: blur(var(--blur-md));
  -webkit-backdrop-filter: blur(var(--blur-md));
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-md);
  transform: translateY(-115%);
  transition: transform var(--transition-base);
}
.job-apply-bar.is-visible { transform: translateY(0); }
.job-apply-bar__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-3) var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.job-apply-bar__label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex: 1;
}
.job-apply-bar__title {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.job-apply-bar__cta { flex-shrink: 0; }
.job-apply-bar__pdf { flex-shrink: 0; }
.job-apply-bar__close {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.job-apply-bar__close:hover { color: var(--color-text); background: var(--color-bg-alt); }
@media (max-width: 640px) {
  .job-apply-bar__inner { padding: var(--space-2) var(--space-3); gap: var(--space-2); }
  .job-apply-bar__title { display: none; }
  /* Auf schmalen Screens nur das PDF-Icon zeigen (Label würde die Leiste sprengen). */
  .job-apply-bar__pdf-label { display: none; }
}

/* ── Machinery Highlights ─────────────────────────────────── */
.machinery-highlights {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: var(--space-6) 0;
}
.mh-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-gray-300);
}
/* ── Karriere Banner ──────────────────────────────────────── */
.karriere-banner {
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
  border-radius: var(--radius-2xl);
  padding: var(--space-12) var(--space-12);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
  border: 1px solid var(--color-border-dark);
}
.karriere-text .section-title { margin-bottom: var(--space-4); }
.karriere-text p { color: var(--color-text-muted); max-width: 480px; }

/* ── Contact Grid ─────────────────────────────────────────── */
.contact-grid {
  display: grid;
  gap: var(--space-8);
  /* Einspaltig: die Standortkarte spannt die VOLLE Breite (identisch zur /kontakt-Logik,
     gleiches consent_map-Paket) statt in einer halben Spalte gequetscht zu sein. */
  grid-template-columns: 1fr;
  align-items: start;
}

.contact-info { display: flex; flex-direction: column; gap: var(--space-6); }
@media (min-width: 768px) {
  /* Interim: Kontaktdaten als schlankes horizontales Band ÜBER der vollbreiten Karte.
     Der finale, schönere & wiederverwendbare Kontaktdaten-Baustein folgt separat (Handoff). */
  .contact-info { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-6) var(--space-10); }
  .contact-info > .contact-cta { margin-left: auto; }
}
.contact-info-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  font-size: var(--text-base);
  color: var(--color-text-muted);
}
.contact-info-item a { color: var(--color-accent-text); text-decoration: none; }
.contact-info-item a:hover { text-decoration: underline; }
.map-placeholder {
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-12);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  text-align: center;
  min-height: 320px;
  justify-content: center;
}
.map-placeholder p { color: var(--color-text-muted); }

/* ── Contact Page Form ────────────────────────────────────── */
.contact-layout {
  display: grid;
  gap: clamp(2.5rem, 3vw, 4rem);
}

.contact-top-grid {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 1024px) {
  .contact-top-grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
  }
}

.contact-sidebar {
  display: grid;
  gap: var(--space-6);
  align-self: flex-start;
  position: sticky;
  top: calc(var(--header-offset) + var(--space-8));
}
.contact-sidebar-panel,
.contact-quick-panel,
.contact-form-wrap,
.contact-map-section,
.contact-person-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-bg);
  box-shadow: 0 24px 48px rgb(var(--c-shadow) / 0.06);
}
.contact-sidebar-panel {
  padding: var(--space-8);
  background:
    radial-gradient(circle at top right, rgb(var(--c-ember) / 0.12), transparent 30%),
    linear-gradient(180deg, var(--color-bg-alt), var(--color-bg));
}
.contact-sidebar-title {
  font-family: var(--font-display);
  font-size: clamp(var(--text-xl), 2vw, var(--text-2xl));
  font-weight: var(--font-weight-bold);
  margin-bottom: var(--space-3);
}
.contact-sidebar-text,
.contact-form-lead,
.contact-section-text {
  color: var(--color-text-muted);
  max-width: 62ch;
  font-size: var(--text-base);
  line-height: 1.7;
}
.contact-form-intro {
  display: grid;
  gap: var(--space-3);
  max-width: 60ch;
  margin-bottom: var(--space-8);
}
.contact-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.78rem;
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-accent-text);
}
.contact-eyebrow::before {
  content: '';
  width: 2.25rem;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}
.contact-info-block {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.contact-info-block strong {
  display: block;
  color: var(--color-text);
  margin-bottom: 0.2rem;
}
.contact-info-block .fas {
  color: var(--color-accent-text);
  font-size: var(--text-lg);
  flex-shrink: 0;
  margin-top: 2px;
  width: 20px;
}
.contact-info-block a { color: var(--color-accent-text); text-decoration: none; }
.contact-info-block + .contact-info-block { margin-top: var(--space-5); }

.contact-quick-panel {
  padding: var(--space-7);
  border-top: 3px solid var(--color-accent);
}
.contact-quick-panel-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--font-weight-bold);
  margin-bottom: var(--space-5);
  color: var(--color-text);
}
.contact-quick-list {
  display: grid;
  gap: var(--space-4);
}
.contact-quick-item {
  display: grid;
  gap: 0.35rem;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.contact-quick-item:first-child {
  padding-top: 0;
  border-top: 0;
}
.contact-quick-item strong {
  color: var(--color-text);
  font-size: var(--text-sm);
}
.contact-quick-item span {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  line-height: 1.65;
}

.contact-team-section,
.contact-map-section {
  display: grid;
  gap: var(--space-8);
}
.contact-map-section {
  padding: var(--space-8);
  background:
    linear-gradient(180deg, var(--color-bg-alt), var(--color-bg)),
    radial-gradient(circle at top left, rgb(var(--c-info) / 0.06), transparent 30%);
}
.contact-section-heading {
  display: grid;
  gap: var(--space-3);
}
.contact-section-heading--map {
  max-width: 72ch;
}
.contact-section-title {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3vw, 2.8rem);
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
}

.contact-person-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;          /* phones: one full-width horizontal "directory" card */
}
@media (min-width: 560px) {
  .contact-person-grid {
    gap: var(--space-5);
    grid-template-columns: repeat(2, var(--grid-track-fluid));
  }
}
@media (min-width: 760px) {
  .contact-person-grid {
    gap: var(--space-6);
    grid-template-columns: repeat(3, var(--grid-track-fluid));
  }
}
@media (min-width: 1100px) {
  .contact-person-grid {
    grid-template-columns: repeat(4, var(--grid-track-fluid));
  }
}
.contact-person-card {
  background: var(--card-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-align: center;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast);
}
.contact-person-card:has(a[href]:is(:hover, :focus-visible)) {
  box-shadow: var(--card-shadow-hover-soft);
  border-color: color-mix(in srgb, var(--color-accent) 26%, var(--color-border));
}
.contact-person-card__photo {
  width: 100%;
  height: 200px;
  overflow: hidden;
}
.contact-person-card__photo picture {
  display: block;
  width: 100%;
  height: 100%;
}
.contact-person-card__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.5s ease;
  display: block;
}
.contact-person-card:has(a[href]:is(:hover, :focus-visible)) .contact-person-card__photo img {
  transform: none;
}

/* Portrait als Lightbox-Trigger: klickbar (Popup mit großem Bild + Kontaktdaten,
   generische Lightbox). Affordance analog zur Galerie-Kachel. */
.contact-person-card__photo--trigger {
  position: relative;
  cursor: zoom-in;
}
.contact-person-card__photo--trigger:focus-visible {
  outline: 2px solid var(--color-accent-text);
  outline-offset: 2px;
}
.contact-person-card__photo--trigger:hover img,
.contact-person-card__photo--trigger:focus-visible img {
  transform: scale(1.05);
}
/* Monogramm-Platzhalter (kein <img>) bekommt dieselbe Hover-Andeutung. */
.contact-person-card__photo--trigger .contact-person-card__monogram {
  transition: transform 0.4s ease;
}
.contact-person-card__photo--trigger:hover .contact-person-card__monogram,
.contact-person-card__photo--trigger:focus-visible .contact-person-card__monogram {
  transform: scale(1.06);
}
/* Aussehen, Aufdecken beim Hover/Fokus und die Touch-Sichtbarkeit kommen aus der
   SSOT `.media-zoom-badge` (components/lightbox.css) — hier steht nur noch, wie
   GROSS das Badge auf dem 200px-Portrait sitzt.
   Vorher stand hier eine vierte Kopie des Badge-Rezepts, und ihr
   `@media (hover: none) { display: none }` war der Defekt: auf dem Smartphone
   zeigte an den Kontaktkarten nichts mehr an, dass sie sich antippen lassen. */
.contact-person-card__zoom {
  --media-zoom-size: 1.9rem;
  --media-zoom-icon-size: 0.95rem;
}

/* Hover-Hinweis am unteren Bildrand (wie /einblicke/): gleitet beim Hover hoch
   und signalisiert „Klick öffnet mehr" (großes Bild + Kontaktdaten). Nur Desktop. */
.contact-person-card__hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  padding: 0.42rem;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--on-dark-text);
  background: var(--scrim-media-chip-strong);
  backdrop-filter: blur(var(--blur-sm));
  pointer-events: none;
  opacity: 0;
  transform: translateY(101%);
  transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.contact-person-card__hint-icon {
  width: 0.95rem;
  height: 0.95rem;
  flex-shrink: 0;
}
.contact-person-card__photo--trigger:hover .contact-person-card__hint,
.contact-person-card__photo--trigger:focus-visible .contact-person-card__hint {
  opacity: 1;
  transform: translateY(0);
}
/* Touch: der Hinweis-BALKEN bleibt aus — er legt sich über das halbe Gesicht und
   hätte auf einem 200px-Portrait keinen Hover, der ihn wieder wegnimmt. Die
   Antipp-Affordanz trägt dort das Badge oben rechts (`.media-zoom-badge`, s. o.),
   genau wie auf /einblicke/. Aus heißt hier also NICHT „kein Signal". */
@media (hover: none) {
  .contact-person-card__hint {
    display: none;
  }
}
.contact-person-card__info {
  padding: 1.1rem var(--space-4) var(--space-5);
}
.contact-person-card__name {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin-bottom: 0.2rem;
  line-height: 1.3;
}
.contact-person-card__role {
  display: block;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
  line-height: 1.4;
}
/* Teaser direkt auf der Card (immer sichtbar): Icon + kurzer Qualifizierungssatz,
   damit Besucher sofort den/die richtige Ansprechpartner:in erkennen. */
.contact-person-card__teaser {
  display: flex;
  align-items: flex-start;
  justify-content: center;   /* Block folgt der zentrierten Card … */
  gap: 0.5em;
  margin: 0 0 var(--space-4);
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--color-text-muted);
}
.contact-person-card__teaser > span {
  text-align: left;          /* … Fließtext bleibt linksbündig (lesbarer). */
  max-width: 30ch;
}
.contact-person-card__teaser-icon {
  width: 0.9rem;
  height: 0.9rem;
  flex-shrink: 0;
  margin-top: 0.12em;
  color: var(--color-success);
}
.contact-person-card__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--badge-pill-gap);
  font-size: var(--badge-pill-font-size);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
  padding: var(--badge-pill-padding-y) var(--badge-pill-padding-x);
  background: rgb(var(--c-ember) / 0.07);
  border-radius: var(--badge-pill-radius);
  text-decoration: none;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}
.contact-person-card__phone:hover {
  background: var(--color-accent);
  color: var(--color-text-inverse);
}
.contact-person-card__phone .fas {
  font-size: 0.72rem;
  flex-shrink: 0;
}

/* Department grouping ----------------------------------------------------- */
.contact-dept + .contact-dept {
  margin-top: var(--space-8);
}
.contact-dept__title {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  letter-spacing: var(--tracking-snug);
  margin-bottom: var(--space-5);
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.contact-dept__title::before {
  content: "";
  width: 3px;
  height: 1.05em;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  flex-shrink: 0;
}

/* Monogram fallback when a person has no photo yet ------------------------- */
.contact-person-card__photo--monogram {
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(120% 120% at 30% 20%, rgb(var(--c-ember) / 0.14), transparent 60%),
    var(--color-bg-alt);
}
.contact-person-card__monogram {
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-snug);
  line-height: 1;
  color: var(--color-accent-text);
  width: 84px;
  height: 84px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--card-surface);
  border: 1px solid color-mix(in srgb, var(--color-accent) 22%, var(--color-border));
  box-shadow: 0 2px 10px rgb(var(--c-ember) / 0.08);
}

/* Contact links row (phone + optional email) ------------------------------ */
.contact-person-card__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem;
}
.contact-person-card__email {
  display: inline-flex;
  align-items: center;
  gap: var(--badge-pill-gap);
  max-width: 100%;
  font-size: var(--badge-pill-font-size);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  padding: var(--badge-pill-padding-y) var(--badge-pill-padding-x);
  background: rgb(var(--c-black) / 0.05);
  border-radius: var(--badge-pill-radius);
  text-decoration: none;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}
.contact-person-card__email:hover {
  background: var(--color-accent);
  color: var(--color-text-inverse);
}
.contact-person-card__email .fas {
  font-size: 0.72rem;
  flex-shrink: 0;
}
.contact-person-card__email .js-cmail-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Phones (≤559px): premium full-width HORIZONTAL "directory" card.
   Portrait/monogram avatar left, identity + actions right. The phone number is
   the primary CTA (B2B callers); e-mail collapses to a tappable icon button so
   the long revealed address can never overflow or truncate the row. One column
   only — the grid above keeps a single full-width card per row below 560px. */
@media (max-width: 559px) {
  .contact-person-card {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: var(--space-4);
    text-align: left;
    padding: var(--space-4);
  }
  .contact-person-card__photo {
    width: 84px;
    height: 84px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    flex-shrink: 0;
    box-shadow: inset 0 0 0 1px rgb(var(--c-black) / 0.06);
  }
  /* Das Badge steht auf Touch DAUERHAFT (SSOT .media-zoom-badge) — auf dem
     84px-Avatar dieser Zeile wäre die Desktop-Größe 1,9rem = 36 % der Portraitbreite
     und läge mitten im Gesicht. Gemessen bei 390px: 30px Badge auf 84px Portrait.
     1,25rem trägt das Signal, ohne das Portrait zu verdecken. */
  .contact-person-card__zoom {
    --media-zoom-size: 1.25rem;
    --media-zoom-icon-size: 0.7rem;
    --media-zoom-inset: var(--space-1);
  }
  .contact-person-card__photo--monogram {
    border-radius: var(--radius-lg);
  }
  .contact-person-card__monogram {
    width: 100%;
    height: 100%;
    border-radius: var(--radius-lg);
    font-size: var(--text-2xl);
    box-shadow: none;
  }
  .contact-person-card__info {
    min-width: 0;            /* lets the identity column shrink instead of overflowing */
    padding: 0;
  }
  .contact-person-card__name {
    font-size: var(--text-base);
    margin-bottom: 0.15rem;
  }
  .contact-person-card__role {
    margin-bottom: var(--space-3);
  }
  .contact-person-card__links {
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: var(--space-2);
  }
  .contact-person-card__phone {
    flex: 1 1 auto;          /* never shrinks below the number → no clipping */
    min-height: 40px;
    justify-content: center;
    font-size: var(--text-sm);
  }
  .contact-person-card__email {
    flex: 0 0 auto;
    width: 44px;
    min-height: 40px;
    padding-inline: 0;
    justify-content: center;
    background: var(--color-bg);
    border: 1px solid color-mix(in srgb, var(--color-accent) 24%, var(--color-border));
    color: var(--color-accent-text);
  }
  .contact-person-card__phone .fas {
    font-size: 0.85rem;
  }
  .contact-person-card__email .fas {
    font-size: 0.95rem;
  }
  .contact-person-card__email .js-cmail-label {
    display: none;           /* icon-only on phones; aria-label keeps it accessible */
  }
}

/* Very narrow phones (≤430px): the phone number + e-mail icon no longer share a
   row comfortably, so stack both actions full-width as matched tap targets — a
   filled phone CTA over an outlined e-mail icon button. The e-mail stays
   icon-only (the name above already identifies the recipient) so it reads
   consistently clean instead of truncating the long address mid-domain. */
@media (max-width: 430px) {
  .contact-person-card__links {
    flex-direction: column;
    align-items: stretch;
  }
  .contact-person-card__phone,
  .contact-person-card__email {
    width: 100%;
  }
}

.consent-embed {
  display: grid;
  gap: var(--space-4);
}
.consent-embed-frame[hidden],
.consent-embed-placeholder[hidden] {
  display: none !important;
}
.consent-embed-frame {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-bg-alt);
  min-height: 400px;
}
.consent-embed-frame iframe {
  width: 100%;
  min-height: 400px;
  border: 0;
  display: block;
}
/* Google-Maps-Consent-Mock. Farben ab jetzt THEME-AWARE über --consent-*-Tokens (variables.css,
   Foreign-Brand-Palette dort EINMALIG gehatcht) → dieser Consumer bleibt vom Farb-SSOT-Guard
   ABGEDECKT (self-healing: neues Roh-Hex hier lässt CI rot werden). Google-authentische
   Off-Scale-Dimensionen (px/rem) bleiben bewusst literal (nicht auf dem Marken-Raster). */
/* Google Maps-style consent placeholder */
.consent-embed-placeholder {
  position: relative;
  background: transparent;
  border: 0;
  border-radius: var(--radius-lg);
  padding: 0;
  display: flex;
  flex-direction: column;
  cursor: default;
  overflow: hidden;
  box-shadow: 0 1px 4px rgb(var(--c-black) / 0.18), 0 3px 12px rgb(var(--c-black) / 0.10);
}
.consent-embed-preview {
  position: relative;
  display: block;
  min-height: 400px;
  flex: 1;
  overflow: hidden;
  border-radius: 0;
  background-image: url('/assets/images/map-preview.svg');
  filter: var(--consent-preview-filter);  /* Dark: map-preview abdunkeln (data-theme) */
  background-size: cover;
  background-position: center;
  border: 0;
}
/* Google Maps search bar */
.consent-embed-search {
  left: 0.75rem;
  right: 3.55rem;
  top: 0.75rem;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-2xl);
  background: var(--consent-chrome-bg);
  color: var(--consent-chrome-ink);
  font-size: 13px;
  font-weight: var(--font-weight-normal);
  box-shadow: 0 1px 3px rgb(var(--c-black) / 0.22), 0 1px 6px rgb(var(--consent-shadow) / 0.16);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 1;
}
.consent-embed-search .fas {
  color: var(--consent-chrome-icon);
  font-size: 0.78rem;
  flex-shrink: 0;
}
/* Google Maps zoom controls */
.consent-embed-zoom {
  top: 0.75rem;
  right: 0.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 2.35rem;
  overflow: hidden;
  border-radius: 2px;
  background: var(--consent-chrome-bg);
  box-shadow: 0 1px 3px rgb(var(--c-black) / 0.22);
  z-index: 1;
}
.consent-embed-zoom span {
  width: 100%;
  min-height: 2.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--consent-chrome-icon);
  font-size: 1.1rem;
  font-weight: var(--font-weight-normal);
}
.consent-embed-zoom span:nth-child(2) {
  min-height: 1px;
  background: var(--consent-chrome-divider);
}
/* Centered consent overlay card */
.consent-embed-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  background: transparent;
  border-radius: inherit;
  z-index: 2;
}
.consent-embed-overlay-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 300px;
  gap: 0.65rem;
  background: var(--consent-chrome-bg);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-7);
  box-shadow: 0 8px 32px rgb(var(--c-black) / 0.22), 0 2px 8px rgb(var(--c-black) / 0.12);
}
.consent-embed-overlay-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: var(--consent-logo-bg);
  border-radius: 50%;
  flex-shrink: 0;
}
.consent-embed-overlay-title {
  font-size: 0.92rem;
  font-weight: var(--font-weight-bold);
  color: var(--consent-chrome-ink);
  line-height: 1.3;
}
.consent-embed-overlay-desc {
  font-size: var(--text-xs);
  color: var(--consent-chrome-icon);
  line-height: 1.55;
  margin: 0;
}
.consent-embed-settings {
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--consent-link);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  white-space: nowrap;
}
.consent-embed-settings:hover,
.consent-embed-settings:focus-visible {
  color: var(--consent-link-hover);
  text-decoration: underline;
}

@media (max-width: 640px) {
  .consent-embed-preview {
    min-height: 300px;
  }
  .consent-embed-search {
    right: 3.4rem;
    font-size: var(--text-xs);
    min-height: 38px;
    padding: 0.55rem var(--space-3);
  }
  .consent-embed-zoom {
    width: 2.15rem;
  }
  .consent-embed-overlay {
    padding: var(--space-4);
  }
  .consent-embed-overlay-card {
    padding: 1.1rem var(--space-5);
    max-width: 260px;
  }
}
/* Ende Google-Maps-Consent-Mock (Farben jetzt token-getrieben + guard-abgedeckt) */

/* ── 2-in-1-Standortkarte-Paket: feste Vektor-Reichweitenkarte (oben, consent-frei)
      + darunter die interaktive Google-Consent-Zone. Ein Baustein, zwei Rollen. ── */
.reachmap-package {
  display: grid;
  gap: var(--space-3);
}
.reachmap-cap {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  line-height: 1.3;
}
.reachmap-cap-role {
  font-weight: var(--font-weight-bold);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text);
}
.reachmap-cap-sub {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.reachmap-cap--interactive {
  margin-top: var(--space-1);
}
.reachmap-figure {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-bg-alt);
}
/* Feste Reichweitenkarte: EINE von vier gebauten SVG-Varianten (Desktop/Mobil × Hell/Dunkel, alle
   aus EINEM Generator seo_engine/pdf/reach_map) als Hintergrund. Die vier gehashten URLs liefert das
   Template (consent_map) als --rm-*-Custom-Props; hier wird per Viewport + :root[data-theme] die
   aktive gewählt → es lädt nur die gematchte Datei (kein Doppel-Download). Ersetzt den früheren
   <img>-Ansatz: so folgt die Karte dem manuellen Dark-Toggle (data-theme, NICHT OS-Media). */
.reachmap-img {
  display: block;
  width: 100%;
  aspect-ratio: 1040 / 340;
  background-image: var(--rm-desktop, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
:root[data-theme="dark"] .reachmap-img { background-image: var(--rm-desktop-dark, none); }
@media (max-width: 640px) {
  .reachmap-img { aspect-ratio: var(--reachmap-portrait-ratio); background-image: var(--rm-mobile, none); }
  :root[data-theme="dark"] .reachmap-img { background-image: var(--rm-mobile-dark, none); }
}
/* Die Vektorkarte oben ist der visuelle Anker → der graue Google-Teaser entfällt im Paket,
   nur der schlanke „Karte laden"-Streifen bleibt (kein zweites, konkurrierendes Kartenbild). */
.reachmap-package .consent-embed { gap: 0; }
.reachmap-package .consent-embed-preview { display: none; }
.reachmap-package .consent-embed-placeholder {
  box-shadow: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-alt);
  min-height: 0;
}
.reachmap-package .consent-embed-overlay {
  position: static;
  padding: var(--space-5);
}
/* ── Map-Paket-Höhe: EINE SSOT-Stelle für ALLE Vollbreiten-Karten ────────────
   Nach Zustimmung lädt das echte iframe → es nimmt die zentrale Desktop-Höhe.
   Diese Regel am Paket selbst gilt für /kontakt (.contact-map-section) UND Home
   (.contact-grid) gleichzeitig — beide sind vollbreit, kein Kontext-Override mehr.
   Höhe ändern = NUR den Token --map-embed-h-desktop (variables.css) anfassen.
   Einzige Ausnahme ist das schmale contact_cta-Band (eigene Fill-Höhe unten). */
.reachmap-package .consent-embed-frame { min-height: var(--map-embed-h-desktop); }
.reachmap-package .consent-embed-frame iframe { min-height: var(--map-embed-h-desktop); }
/* Im schmalen contact_cta-Band die Fill-Höhen-Kette (fixe Spaltenhöhe + overflow:hidden)
   fürs Paket aufheben — das gestapelte Paket bestimmt seine natürliche Höhe selbst. */
.contact-cta__map .contact-map:has(.reachmap-package) {
  height: auto;
  overflow: visible;
}
.contact-cta__map .reachmap-package,
.contact-cta__map .reachmap-package .consent-embed,
.contact-cta__map .reachmap-package .consent-embed-placeholder,
.contact-cta__map .reachmap-package .consent-embed-frame {
  height: auto;
  min-height: 0;
}
.contact-cta__map .reachmap-package .consent-embed-frame,
.contact-cta__map .reachmap-package .consent-embed-frame iframe {
  /* Kompakter Band-Streifen: folgt DEMSELBEN Token --map-embed-h-desktop, nur per
     min()-Deckel schlank gehalten (die vollen 840px würden das schmale Band sprengen).
     → EIN Knopf bewegt auch dieses Band mit; kein unabhängig gepflegter Wert. */
  min-height: min(var(--map-embed-h-desktop), 480px);
}
/* Schmale contact_cta-Spalte (Desktop ≥880px): dort ist die Spalte hochformatig →
   die MOBIL-Variante der EINEN Generator-Karte (Region + Deutschland übereinander)
   statt des plattgequetschten Querformats. Bewusst HIER (bei den zentralen
   .reachmap-img-Regeln, die das consent_map-Partial als die eine Schaltstelle
   benennt) und NICHT in contact-cta.css — Variantenwahl + Geometrie der Reachmap
   haben genau EINE Pflegestelle. */
@media (min-width: 880px) {
  .contact-cta__map .reachmap-img {
    aspect-ratio: var(--reachmap-portrait-ratio);
    background-image: var(--rm-mobile, none);
  }
  :root[data-theme="dark"] .contact-cta__map .reachmap-img {
    background-image: var(--rm-mobile-dark, none);
  }
}

.contact-form-wrap {
  padding: var(--space-8);
  position: relative;
  isolation: isolate;
  /* overflow VISIBLE: damit der --glow-Halo des fokussierten Feldes nicht am
     Formular-Rand abgeschnitten wird. Der Radial-Verlauf-Hintergrund bleibt durch
     border-radius + background-clip ohnehin gerundet. */
  overflow: visible;
  background-clip: padding-box;
  background:
    radial-gradient(80% 70% at 100% 0%, rgb(var(--c-wash) / 0.92), transparent 52%),
    radial-gradient(62% 58% at 0% 0%, rgb(var(--c-red) / 0.07), transparent 48%),
    linear-gradient(180deg, var(--color-bg), var(--color-bg-alt));
}
.contact-form-wrap > * {
  position: relative;
  z-index: 1;
}
.contact-form-title {
  font-family: var(--font-display);
  font-size: clamp(var(--text-2xl), 2.6vw, 2.7rem);
  font-weight: var(--font-weight-bold);
}

.contact-map {
  overflow: hidden;
  border-radius: var(--radius-lg);
}
.contact-map .consent-embed-frame,
.contact-map .consent-embed-placeholder {
  border-radius: var(--radius-lg);
}
.contact-map-section .consent-embed-frame,
.contact-map-section .consent-embed-placeholder {
  border-radius: calc(var(--radius-xl) - 4px);
}
/* Höhe kommt aus der zentralen .reachmap-package-Regel (Token --map-embed-h-desktop) —
   HIER bewusst KEIN eigener min-height mehr (war die zweite Pflegestelle). */

/* Form Elements */
.form-row { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 640px) { .form-row { grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid); } }
.form-group { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-4); }
.form-label { font-size: var(--text-sm); font-weight: var(--font-weight-semibold); color: var(--color-text); }
.required { color: var(--color-accent-text); }
.form-input {
  padding: var(--space-3) var(--space-4);
  border: 1.5px solid var(--field-border);
  border-radius: var(--field-radius);
  font-size: var(--text-base);
  font-family: var(--font-base);
  color: var(--color-text);
  background: var(--field-bg);
  box-shadow: var(--field-shadow);
  transition:
    border-color var(--glow-speed) var(--glow-ease),
    box-shadow var(--glow-speed) var(--glow-ease),
    background var(--glow-speed) var(--glow-ease);
  width: 100%;
}
.form-input:not(.form-readonly):hover {
  border-color: var(--field-hover-border);
  background: var(--field-hover-bg);
  box-shadow: var(--field-hover-shadow);
}
.form-input:not(.form-readonly):is(:focus, :focus-visible) {
  border-color: rgb(var(--c-red-light) / 0.55);
  background: var(--field-hover-bg);
  /* nur das FOKUSSIERTE Feld glüht — zentraler --glow (SSOT, wie Cards/Galerie) */
  box-shadow: var(--glow);
  outline: none;
}
.form-input.input-error {
  border-color: var(--color-error);
  box-shadow: var(--field-error-shadow);
}
.form-select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2394a3b8' d='M1 1l5 5 5-5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; padding-right: 40px; }
.form-textarea { resize: vertical; min-height: 160px; }
.form-error { font-size: var(--text-xs); color: var(--color-error); min-height: 1.2em; }
.form-checkbox {
  flex-direction: row;
  align-items: flex-start;
  gap: var(--space-3);
  padding: 0.35rem 0.45rem;
  border-radius: var(--radius-md);
  transition:
    transform var(--glow-speed) ease,
    box-shadow var(--glow-speed) ease,
    background-color var(--glow-speed) ease;
}
.form-checkbox input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
  accent-color: var(--color-accent);
  transition:
    transform var(--glow-speed) ease,
    box-shadow var(--glow-speed) ease,
    filter var(--glow-speed) ease;
}
.form-checkbox:is(:hover, :focus-within) {
  transform: translateY(-1px);
  background: var(--color-bg);
  box-shadow: var(--checkbox-hover-shadow);
}
.form-checkbox:is(:hover, :focus-within) input[type="checkbox"] {
  transform: scale(1.06);
  box-shadow: var(--checkbox-control-hover-shadow);
}
.form-label-inline { font-size: var(--text-sm); color: var(--color-text-muted); }
.form-label-inline a { color: var(--color-accent-text); }
.form-honeypot { display: none !important; }
@media (max-width: 1023px) {
  .contact-sidebar {
    position: static;
    top: auto;
  }
}
@media (max-width: 640px) {
  .contact-form-wrap,
  .contact-sidebar-panel,
  .contact-quick-panel,
  .contact-map-section {
    padding: var(--space-6);
  }
}

/* ── Page Hero ────────────────────────────────────────────── */
.page-hero {
  position: relative;
  min-height: 50vh;
  display: flex;
  align-items: flex-end;
  padding-bottom: var(--space-16);
  overflow: hidden;
  /* Dunkler Fallback, falls kein Hintergrundbild gesetzt ist (Text bleibt lesbar). */
  background-color: var(--color-primary-dark);
}
.page-hero-short { min-height: 35vh; }

/* Bild-Hero: bewährter Cover-Look bleibt — aber die Hero-HÖHE wird pro Seite
   moderat angehoben, wenn das Bild quadratisch/hoch ist (würde sonst hart
   vertikal beschnitten). Breite Bilder behalten die Basishöhe. Den konkreten
   Wert (--page-hero-h, z. B. 50–68vh) berechnet das page_hero-Macro automatisch
   aus den Bildmaßen (page_hero_height). Langer Text lässt den Hero bei Bedarf
   weiter wachsen (min-height statt fixe height). */
.page-hero--adaptive {
  min-height: var(--page-hero-h, 50vh);
}

.page-hero-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  transform: scale(1.05);
  transition: transform 8s ease;
}
.page-hero:hover .page-hero-bg { transform: scale(1); }

/* Video als Hero-Hintergrund (autoplay/muted/loop, lazy via js-lazy-video).
   Kein Ken-Burns-Zoom – ein laufendes Video bewegt sich bereits selbst. */
.page-hero-bg--video,
.page-hero--video:hover .page-hero-bg--video { transform: none; }
.page-hero-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* <picture> als Hintergrundbild in .page-hero-bg */
.page-hero-bg picture { display: block; width: 100%; height: 100%; }
.page-hero-bg picture img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

.page-hero-overlay {
  position: absolute;
  inset: 0;
  background: var(--media-hero-scrim);
  transition: opacity 0.8s ease;
}
.page-hero-overlay-light {
  background: var(--media-hero-scrim-light);
}
/* Auf Video-Slides: Overlay auf ~40 % zurückfahren → Video deutlich sichtbarer;
   der Überblend synchronisiert sich mit dem Slide-Crossfade (0.8 s). */
.page-hero--carousel.is-video-slide .page-hero-overlay { opacity: 0.4; }

.page-hero-content {
  position: relative;
  z-index: 2;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--space-6);
  width: 100%;
}
@media (min-width: 768px) { .page-hero-content { padding: 0 var(--space-8); } }

.page-hero-title {
  font-family: var(--font-display);
  font-size: clamp(var(--text-3xl), 5vw, var(--text-6xl));
  font-weight: var(--font-weight-black);
  color: var(--on-dark-text);
  line-height: var(--leading-tight);
  margin-bottom: var(--space-4);
  letter-spacing: var(--tracking-tight);
}
.page-hero-subtitle {
  font-size: var(--text-lg);
  color: var(--on-dark-text-muted);
  max-width: 600px;
}
/* ── Kontakt-Hero: Badge-Reihe + Dual-CTA ───────────────────────────────── */
.kontakt-hero-trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-5);
}
.kontakt-hero-trust .hero-badge { margin-bottom: 0; }

/* ── GESTACKTER Video-Hero (Champions-League-UX, ALLE Breakpoints) ─────────
   Bewusst HIER (nach den .hero- UND .page-hero-Basisregeln), damit dieser
   Block per Source-Order gewinnt (gleiche Spezifität wie die Basisregeln).
   Der Hero ist auf JEDER Größe GESTACKT: Video-Band oben, Text-Panel darunter
   (saubere Trennung, weiße Schrift auf dunklem Grund, kein Scrim/Overlay nötig).
   Der Pause-Button sitzt absolut im Band → automatisch unten rechts AM VIDEO.
   - Mobil/Tablet: das Band wächst mit dem EIGENEN Seitenverhältnis des Videos
     (Poster width/height-Attr + height:auto → kein Crop, kein Letterbox; passt
     für Quer- UND Hochformat automatisch).
   - Desktop: das Band wird zu einem „Cinematic Banner" gedeckelt (Höhe via
     Token --hero-band-height) — sonst wäre ein 16:9-Video bildschirmhoch.
   Reines CSS, 0 zusätzliche Bytes; greift für beide Hero-Typen (Bild-Heroes
   bleiben unberührt, da nur .hero / .page-hero--video getroffen werden). */
.hero,
.page-hero--video {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  height: auto;
  min-height: 0;
  background: var(--color-primary-dark);
}
/* Media wird ein in-flow Band oben (statt absolut über die ganze Höhe). */
.hero-bg,
.page-hero-bg--video {
  position: relative;
  inset: auto;
  width: 100%;
  height: auto;
  transform: none;
}
/* Bandhöhe = Seitenverhältnis des Posters (width/height-Attr + height:auto). */
.hero-bg .bm-hero-poster,
.page-hero-bg--video .bm-hero-poster,
.page-hero-bg--video picture {
  position: relative;
  inset: auto;
  height: auto;
}
.hero-bg .bm-hero-poster img,
.hero-bg .bm-hero-poster-img,
.page-hero-bg--video .bm-hero-poster img,
.page-hero-bg--video .bm-hero-poster-img,
.page-hero-bg--video picture img {
  display: block;
  height: auto;
  object-fit: cover;
  object-position: center;
}
/* Video überlagert das Poster-Band exakt (Box == Ratio → kein Crop). */
.hero-bg .bm-hero-video,
.page-hero-bg--video .bm-hero-video {
  object-fit: cover;
  object-position: center;
}
/* Scrim/Overlay im gestackten Layout nicht nötig (Text auf dunklem Grund). */
.hero .hero-overlay,
.page-hero--video .page-hero-overlay { display: none; }
/* Text-Panel unter dem Video: vertikale Luft. */
.hero .hero-content,
.page-hero--video .page-hero-content {
  padding-top: var(--space-10);
  padding-bottom: var(--space-12);
}

/* Desktop: das Band als gedeckelter „Cinematic Banner" (Höhe = Token). Poster +
   Video füllen das fixe Band; Querformat = cover (füllt Breite, kinoartig),
   Hochformat = contain (ganzer Frame, Ränder = --hero-media-backdrop). Der Text
   bleibt als eigenes Panel darunter — gleiche Trennung wie auf Mobil. */
@media (min-width: 1025px) {
  .hero-bg,
  .page-hero-bg--video {
    height: var(--hero-band-height);
    background: var(--hero-media-backdrop);
  }
  .hero-bg .bm-hero-poster,
  .page-hero-bg--video .bm-hero-poster,
  .page-hero-bg--video picture {
    position: absolute;
    inset: 0;
    height: 100%;
  }
  .hero-bg .bm-hero-poster img,
  .hero-bg .bm-hero-poster-img,
  .page-hero-bg--video .bm-hero-poster img,
  .page-hero-bg--video .bm-hero-poster-img,
  .page-hero-bg--video picture img {
    height: 100%;
  }
  /* Hochformat: ganzer Frame statt Crop. Die Pillarbox füllt .bm-media-fill
     (unscharfe Kopie desselben Frames, vom hero_video()-Macro mitgeliefert);
     der Backdrop bleibt die Grundfläche darunter. Poster/Video explizit über
     die Füll-Ebene legen — nicht auf DOM-Reihenfolge verlassen. */
  .bm-hero-poster.bm-hero-media--portrait img,
  .bm-hero-poster.bm-hero-media--portrait .bm-hero-poster-img,
  .bm-hero-video.bm-hero-media--portrait { object-fit: contain; }
  .bm-hero-poster.bm-hero-media--portrait,
  .bm-hero-video.bm-hero-media--portrait { z-index: 1; }
  /* Text-Panel auf Desktop etwas großzügiger. */
  .hero .hero-content,
  .page-hero--video .page-hero-content {
    padding-top: var(--space-14);
    padding-bottom: var(--space-16);
  }
}

/* ════════════════════════════════════════════════════════════════
   BILD-KARUSSELL HERO  (optional, ab 2 hero_images) — Champions-League
   ════════════════════════════════════════════════════════════════
   SSOT: gerendert vom page_hero()-Macro (templates/macros/hero.html.jinja),
   gesteuert von der Hero-Carousel-Runtime in main.js. Architektur:
     • Slides liegen GESTAPELT im .page-hero-bg--carousel (Crossfade via opacity).
     • Bedien-Layer (Dots, cursor-folgender Prev/Next-Button, WCAG-2.2.2-Pause)
       liegt ÜBER dem Scrim (.page-hero-overlay).
     • Der Prev/Next-Button spiegelt 1:1 .bm-hero-pause--follow (Video-Hero):
       er „hängt" am Mauszeiger (GPU-transform via --bm-nav-x/y, KEIN Reflow),
       seine Pfeilrichtung folgt der Maus-Hälfte (links=zurück, rechts=vor).
   Progressive Enhancement: ohne JS bleibt ein sauberer Einzelbild-Hero (Slide 1);
   alle Bedienelemente sind bis .is-enhanced ausgeblendet (kein toter Klick). */

/* Karussell-Band: kein Ken-Burns-Zoom (der Crossfade IST die Bewegung). */
.page-hero-bg--carousel,
.page-hero--carousel:hover .page-hero-bg--carousel { transform: none; }

.bm-hero-slides { position: absolute; inset: 0; }
.bm-hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--hero-carousel-fade) ease;
  will-change: opacity;
}
.bm-hero-slide.is-active { opacity: 1; }
.bm-hero-slide picture { display: block; width: 100%; height: 100%; }
.bm-hero-slide picture img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block;
}

/* Video-Slide (Cover-Modus): das <video> liegt cover ÜBER seinem Poster (die
   picture-Regel oben covert das Standbild) und blendet bei canplay ein. Die
   Karussell-Runtime (main.js) injiziert die <source>-Stufen und steuert
   play/pause beim Slide-Wechsel. KEIN gestackter Voll-Video-Hero hier. */
.bm-hero-slide .bm-hero-cv {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  opacity: 0;
  transition: opacity var(--hero-video-fade) ease;
}
.bm-hero-slide .bm-hero-cv.is-playing { opacity: 1; }

/* ── HOCHFORMAT-Video als Karussell-Slide (smart, = Voll-Video-Hero) ──────────
   Ein Portrait-Clip (videos.yaml height > width) würde im breiten Cover-Slide
   hart beschnitten. Das page_hero()-Macro taggt die Slide dann als
   .bm-hero-slide--portrait und den Hero als .page-hero--portrait-video; die
   Slide bringt via media_fill() ihre Füll-Ebene mit.

   Die Regel gilt auf JEDEM Breakpoint — ein hochkantes Motiv wird nie hart
   beschnitten. (Sie stand bis 2026-08 unter @media(min-width:1025px): Desktop
   war korrekt, Telefon UND Tablet zeigten cover — beim 4:5-Karriere-Clip in
   einem 16:9-Band waren das 2,2× Zoom und 55 % abgeschnittener Frame.)
   Poster UND <video> teilen dasselbe Fit, damit Standbild→Clip nahtlos bleibt;
   die Füll-Ebene liegt darunter (z-index) und bleibt cover. Der neutrale
   --hero-media-backdrop bleibt als Grundfläche darunter: er trägt, solange das
   Füllbild noch lädt, und wenn es fehlt. Bild-Slides und Querformat-Videos
   sind unberührt. Vertikaler Raum: Desktop = Video-Bandhöhe, Mobil = das
   vertiefte Solo-Band (--hero-solo-band-portrait, s. MOBIL-SOLO-Block). */
.bm-hero-slide--portrait { background: var(--hero-media-backdrop); }
/* Über die Füll-Ebene heben. NUR das Poster braucht dafür `position`: es liegt
   im Fluss, ohne Positionierung greift z-index nicht. Das <video> ist bereits
   absolut (`.bm-hero-slide .bm-hero-cv`) — es hier MITZUPOSITIONIEREN wäre fatal:
   gleiche Spezifität, spätere Quelle ⇒ `relative` schlägt `absolute`, das Video
   fällt in den Fluss und rendert UNTER dem Standbild statt darüber. Genau das
   ist am 2026-08-03 live passiert und blieb in headless unsichtbar, weil das
   Video dort nie lädt (opacity bleibt 0). Video: z-index, NIEMALS position. */
.bm-hero-slide--portrait > picture { position: relative; z-index: 1; }
.bm-hero-slide--portrait .bm-hero-cv { z-index: 1; }
.bm-hero-slide--portrait > picture img,
.bm-hero-slide--portrait .bm-hero-cv { object-fit: contain; }
@media (min-width: 1025px) {
  .page-hero--carousel.page-hero--portrait-video { min-height: var(--hero-band-height); }
}

/* ── FÜLL-EBENE (.bm-media-fill) — Komponente, Macro: images.html.jinja ───────
   Füllt die Pillarbox eines contain-gezeigten Mediums mit einer weich
   unscharfen, abgedunkelten Kopie DESSELBEN Frames. Sie ist dekorativ
   (aria-hidden) und lädt KEINE zweite Datei: identisches srcset+sizes wie das
   scharfe Medium → derselbe Kandidat, ein Request. Liegt per z-index unter dem
   scharfen Medium; blur() wird am Rand weich, deshalb der leichte Maßstab +
   overflow:hidden. Konsumenten: Karussell-Video-Slide und gestackter
   Video-Hero (.bm-hero-media--portrait).

   SELBSTTRAGEND und bewusst WEIT UNTEN in der Datei: die Bänder darüber
   adressieren ihre Medien generisch (`.page-hero-bg--video picture img`,
   `.bm-hero-slide picture img`) und träfen sonst auch diese Kopie. Gleiche
   Spezifität entscheidet die Quell-Reihenfolge — dieser Block MUSS nach den
   Band-Regeln stehen, sonst erbt die Füllung deren height/fit. */
.bm-media-fill {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.bm-media-fill picture {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%; height: 100%;
}
.bm-media-fill picture img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block;
  transform: scale(var(--hero-fill-scale));
  filter: blur(var(--hero-fill-blur)) brightness(var(--hero-fill-dim));
}

/* Bedienelemente erst sichtbar, wenn JS das Karussell aktiviert hat. */
.page-hero--carousel .bm-hero-dots,
.page-hero--carousel .bm-hero-carousel-pause,
.page-hero--carousel .bm-hero-nav { display: none; }
.page-hero--carousel.is-enhanced .bm-hero-dots { display: inline-flex; }
/* Pause/Play-Button NUR sichtbar, während die VIDEO-Slide aktiv ist — auf Bild-
   Slides ist er sinnlos (Pause gehört zum Video). JS togglet .is-video-slide am
   Karussell beim Slide-Wechsel; der Button fadet sanft ein/aus und fängt im
   ausgeblendeten Zustand keine Klicks ab (visibility:hidden). */
.page-hero--carousel.is-enhanced .bm-hero-carousel-pause {
  display: inline-flex;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease, background 0.2s ease;
}
.page-hero--carousel.is-enhanced.is-video-slide .bm-hero-carousel-pause {
  opacity: 1;
  visibility: visible;
}

/* ── Dots (Sprungziele + Fortschritts-Indikator) ──────────────── */
.bm-hero-dots {
  position: absolute;
  left: 50%;
  bottom: var(--space-5);
  transform: translateX(-50%);
  z-index: 4;                       /* über Scrim UND Content */
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--scrim-overlay-soft);
  -webkit-backdrop-filter: blur(var(--blur-sm));
  backdrop-filter: blur(var(--blur-sm));
}
.bm-hero-dot {
  position: relative;
  width: 10px; height: 10px;
  padding: 0; border: none;
  border-radius: var(--radius-full);
  background: var(--on-dark-text-faint);
  cursor: pointer;
  overflow: hidden;
  transition: width 0.3s ease, background 0.25s ease;
}
.bm-hero-dot:hover { background: var(--on-dark-text-high); }
.bm-hero-dot:focus-visible { outline: 2px solid var(--on-dark-text); outline-offset: 2px; }
/* Aktiver Dot = Pille; ein weißer Balken füllt sie über das Auto-Advance-
   Intervall (CSS-Animation, vom JS via --hero-carousel-interval getaktet). */
.bm-hero-dot.is-active {
  width: 30px;
  background: var(--on-dark-border-glass);
}
.bm-hero-dot__fill {
  position: absolute;
  inset: 0;
  width: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background: var(--on-dark-text);
  border-radius: inherit;
}
.page-hero--carousel.is-enhanced:not(.is-paused) .bm-hero-dot.is-active .bm-hero-dot__fill {
  animation: bm-hero-dot-fill var(--hero-carousel-interval) linear forwards;
}
.page-hero--carousel.is-paused .bm-hero-dot.is-active .bm-hero-dot__fill {
  animation-play-state: paused;
}
@keyframes bm-hero-dot-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ── Cursor-folgender Prev/Next-Button (NUR Desktop, via JS) ──────
   Spiegelt .bm-hero-pause--follow: pointer-events:none (blockiert nie
   Dots/CTA/Links), Position über GPU-transform, Sichtbarkeit per .is-visible.
   Die Pfeilrichtung togglet das JS (.is-prev/.is-next) nach Maus-Hälfte. */
.bm-hero-nav {
  position: absolute;
  left: 0; top: 0;
  z-index: var(--z-overlay);
  width: 66px; height: 66px;
  display: inline-flex;
  align-items: center; justify-content: center;
  padding: 0; border: none;
  border-radius: var(--radius-full);
  background: var(--scrim-control);
  color: var(--on-dark-text);
  -webkit-backdrop-filter: blur(var(--blur-sm));
  backdrop-filter: blur(var(--blur-sm));
  transform: translate3d(calc(var(--bm-nav-x, 0px) - 50%), calc(var(--bm-nav-y, 0px) - 50%), 0);
  pointer-events: none;             /* Klick geht durch → section-Handler togglet */
  opacity: 0;
  transition: opacity 0.18s ease, background 0.2s ease;
  will-change: transform;
}
.page-hero--carousel.is-enhanced .bm-hero-nav { display: inline-flex; }
.bm-hero-nav.is-visible { opacity: 1; }
.bm-hero-nav__icon {
  position: absolute;
  width: 30px; height: 30px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.bm-hero-nav.is-prev .bm-hero-nav__prev { opacity: 1; }
.bm-hero-nav.is-next .bm-hero-nav__next { opacity: 1; }
/* Kein Pause/Play-Button beim Bild-Karussell — der gehört NUR zum Video-Hero
   (.bm-hero-pause via hero_video). Bild-Karussell: nur Dots + cursor-Nav. */

/* reduced-motion: kein Crossfade (harter Schnitt), kein Dot-Fortschritt, kein
   Auto-Advance (JS-seitig). Manuelle Navigation (Dots/Swipe) bleibt nutzbar. */
@media (prefers-reduced-motion: reduce) {
  .bm-hero-slide { transition: none; }
  .bm-hero-dot__fill { animation: none !important; transform: scaleX(0); }
}

/* Touch/Coarse: kein cursor-folgender Button; Dots größer für Daumen-Tap. */
@media (hover: none), (pointer: coarse) {
  .bm-hero-nav { display: none !important; }
  .bm-hero-dot { width: 12px; height: 12px; }
  .bm-hero-dot.is-active { width: 34px; }
}

/* ════════════════════════════════════════════════════════════════
   MOBIL-SOLO BILD-HERO  (≤767px) — SWITCH: page_hero(mobile_solo=…, Default an)
   ════════════════════════════════════════════════════════════════
   Auf Mobil wird der BILD-/Karussell-Hero GESTACKT wie der Video-Hero der
   Startseite: Bild als freistehendes Querformat-Band OBEN (ohne Text-Overlay),
   Text-Panel darunter auf dunklem Grund. Die FESTE Band-Höhe (--hero-solo-band =
   16:9 der vollen Breite) verhindert den harten Hochformat-Crop UND jedes
   Quer↔Hoch-Springen. Das Macro setzt .page-hero--msolo nur für BILD-/Karussell-
   Heroes; Video-Heroes (.page-hero--video) sind ohnehin gestackt und bleiben
   unberührt. Reines CSS, 0 Extra-Bytes. Muster spiegelt bewusst den gestackten
   Video-Hero-Block oben (.hero/.page-hero--video). Wisch-Navigation ist bereits
   verdrahtet (window.bmBindSwipe an der Section, geteilte SSOT-Geste wie Jobs-
   Carousel & Lightbox) — greift auf dem Band automatisch. Ab 768px greift wieder
   der bewährte Cover-Overlay-Look. Deaktivieren: mobile_solo=false. */
@media (max-width: 767px) {
  .page-hero--msolo {
    flex-direction: column;
    align-items: stretch;
    height: auto;
    min-height: 0;                       /* schlägt .page-hero(-short)/--adaptive */
    padding-bottom: 0;                   /* Content-Panel steuert die Unterkante */
    background: var(--color-primary-dark);
  }
  /* Bild/Karussell-Band: in-flow, feste 16:9-Höhe (EIN Token), kein Ken-Burns. */
  .page-hero--msolo .page-hero-bg {
    position: relative;
    inset: auto;
    width: 100%;
    height: var(--hero-solo-band);
    transform: none;
    background: var(--hero-media-backdrop);
  }
  .page-hero--msolo:hover .page-hero-bg { transform: none; }
  .page-hero--msolo .page-hero-bg picture,
  .page-hero--msolo .page-hero-bg picture img { height: 100%; }
  /* Scrim/Overlay weg — Text steht auf dem dunklen Panel darunter. */
  .page-hero--msolo .page-hero-overlay { display: none; }
  /* Text-Panel unter dem Band: vertikale Luft. */
  .page-hero--msolo .page-hero-content {
    padding-top: var(--space-7);
    padding-bottom: var(--space-10);
  }
  /* Karussell-Dots liegen ÜBER dem Band (unten mittig) statt darunter → spart
     vertikalen Platz, gleiche Optik wie Desktop. Die Dots bleiben absolut zur
     Section (Basis: .bm-hero-dots), verankert an der Band-Unterkante via denselben
     Token wie die Band-Höhe (SSOT) — das Band ist das oben bündige erste Kind. */
  .page-hero--msolo .bm-hero-dots {
    top: calc(var(--hero-solo-band) - var(--space-10));
    bottom: auto;
  }
  /* …und GENAUSO die WCAG-2.2.2-Pause: sie gehört AUF das Video, nicht unter den
     Text. Der Button liegt (wie Dots/Nav) als Bedien-Layer ÜBER dem Scrim, ist
     also absolut zur SECTION positioniert — deren Unterkante ist im gestackten
     Solo-Layout der Fuß des TEXT-Panels. Das basis-`bottom` setzte ihn damit
     ~450 px UNTER das Band, mitten in den Fließtext (gemessen 2026-08-04 bei
     390 px). Verankerung an der Band-Unterkante über denselben Band-Token wie
     die Dots (SSOT): Bandhöhe − Buttonhöhe − Rand. */
  .page-hero--msolo .bm-hero-carousel-pause {
    top: calc(var(--hero-solo-band) - var(--hero-control-size) - var(--space-4));
    bottom: auto;
  }

  /* ── Solo-Band mit HOCHFORMAT-Medium in der Sequenz ───────────────────────
     Ein hochkanter Clip wird ganz gezeigt (contain, s. Hochformat-Block oben) —
     dann ist er nur so BREIT, wie das Band HOCH ist. Im 16:9-Band blieben davon
     45 % der Breite, im 4:3-Band sind es 60 %: das Motiv bekommt Präsenz, ohne
     dass die Höhe pro Slide springen müsste (ein wechselndes Band würde das
     Text-Panel bei jedem Auto-Advance verschieben). Preis sind ~11 % Randbeschnitt
     an den Querformat-Bildern derselben Sequenz — bewusst, weil sie den Beschnitt
     vertragen und der Clip ihn nicht verträgt. Greift nur auf Seiten mit
     Hochformat-Medium. Bandhöhe UND Dot-Verankerung teilen EINEN Token. */
  .page-hero--msolo.page-hero--portrait-video .page-hero-bg {
    height: var(--hero-solo-band-portrait);
  }
  .page-hero--msolo.page-hero--portrait-video .bm-hero-dots {
    top: calc(var(--hero-solo-band-portrait) - var(--space-10));
  }
  .page-hero--msolo.page-hero--portrait-video .bm-hero-carousel-pause {
    top: calc(var(--hero-solo-band-portrait) - var(--hero-control-size) - var(--space-4));
  }

  /* ── Kompakte Mobil-Breadcrumb (ALLE .page-hero) ─────────────────────────
     Der volle Pfad (Start / Ebene / langer aktueller Titel) frisst auf Mobil bis
     zu drei Zeilen. Champions-League-Lösung: nur die DIREKTE Elternebene als
     Zurück-Link „‹ Eltern" zeigen; Zwischenstufen + der (oft sehr lange) aktuelle
     Titel entfallen — die H1 direkt darunter benennt die Seite ohnehin. Reines
     CSS auf dem bestehenden Breadcrumb-Markup (kein Macro-Umbau). */
  .page-hero .breadcrumb { margin-bottom: var(--space-3); }
  .page-hero .breadcrumb > * { display: none; }         /* Trail + aktueller Titel aus */
  .page-hero .breadcrumb a:last-of-type {               /* nur die Elternebene */
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--on-dark-text);
  }
  .page-hero .breadcrumb a:last-of-type::before {
    content: "\2039";                                    /* ‹ Zurück-Chevron */
    font-size: 1.2em;
    line-height: 1;
  }
}

/* ── Legal Pages ──────────────────────────────────────────── */
.legal-container {
  max-width: 800px !important;
}
.legal-page h1 {
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: var(--font-weight-black);
  margin-bottom: var(--space-2);
}
.legal-updated { font-size: var(--text-sm); color: var(--color-text-muted); margin-bottom: var(--space-10); }
.legal-page h2 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--font-weight-bold);
  margin-top: var(--space-10);
  margin-bottom: var(--space-4);
  color: var(--color-heading);
}
.legal-page h3 { font-size: var(--text-lg); font-weight: var(--font-weight-semibold); margin-top: var(--space-6); margin-bottom: var(--space-3); }
.legal-page p { color: var(--color-text-muted); line-height: var(--leading-relaxed); margin-bottom: var(--space-4); }
.legal-page ul { padding-left: var(--space-6); list-style: disc; color: var(--color-text-muted); }
.legal-page ul li { margin-bottom: var(--space-2); line-height: var(--leading-relaxed); }
.legal-page address { color: var(--color-text-muted); line-height: 1.8; margin-bottom: var(--space-6); }
.legal-page a { color: var(--color-accent-text); text-decoration: none; }
.legal-page a:hover { text-decoration: underline; }
.legal-download-box {
  display: flex; align-items: center; gap: var(--space-4);
  background: var(--color-bg-alt); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-5) var(--space-6);
  margin: var(--space-8) 0; flex-wrap: wrap;
}
.legal-download-box > i { font-size: 2rem; color: var(--color-accent-text); flex-shrink: 0; }
/* flex-basis muss > 0 sein, sonst schrumpft die Textspalte neben dem Button auf
   ~0px und der Text läuft heraus (Mobile). Mit echter Basis bricht die Zeile
   stattdessen um und der Text bekommt die volle Breite. */
.legal-download-box > div { flex: 1 1 14rem; min-width: 0; }
.legal-download-box > div strong { display: block; margin-bottom: var(--space-1); }
.legal-download-box > div p { margin: 0; font-size: var(--text-sm); }
.legal-notice-box {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--color-warning-bg); border-left: 4px solid var(--color-warning);
  border-radius: var(--radius-md); padding: var(--space-4) var(--space-5);
  margin: var(--space-6) 0;
}
.legal-notice-box > i { color: var(--color-warning); margin-top: 2px; flex-shrink: 0; }
.legal-notice-box p { margin: 0; font-size: var(--text-sm); color: var(--color-text-muted); }
/* Rechtsverbindlichkeits-Hinweis auf übersetzten Rechtsseiten (Nicht-DE): die deutsche
   Fassung ist verbindlich, die Übersetzung dient der Orientierung. Neutral-akzentuiert. */
.legal-translation-notice {
  background: var(--color-bg-alt); border-left: 4px solid var(--color-accent-text);
  border-radius: var(--radius-md); padding: var(--space-4) var(--space-5);
  margin: var(--space-6) 0;
}
.legal-translation-notice p { margin: 0 0 var(--space-2); font-size: var(--text-sm); }
.legal-translation-notice a { font-weight: var(--font-weight-semibold); }
/* .breadcrumb-light entfernt: nie an ein Template verdrahtet (0 Nutzer) — der
   frühere Anlauf, den Breadcrumb auf heller Fläche lesbar zu machen. Die Basisregel
   von .breadcrumb flippt das jetzt selbst, siehe dort. */

/* ── Footer ───────────────────────────────────────────────── */
.site-footer {
  background: var(--color-primary-dark);
  color: var(--color-text-inverse);
}
.footer-container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-16) var(--space-6);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-10);
}
/* Prevent a long word in any language from blowing out a grid track (min-width:auto default). */
.footer-container > * { min-width: 0; }
@media (min-width: 640px) { .footer-container { grid-template-columns: var(--grid-track-fluid) var(--grid-track-fluid); } }
@media (min-width: 1024px) { .footer-container { grid-template-columns: 2fr 1fr 1fr 1fr; } }

.footer-logo { height: 36px; width: auto; margin-bottom: var(--space-4); }
.footer-tagline { font-size: var(--text-sm); color: var(--on-dark-text-muted); margin-bottom: var(--space-5); }
.footer-address { font-size: var(--text-sm); color: var(--on-dark-text-muted); line-height: 1.7; margin-bottom: var(--space-5); }
.footer-contact-links { display: flex; flex-direction: column; gap: var(--space-2); }
.footer-contact-link {
  display: inline-flex;
  align-items: center;
  align-self: flex-start; /* don't stretch to full column width */
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--on-dark-text-muted);
  text-decoration: none;
  position: relative;
  padding-bottom: 2px;
  transition: color var(--transition-fast);
}
.footer-contact-link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: calc(16px + var(--space-2)); /* skip icon (16px) + gap (8px) */
  right: 0;
  height: 1.5px;
  background: var(--color-accent-light);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s cubic-bezier(.25,.46,.45,.94);
}
.footer-contact-link:is(:hover, :focus-visible) {
  color: var(--color-accent-text);
}
.footer-contact-link:is(:hover, :focus-visible)::after {
  transform: scaleX(1);
}
.footer-social {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.footer-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-full);
  background: var(--on-dark-surface);
  color: var(--on-dark-text-muted);
  font-size: var(--text-base);
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
}
.footer-social-link:hover {
  background: var(--color-accent);
  color: var(--on-dark-text);
  transform: translateY(-2px);
}
.footer-contact-link .fas { color: var(--color-accent-text); width: 16px; }

/* Herkunfts-Badge („Made in Germany"). Der Text lebt in config/claims.yaml
   (made_in_germany), nicht hier — dieses Regelwerk macht nur die Form. */
.footer-origin {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-5);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--on-dark-border);
  border-radius: var(--radius-full);
  background: var(--on-dark-surface-faint);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--on-dark-text-soft);
}

.footer-section-title {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--on-dark-text-muted);
  margin-bottom: var(--space-4);
}
.footer-links { display: flex; flex-direction: column; gap: var(--space-2); }
.footer-link {
  font-size: var(--text-sm);
  color: var(--on-dark-text-muted);
  text-decoration: none;
  display: inline-block;
  overflow-wrap: break-word;
  background-image: linear-gradient(var(--color-accent-light), var(--color-accent-light));
  background-repeat: no-repeat;
  background-position: 0% 100%;
  background-size: 0% 1.5px;
  padding-bottom: 2px;
  transition: color var(--transition-fast), background-size 0.28s cubic-bezier(.25,.46,.45,.94);
}
.footer-link:is(:hover, :focus-visible) {
  color: var(--color-accent-text);
  background-size: 100% 1.5px;
}

.footer-bottom {
  border-top: 1px solid var(--color-gray-800);
}
.footer-bottom-inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-5) var(--space-6);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.footer-copy { font-size: var(--text-sm); color: var(--on-dark-text-subtle); overflow-wrap: break-word; }
.footer-legal-links { display: flex; flex-wrap: wrap; gap: var(--space-6); min-width: 0; }
.footer-legal-links a {
  font-size: var(--text-sm);
  color: var(--on-dark-text-subtle);
  text-decoration: none;
  display: inline-block;
  background-image: linear-gradient(var(--color-accent-light), var(--color-accent-light));
  background-repeat: no-repeat;
  background-position: 0% 100%;
  background-size: 0% 1px;
  padding-bottom: 1px;
  transition: color var(--transition-fast), background-size 0.28s cubic-bezier(.25,.46,.45,.94);
}
.footer-legal-links a:is(:hover, :focus-visible) {
  color: var(--color-accent-text);
  background-size: 100% 1px;
}

/* ── Cookie-Consent-Banner ────────────────────────────────── */
.bm-cc-banner {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  width: 100%;
  background: var(--color-bg);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -6px 24px rgb(var(--c-black) / 0.12);
  z-index: var(--z-toast);
  font-family: var(--font-base);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}
.bm-cc-inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-4) var(--space-6);
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
}
.bm-cc-text-block { flex: 1; min-width: 240px; }
.bm-cc-title {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin: 0 0 var(--space-2);
}
.bm-cc-copy {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
.bm-cc-link { color: var(--color-accent-text); text-decoration: underline; }
.bm-cc-more-btn {
  display: inline-block;
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  text-decoration: underline;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color var(--transition-fast);
}
.bm-cc-more-btn:hover { color: var(--color-text); }
.bm-cc-details {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.bm-cc-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-2) 0;
}
.bm-cc-toggle input[type="checkbox"] {
  width: 1rem; height: 1rem;
  flex-shrink: 0;
  accent-color: var(--color-accent);
  cursor: pointer;
}
.bm-cc-service-label {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  font-size: var(--text-sm);
  cursor: pointer;
}
.bm-cc-service-desc {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
/* Mobile: zentrierte Karte */
@media (max-width: 640px) {
  .bm-cc-banner {
    left: 50%;
    right: auto;
    bottom: 12px;
    transform: translateX(-50%);
    width: min(92vw, 360px);
    border-radius: var(--radius-xl);
    border-top: none;
    box-shadow: 0 10px 30px rgb(var(--c-black) / 0.18);
  }
  .bm-cc-inner {
    padding: var(--space-4) var(--space-5);
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
  }
}

/* ── Animations ───────────────────────────────────────────── */
/* Reveal-on-scroll nur wenn JS aktiv ist (Klasse `js` auf <html>, inline in
   base.html.jinja gesetzt). OHNE JS greift keine dieser Regeln → Inhalt bleibt
   sichtbar (kein opacity:0-Blackout, wichtig für Crawler & JS-lose Nutzer). */
.js [data-animate] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.js [data-animate="fade-right"] { transform: translateX(-30px); }
.js [data-animate="fade-left"]  { transform: translateX(30px); }
.js [data-animate="fade-up"]    { transform: translateY(30px); }
/* Ruhezustand nach dem Reveal. `transform` MUSS hier `none` sein, nicht
   `translate(0)`: JEDER Transform-Wert ≠ none — auch die Identität — macht das
   Element zum Containing Block für `position:absolute`-Nachfahren. Ein
   Reveal-Wrapper (`.two-col-text`, `.section-media__body`, `.mpk-recruit__text`)
   fing damit das `inset:0`-Overlay des `.card-stretched-link` ein → von der Karte
   waren nur 12–37 % klickbar (gemessen 2026-08-03: Maschinenpark-Teaser auf `/`
   12 %). `none` interpoliert als Identität, die Fade/Slide-Transition bleibt also
   unverändert. Guard: tests/styling/test_stretched_link_containing_block.py */
[data-animate].is-visible {
  opacity: 1;
  transform: none;
}
/* Bewegungsreduktion respektieren: Inhalt sofort sichtbar, keine Fade/Slide-Animation. */
@media (prefers-reduced-motion: reduce) {
  .js [data-animate] { opacity: 1; transform: none; transition: none; }
}
/* Windows-Kontrastmodus / forced-colors: sichtbaren Fokusrahmen erzwingen, auch dort wo
   sonst outline:none + box-shadow-Glow genutzt wird (Glow ist im Kontrastmodus unsichtbar). */
@media (forced-colors: active) {
  a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible,
  select:focus-visible, [tabindex]:focus-visible, .form-file-trigger:focus-visible {
    outline: 2px solid Highlight !important;
    outline-offset: 2px;
  }
}

/* ── Responsive Utilities ─────────────────────────────────── */
@media (max-width: 640px) {
  .hero-stats { gap: var(--space-6); }
  .stat-value { font-size: var(--text-2xl); }
  .section { padding: var(--space-16) 0; }
  .scroll-to-top { right: 1rem; bottom: 1rem; }
  .karriere-banner { padding: var(--space-8); }
  /* Stacked, centered bottom bar: stretch lets the copyright wrap to full width
     (instead of growing to max-content and clipping); legal/cookie links center. */
  .footer-bottom-inner { flex-direction: column; align-items: stretch; text-align: center; }
  .footer-legal-links { justify-content: center; }
}

/* ── UA-Layer: explizit token-gebunden statt allein auf color-scheme:dark verlassen ──
   variables.css setzt color-scheme:dark → Scrollbars/Selects/Picker themen automatisch.
   Die text-nahen UA-Pseudos hier trotzdem explizit an die (flippenden) Tokens binden, damit
   sie in JEDEM Browser lesbar bleiben, auch falls color-scheme je entfällt (die eine
   ungeguardete Fragilitäts-Naht, die das Panel fand). */
::selection { background: rgb(var(--c-red) / 0.85); color: var(--color-text-inverse); }
::placeholder { color: var(--color-text-muted); opacity: 1; }
:-webkit-autofill,
:-webkit-autofill:hover,
:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--color-text);
  caret-color: var(--color-text);
  transition: background-color 100000s ease-in-out 0s; /* Chrome-Autofill-Fläche neutralisieren → Feld-Tokens bleiben sichtbar */
}

@media print {
  .navbar, .bm-cc-banner, .hero-dots, .scroll-to-top { display: none !important; }
  .hero { height: auto; min-height: 0; }
  .hero-content { padding-top: 0; }
  /* Dark-Mode-Nutzer drucken auf WEISSES Papier → die Dark-Palette (near-weiße Schrift)
     wäre weiß-auf-weiß = unsichtbar. Für den Druck theme-unabhängig die helle Palette
     erzwingen (Kanäle NICHT invertiert, Kontext-Tokens auf hell). */
  :root[data-theme="dark"] {
    color-scheme: light;
    --color-bg: rgb(var(--c-white)); --color-bg-alt: rgb(var(--c-white));
    --color-text: rgb(var(--c-ink)); --color-text-muted: rgb(var(--c-gray-600));
    --color-heading: rgb(var(--c-navy)); --color-border: rgb(var(--c-gray-300));
  }
}

/* ── Kontaktformular Feedback-Banner ──────────────────────── */
.form-banner {
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-6);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}
.form-banner a { color: inherit; font-weight: var(--font-weight-semibold); }
.form-banner-success {
  background: var(--color-success-bg);
  border: 1px solid var(--color-success-border);
  color: var(--color-success-dark);
}
.form-banner-error {
  background: var(--color-error-bg);
  border: 1px solid var(--color-error-border);
  color: var(--color-error-dark);
}

/* ── Form Label Hint ──────────────────────────────────────── */
.form-label-hint {
  font-weight: var(--font-weight-normal);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

/* ── File Upload Zone ─────────────────────────────────────── */
.form-upload-zone {
  border: 2px dashed var(--field-border);
  border-radius: var(--field-radius);
  padding: var(--space-8) var(--space-6);
  text-align: center;
  cursor: pointer;
  transition:
    border-color var(--glow-speed) var(--glow-ease),
    background var(--glow-speed) var(--glow-ease),
    box-shadow var(--glow-speed) var(--glow-ease),
    transform var(--glow-speed) var(--glow-ease);
  background: var(--color-bg-alt);
  box-shadow: var(--field-shadow);
  position: relative;
  outline: none;
}
.form-upload-zone:hover {
  border-color: var(--field-hover-border);
  background: var(--field-hover-bg);
  box-shadow: var(--upload-hover-shadow);
  transform: translate3d(0, -1px, 0);
}
.form-upload-zone.is-dragover {
  border-color: var(--field-hover-border);
  background: var(--field-hover-bg);
  box-shadow: var(--upload-hover-shadow);
  transform: translate3d(0, -1px, 0);
}
.form-upload-zone:focus-visible {
  outline: none;
  border-color: var(--field-hover-border);
  box-shadow: var(--field-hover-shadow);
}
.form-upload-zone input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  width: 100%;
  height: 100%;
}
.form-upload-inner { pointer-events: none; }
.form-upload-icon {
  font-size: 2rem;
  color: var(--color-accent-text);
  margin-bottom: var(--space-2);
}
.form-upload-label {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
}
.form-upload-label strong { color: var(--color-accent-text); }
.form-upload-hint {
  font-size: var(--text-xs);
  color: var(--color-text-light);
  margin: var(--space-1) 0 0;
}
.form-file-list {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.form-file-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}
.form-file-icon { color: var(--color-accent-text); flex-shrink: 0; width: 18px; text-align: center; }
.form-file-name { flex: 1; color: var(--color-text); font-weight: var(--font-weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.form-file-size { color: var(--color-text-muted); font-size: var(--text-xs); flex-shrink: 0; }
.form-file-remove {
  flex-shrink: 0;
  color: var(--color-text-muted);
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 2px 5px;
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast), background var(--transition-fast);
}
.form-file-remove:hover { color: var(--color-error-strong); background: var(--color-error-bg); }
.form-file-item.form-file-error { border-color: var(--color-error-border); background: var(--color-error-bg-soft); }
.form-file-item.form-file-error .form-file-icon { color: var(--color-error-strong); }

/* ── Toast Notification ───────────────────────────────────── */
.bm-toast-container {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column-reverse;
  gap: var(--space-3);
  pointer-events: none;
}
.bm-toast {
  position: relative;
  min-width: 300px;
  max-width: 420px;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xl);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  pointer-events: all;
  overflow: hidden;
  transform: translateX(120%);
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  background: var(--color-bg);
  border-left: 4px solid var(--color-accent);
}
.bm-toast.is-visible { transform: translateX(0); }
.bm-toast--success { border-left-color: var(--color-success); }
.bm-toast--error   { border-left-color: var(--color-error); }
.bm-toast--warning { border-left-color: var(--color-warning); }
.bm-toast-icon { font-size: var(--text-xl); flex-shrink: 0; line-height: 1.2; }
.bm-toast--success .bm-toast-icon { color: var(--color-success); }
.bm-toast--error   .bm-toast-icon { color: var(--color-error); }
.bm-toast--warning .bm-toast-icon { color: var(--color-warning); }
.bm-toast-body { flex: 1; min-width: 0; }
.bm-toast-title { font-weight: var(--font-weight-semibold); color: var(--color-text); margin-bottom: 2px; }
.bm-toast-msg { color: var(--color-text-muted); }
.bm-toast-msg a { color: var(--color-accent-text); }
.bm-toast-close {
  flex-shrink: 0;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  font-size: var(--text-xl);
  line-height: 1;
  padding: 0;
  margin-top: -2px;
  transition: color var(--transition-fast);
}
.bm-toast-close:hover { color: var(--color-text); }
.bm-toast-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 3px;
  background: currentColor;
  opacity: 0.25;
  animation: bm-progress linear forwards;
}
.bm-toast--success .bm-toast-progress { color: var(--color-success); }
.bm-toast--error   .bm-toast-progress { color: var(--color-error); }
.bm-toast--warning .bm-toast-progress { color: var(--color-warning); }
@keyframes bm-progress {
  from { width: 100%; }
  to   { width: 0%; }
}
@media (max-width: 640px) {
  .bm-toast-container { left: var(--space-4); right: var(--space-4); bottom: var(--space-4); }
  .bm-toast { min-width: 0; max-width: 100%; }
}

/* ── Über uns: Zahlen-Leiste ─────────────────────────────────
   Volle Breite, Primärfarben-Hintergrund, 6 KPI-Felder
   ─────────────────────────────────────────────────────────── */
/* ── Über uns: Zahlen-Leiste ─────────────────────────────────
   10/10 Champions League UX: Premium animated numbers with
   generous spacing, perfect typography, glassmorphism, and
   sophisticated micro-interactions. Enterprise-grade design.
   ─────────────────────────────────────────────────────────── */
.numbers-section {
  position: relative;
  padding: clamp(6rem, 10vw, 10rem) 0;
  background:
    radial-gradient(circle at 10% 50%, rgb(var(--c-red) / 0.05), transparent 45%),
    radial-gradient(circle at 90% 50%, rgb(var(--c-info) / 0.04), transparent 45%),
    linear-gradient(180deg, var(--color-bg), var(--color-bg-alt));
  overflow: hidden;
  contain: layout style;
}

.numbers-section::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(105deg, transparent 0%, rgb(var(--c-red) / 0.015) 30%, transparent 60%, rgb(var(--c-info) / 0.015) 90%);
  opacity: 1;
  animation: gradientShift 20s ease-in-out infinite;
}

@keyframes gradientShift {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.85; }
}

.numbers-bar {
  /* Count-aware Layout: `data-count="N"` (Template) → `--cols` steuert die
     Spaltenzahl je Breakpoint. Flex + `max-width == flex-basis == 1/cols` +
     `justify-content:center` = volle Reihen füllen kantenbündig, eine unvoll-
     ständige LETZTE Reihe wird ZENTRIERT (nie ein über die volle Breite
     gestreckter Einzel-„Orphan", nie eine Lücke rechts). Gilt für JEDE Claim-
     Anzahl. `--cols`-Defaults + `[data-count]`-Overrides unten wählen die
     ausgewogenste Zeilenteilung (5 → eine Reihe, 7 → 4+3, 6 → 3+3 …). */
  --cols: 5;
  --nb-gap: var(--space-5);
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: var(--nb-gap);
  padding: var(--space-6);
  border-radius: 32px;
  background:
    linear-gradient(135deg, var(--color-accent-bg), var(--color-primary-bg));
  box-shadow:
    0 24px 80px rgb(var(--c-shadow) / 0.08),
    0 10px 32px rgb(var(--c-shadow) / 0.05),
    inset 0 1px 0 rgb(var(--c-white) / 0.6);
}

/* WIDE (>1280): bis zu 5 pro Reihe, Zeilen so gleichmäßig wie möglich. */
.numbers-bar[data-count="1"] { --cols: 1; }
.numbers-bar[data-count="2"] { --cols: 2; }
.numbers-bar[data-count="3"] { --cols: 3; }
.numbers-bar[data-count="4"] { --cols: 4; }
.numbers-bar[data-count="6"] { --cols: 3; }  /* 3+3 statt 5+1 */
.numbers-bar[data-count="7"] { --cols: 4; }  /* 4+3 statt 5+2 */
.numbers-bar[data-count="8"] { --cols: 4; }  /* 4+4 */

.number-item {
  position: relative;
  /* Flex-Item: exakt 1/cols breit (basis == max-width) → volle Reihen füllen
     kantenbündig; eine unvollständige letzte Reihe behält die Kartenbreite und
     wird durch `justify-content:center` am Bar zentriert. `min-width:0` erlaubt
     das Schrumpfen auf die Basis (sonst zwingt Content-min-width Überlauf). */
  flex: 1 1 calc((100% - (var(--cols) - 1) * var(--nb-gap)) / var(--cols));
  max-width: calc((100% - (var(--cols) - 1) * var(--nb-gap)) / var(--cols));
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 240px;
  padding: var(--space-8) var(--space-4);
  background:
    linear-gradient(135deg, var(--color-bg), var(--color-bg-alt));
  border: 1px solid var(--on-dark-border-bright);
  border-radius: 28px;
  overflow: hidden;
  transition:
    opacity 750ms cubic-bezier(0.34, 1.56, 0.64, 1),
    transform 750ms cubic-bezier(0.34, 1.56, 0.64, 1),
    background-color 350ms ease,
    box-shadow 350ms ease,
    border-color 350ms ease;
  will-change: opacity, transform;
  contain: layout style paint;
}

/* Entrance-Reveal = JS-Progressive-Enhancement (Haus-Konvention `.js`, analog
   `.js [data-animate]`): OHNE JS bleiben ALLE Karten sichtbar. Der versteckte
   Startzustand gilt nur solange die Karte noch nicht enthüllt ist. Vorher hing
   die Sichtbarkeit an `is-counted`, das NUR zählende Figuren bekamen → nicht-
   numerische Claim-Karten (EXC3, „25 × 7 × 6 m") blieben dauerhaft opacity:0
   (unsichtbare Lücken). Jetzt enthüllt main.js JEDE Karte beim Scroll-in. */
.js .number-item:not(.is-counted) {
  opacity: 0;
  transform: translate3d(0, 32px, 0) scale(0.94);
}

@media (prefers-reduced-motion: reduce) {
  .js .number-item:not(.is-counted) { opacity: 1; transform: none; }
}

/* Failsafe-Reveal: head-init.js setzt `.reveal-fallback`, wenn der deferred main.js
   nach der Karenzzeit noch nicht enthüllt hat (langsames Mobilnetz / Ladefehler).
   Spiegelt JEDE `.js …{opacity:0}`-Reveal-Sperre (data-animate + number-item), damit
   JS-versteckter Inhalt nie dauerhaft schwarz bleibt. BEWUSST nach den Sperr-Regeln →
   gewinnt per Quell-Reihenfolge, kein !important nötig. No-op sobald main.js normal
   enthüllt (`bm-enhanced`). */
.reveal-fallback [data-animate]:not(.is-visible),
.reveal-fallback .number-item:not(.is-counted) {
  opacity: 1;
  transform: none;
  transition: none;
}

.number-item::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 28px;
  padding: 1.5px;
  background: linear-gradient(135deg,
    rgb(var(--c-red) / 0.12),
    rgb(var(--c-info) / 0.08),
    rgb(var(--c-red) / 0.06));
  -webkit-mask:
    linear-gradient(rgb(var(--c-white)) 0 0) content-box,
    linear-gradient(rgb(var(--c-white)) 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 350ms ease;
  pointer-events: none;
}

.number-item:hover::before {
  opacity: 1;
}

.number-item::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 50%;
  height: 3px;
  background: linear-gradient(90deg,
    transparent,
    var(--color-accent) 50%,
    transparent);
  opacity: 0;
  transition: opacity 400ms ease, width 400ms ease;
  pointer-events: none;
}

.number-item:hover::after {
  opacity: 1;
  width: 90%;
}

.number-item:hover {
  background:
    linear-gradient(135deg, var(--color-bg), var(--color-bg-alt));
  border-color: rgb(var(--c-red) / 0.2);
  box-shadow:
    0 32px 96px rgb(var(--c-red) / 0.15),
    0 12px 40px rgb(var(--c-shadow) / 0.1),
    inset 0 1px 0 rgb(var(--c-white) / 0.95);
  transform: translate3d(0, -6px, 0) scale(1.02);
}

.number-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  margin-bottom: var(--space-7);
  color: var(--color-text-inverse);   /* weißes Icon auf rotem Kreis (currentColor → Stroke) */
  background:
    linear-gradient(135deg, var(--color-accent), var(--color-accent-light));
  border-radius: 50%;
  box-shadow:
    0 12px 32px rgb(var(--c-red) / 0.3),
    0 6px 16px rgb(var(--c-red) / 0.2),
    inset 0 2px 0 rgb(var(--c-white) / 0.25);
  transition: transform 450ms cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 350ms ease,
              filter 350ms ease;
}

.number-item:hover .number-icon {
  transform: scale(1.15) rotate(-8deg);
  box-shadow:
    0 16px 48px rgb(var(--c-red) / 0.4),
    0 8px 24px rgb(var(--c-red) / 0.25),
    inset 0 2px 0 rgb(var(--c-white) / 0.3);
  filter: brightness(1.08);
}

/* Markup ist ein Inline-<svg class="bm-icon"> (icon()-Makro), kein Font-<i>.
   .bm-icon-Basis ist 1em → braucht explizite Größe, sonst winzig im Kreis. */
.number-icon .bm-icon {
  width: 2.25rem;    /* ~50 % des 72px-Kreises */
  height: 2.25rem;
  filter: drop-shadow(0 2px 6px rgb(var(--c-black) / 0.2));
}

.number-figure {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2rem, 3.6vw, 3.8rem);
  font-weight: var(--font-weight-extrabold);
  line-height: 1.05;
  letter-spacing: var(--tracking-tighter);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  /* Lange, nicht-numerische Claim-Werte (z.B. "25 × 7 × 6 m" mit harten
     &nbsp;, oder "14.000 m²") müssen in der schmalen Karte UMBRECHEN statt vom
     `overflow:hidden` der Karte abgeschnitten zu werden. `overflow-wrap:anywhere`
     bricht notfalls auch die &nbsp;-Kette; kurze Werte ("50 t") bleiben einzeilig. */
  white-space: normal;
  overflow-wrap: anywhere;
  -webkit-hyphens: none;       /* Safari < 17 */
  hyphens: none;
  max-width: 100%;
  min-height: 1.1em;
  /* Verlaufs-Text (background-clip): components/effects.css `.u-text-gradient`
     — .number-figure ist dort als Konsument gelistet und setzt den Navy-Verlauf
     über --text-gradient. `color` oben bleibt als Fallback. */
  margin-bottom: var(--space-3);
  transition: transform 350ms ease;
}

.number-item:hover .number-figure {
  transform: scale(1.06);
}

.number-label {
  display: block;
  color: var(--color-text-muted);
  font-size: clamp(0.85rem, 1vw, 1.05rem);
  font-weight: var(--font-weight-semibold);
  line-height: var(--leading-normal);
  letter-spacing: var(--tracking-snug);
  text-align: center;
  max-width: 160px;
  transition: color 350ms ease;
}

.number-item:hover .number-label {
  color: var(--color-accent-text);
}

/* Stagger animation delays with longer duration */
.number-item:nth-child(1) { transition-delay: 0ms; }
.number-item:nth-child(2) { transition-delay: 100ms; }
.number-item:nth-child(3) { transition-delay: 200ms; }
.number-item:nth-child(4) { transition-delay: 300ms; }
.number-item:nth-child(5) { transition-delay: 400ms; }
.number-item:nth-child(6) { transition-delay: 500ms; }

/* ── Count-aware Spaltenlogik, Breakpoint-Overrides ─────────────────────────
   WICHTIG (Kaskade): Die Tier-Defaults nutzen `.numbers-bar[data-count]`
   (Spezifität 0,2,0) — NICHT das nackte `.numbers-bar` (0,1,0). Sonst würden
   die WIDE-Basis-Overrides `.numbers-bar[data-count="7"]` (0,2,0) die schmaleren
   Media-Defaults schlagen (Spezifität sticht Quellreihenfolge) und die Leiste
   bliebe z.B. bei 430 px mehrspaltig. Da alle Spalten-Regeln nun 0,2,0 haben,
   entscheidet die Quellreihenfolge: das schmalste zutreffende Tier gewinnt. */

/* MID (≤1280): max. 4 pro Reihe. N5 → 3+2 · N7 → 4+3 · N6 → 3+3. */
@media (max-width: 1280px) {
  .numbers-bar {
    --nb-gap: var(--space-4);
    padding: var(--space-5);
  }
  .numbers-bar[data-count]        { --cols: 4; }
  .numbers-bar[data-count="1"]    { --cols: 1; }
  .numbers-bar[data-count="2"]    { --cols: 2; }
  .numbers-bar[data-count="3"]    { --cols: 3; }
  .numbers-bar[data-count="5"]    { --cols: 3; }  /* 3+2 */
  .numbers-bar[data-count="6"]    { --cols: 3; }  /* 3+3 */

  .number-item {
    min-height: 220px;
    padding: var(--space-8) var(--space-7);
  }

  .number-icon {
    width: 64px;
    height: 64px;
    margin-bottom: var(--space-6);
  }

  .number-icon .bm-icon {
    width: 2rem;
    height: 2rem;
  }
}

/* SM (≤768): 2 pro Reihe (ungerade Anzahl → letzte Karte zentriert). */
@media (max-width: 768px) {
  .numbers-section {
    padding: clamp(4.5rem, 8vw, 7rem) 0;
  }

  .numbers-bar {
    --nb-gap: var(--space-4);
    padding: var(--space-4);
    border-radius: var(--radius-2xl);
  }
  .numbers-bar[data-count]        { --cols: 2; }
  .numbers-bar[data-count="1"]    { --cols: 1; }

  .number-item {
    min-height: 200px;
    padding: var(--space-7) var(--space-6);
    border-radius: var(--radius-lg);
  }

  .number-item::before {
    border-radius: var(--radius-lg);
  }

  .number-icon {
    width: 56px;
    height: 56px;
    margin-bottom: var(--space-5);
  }

  .number-icon .bm-icon {
    width: 1.75rem;
    height: 1.75rem;
  }

  .number-figure {
    font-size: clamp(2.2rem, 4.5vw, 5rem);
    margin-bottom: var(--space-2);
  }

  .number-label {
    font-size: clamp(0.8rem, 0.9vw, 0.95rem);
  }
}

/* XS (≤480): eine Spalte. */
@media (max-width: 480px) {
  .numbers-section {
    padding: clamp(3.5rem, 6vw, 5rem) 0;
  }

  .numbers-bar {
    --nb-gap: var(--space-3);
    padding: var(--space-3);
  }
  .numbers-bar[data-count]        { --cols: 1; }

  .number-item {
    min-height: 180px;
    padding: var(--space-6) var(--space-5);
    border-radius: 18px;
  }

  .number-item::before {
    border-radius: 18px;
  }

  .number-icon {
    width: 48px;
    height: 48px;
    margin-bottom: var(--space-4);
  }

  .number-icon .bm-icon {
    width: 1.5rem;
    height: 1.5rem;
  }

  .number-figure {
    font-size: clamp(2rem, 4vw, 4rem);
  }

  .number-label {
    font-size: 0.8rem;
    max-width: 140px;
  }
}

/* ── Über uns: section-subline (Intro-Text unter H2) ─────── */
.section-subline {
  max-width: 680px;
  margin: var(--space-4) auto 0;
  font-size: var(--text-lg);
  color: var(--color-text-muted);
  line-height: var(--leading-relaxed);
  text-align: center;
}

/* ── Über uns: Branchenkompetenz ─────────────────────────── */
.branchen-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-6);
  margin-top: var(--space-10);
}
.branchen-card {
  background: var(--on-dark-surface-faint);
  border: 1px solid var(--on-dark-border-faint);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  transition: background var(--transition-base), border-color var(--transition-base);
}
.branchen-card:has(a[href]):is(:hover, :focus-within) {
  background: var(--on-dark-surface);
  border-color: var(--color-accent);
}
.branchen-icon {
  font-size: 1.75rem;
  color: var(--color-accent-text);
  margin-bottom: var(--space-3);
  display: block;
}
.branchen-card h3 {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-bold);
  color: var(--on-dark-text);
  margin-bottom: var(--space-2);
}
.branchen-card p {
  font-size: var(--text-sm);
  color: var(--color-gray-400);
  line-height: var(--leading-relaxed);
  margin: 0;
}

/* ── FAQ Cards: nativer Accordion-Standard ────────────────── */
.faq-cards,
.bs-faq-cards,
.faq-section {
  --faq-bg: var(--color-bg);
  --faq-border: var(--color-border);
  --faq-text: var(--color-text);
  --faq-muted: var(--color-text-muted);
  --faq-accent: var(--color-accent);
  --faq-radius: var(--radius-lg);
  --faq-base-shadow: var(--card-shadow);
  --faq-hover-shadow: var(--card-shadow-hover-soft);
  --faq-open-border: color-mix(in srgb, var(--faq-accent) 14%, var(--faq-border));
  --faq-glow-opacity: 0.82;
  --faq-motion-duration: 320ms;
  --faq-motion-ease: cubic-bezier(0.16, 1, 0.3, 1);
  max-width: 900px;
  margin: var(--space-10) auto 0;
  min-width: 0;
}
.dark-section :is(.faq-cards, .bs-faq-cards, .faq-section),
:is(.faq-cards, .bs-faq-cards, .faq-section).is-dark {
  --faq-bg: var(--on-dark-surface-soft);
  --faq-border: var(--on-dark-border);
  --faq-text: var(--on-dark-text);
  /* on-dark (flippt NICHT); --color-gray-300 invertierte im Dark → grau-auf-dunkel 2.47:1 */
  --faq-muted: var(--on-dark-text-muted);
  --faq-base-shadow: none;
  --faq-hover-shadow: var(--card-shadow-hover-dark);
}
.faq-cards > h2,
.faq-cards > h3,
.bs-faq-cards > h2,
.bs-faq-cards > h3,
.faq-section > h2,
.faq-section > h3 {
  margin: 0 0 var(--space-5);
  color: var(--faq-text);
  font-family: var(--font-display);
  font-size: clamp(var(--text-2xl), 2.4vw, var(--text-4xl));
  line-height: var(--leading-tight);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-width: 0;
  max-width: 100%;
  margin: 0 0 var(--space-3);
  color: var(--faq-text);
  background: var(--faq-bg);
  border: 1px solid var(--faq-border);
  border-radius: var(--faq-radius);
  box-shadow: var(--faq-base-shadow);
  background-clip: padding-box;
  transition:
    border-color var(--glow-speed) var(--glow-ease),
    box-shadow var(--glow-speed) var(--glow-ease);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  background: var(--glow-layer-card);
  transition: opacity var(--glow-speed) var(--glow-ease);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details > * {
  position: relative;
  z-index: 1;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details[open] {
  border-color: var(--faq-open-border);
}
@media (hover: hover) {
  :is(.faq-cards, .bs-faq-cards, .faq-section) details:hover {
    z-index: 2;
    border-color: color-mix(in srgb, var(--faq-accent) 24%, var(--faq-border));
    box-shadow: var(--faq-hover-shadow);
  }
  :is(.faq-cards, .bs-faq-cards, .faq-section) details:hover::before {
    opacity: var(--faq-glow-opacity);
  }
}
:is(.faq-cards, .bs-faq-cards, .faq-section) summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
  margin: 0;
  padding: var(--space-5) var(--space-6);
  color: var(--faq-text);
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  line-height: var(--leading-snug);
  list-style: none;
  cursor: pointer;
  overflow-wrap: anywhere;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) summary::-webkit-details-marker {
  display: none;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) summary::marker {
  content: "";
}
:is(.faq-cards, .bs-faq-cards, .faq-section) summary::before {
  content: none;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) summary::after {
  content: "";
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--faq-accent);
  border-bottom: 2px solid var(--faq-accent);
  transform: rotate(45deg);
  transition:
    transform var(--glow-speed) var(--glow-ease),
    opacity var(--glow-speed) var(--glow-ease);
  opacity: 0.9;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details[open] summary::after {
  transform: rotate(225deg);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) summary:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--faq-accent) 42%, transparent);
  outline-offset: -3px;
  border-radius: calc(var(--faq-radius) - 2px);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--faq-accent) 18%, transparent);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body {
  box-sizing: border-box;
  display: block;
  padding: 0 var(--space-6) var(--space-5);
  color: var(--faq-muted);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  overflow-wrap: anywhere;
  transform: translate3d(0, 0, 0);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details[data-faq-animating] {
  z-index: 3;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details[data-faq-animating]::before {
  opacity: 0;
  transition-duration: 120ms;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) details[data-faq-animating] .faq-body {
  overflow: hidden;
  transition:
    height var(--faq-motion-duration) var(--faq-motion-ease),
    opacity var(--glow-speed) ease,
    transform var(--faq-motion-duration) var(--faq-motion-ease);
  will-change: height, opacity, transform;
}
@supports (interpolate-size: allow-keywords) and selector(details::details-content) {
  :root {
    interpolate-size: allow-keywords;
  }
  :is(.faq-cards, .bs-faq-cards, .faq-section) details::details-content {
    block-size: 0;
    overflow: hidden;
    opacity: 0;
    transform: translate3d(0, -4px, 0);
    transition:
      block-size var(--faq-motion-duration) var(--faq-motion-ease),
      opacity var(--glow-speed) ease,
      transform var(--faq-motion-duration) var(--faq-motion-ease);
  }
  :is(.faq-cards, .bs-faq-cards, .faq-section) details[open]::details-content {
    block-size: auto;
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body > *:first-child {
  margin-top: 0;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body > *:last-child {
  margin-bottom: 0;
}
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body p {
  margin: 0 0 var(--space-3);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body ul,
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body ol {
  margin: var(--space-2) 0 var(--space-3) var(--space-5);
  padding: 0;
  line-height: var(--leading-relaxed);
}
:is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body a {
  color: var(--color-accent-text);
  font-weight: var(--font-weight-semibold);
}
@media (max-width: 640px) {
  .faq-cards,
  .bs-faq-cards,
  .faq-section {
    margin-top: var(--space-8);
  }
  :is(.faq-cards, .bs-faq-cards, .faq-section) summary {
    padding: var(--space-4) var(--space-5);
    font-size: var(--text-base);
  }
  :is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body {
    padding: 0 var(--space-5) var(--space-4);
  }
}
@media (prefers-reduced-motion: reduce) {
  :is(.faq-cards, .bs-faq-cards, .faq-section) details,
  :is(.faq-cards, .bs-faq-cards, .faq-section) details::before,
  :is(.faq-cards, .bs-faq-cards, .faq-section) summary::after,
  :is(.faq-cards, .bs-faq-cards, .faq-section) .faq-body {
    transition-duration: 1ms;
  }
  @supports selector(details::details-content) {
    :is(.faq-cards, .bs-faq-cards, .faq-section) details::details-content {
      transition-duration: 1ms;
    }
  }
  :is(.faq-cards, .bs-faq-cards, .faq-section) details:hover {
    transform: none;
  }
}

/* Base card for article.faq-item grids (e.g. 3D plasma pipe FAQ).
   Override per page with a scoped selector. */
.faq-item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  background: var(--color-bg);
  box-shadow: var(--card-shadow);
}

/* ── Video Showcase ────────────────────────────────────────── */
/* Eingebettetes Content-Video mit CLS-Schutz (aspect-ratio) und
   Lazy-Load via IntersectionObserver (data-src → src per JS).   */
.video-showcase__header {
  text-align: center;
  max-width: 720px;
  margin: 0 auto var(--space-12);
}
.video-showcase__container {
  max-width: 960px;
  margin: 0 auto;
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: 0 32px 80px rgb(var(--c-black) / 0.5);
  background: rgb(var(--c-black));
  /* Reserviert 16:9-Platz sofort → kein CLS */
  aspect-ratio: 16 / 9;
}
.video-showcase__video,
.video-showcase__container picture,
.video-showcase__container picture img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 640px) {
  .video-showcase__container { border-radius: var(--radius-lg); }
}
/* Reduced-motion: Poster bleibt, kein Autoplay */@media (prefers-reduced-motion: reduce) {
  .video-showcase__video { animation: none !important; }
}

/* ── Leistungen Overview – Grid-Varianten ─────────────────── */
@media (min-width: 640px)  { .services-grid--2col { grid-template-columns: repeat(2, var(--grid-track-fluid)); } }
@media (min-width: 1024px) { .services-grid--3col { grid-template-columns: repeat(3, var(--grid-track-fluid)); } }

/* Unterbelegtes 3er-Raster: genau ZWEI Karten fuellen ab 1024px nur die ersten
   beiden von drei Spalten — die dritte bleibt leer, das Paar klebt links und
   die Sektion kippt optisch nach links (z. B. `karriere-region` auf
   /standort/, in allen Sprachen dieselbe Sektion). Fix ist zaehl-gesteuert
   ueber `:has()` statt ueber eine Seiten-/Sektions-Klasse: jedes 3er-Raster,
   das nur zwei Karten traegt, zentriert sich selbst — kein Marker im Template,
   keine Sonderregel pro Seite. Unter 1024px greift ohnehin das 2-Spalten-
   Raster von `.services-grid`, dort gibt es kein Loch.
   `max-width` + `margin-inline` statt `justify-content`: die Tracks sind
   `minmax(0,1fr)` und fuellen den Container restlos aus — `justify-content`
   haette an fr-Tracks keinen Verteilungsspielraum und bliebe wirkungslos. */
@media (min-width: 1024px) {
  .services-grid--3col:has(> :nth-child(2):last-child) {
    grid-template-columns: repeat(2, var(--grid-track-fluid));
    max-width: 60rem;
    margin-inline: auto;
  }
}

/* ── card-fold — „Weitere … anzeigen" (natives <details>) ───────────────────
   Klappt die Rest-Karten einer `process_list media:true` mit `fold_after` ein
   (templates/partials/page_sections.html.jinja).

   WARUM nativ statt JS: die Startseiten-Branchen-Bahn traegt 15 interne Links.
   Die muessen im HTML bleiben (Crawling + Linkfluss auf die Branchen-Spokes),
   duerfen aber nicht 15 Bildschirme Scrollstrecke kosten. <details> loest beides
   ohne JS — und damit auch ohne den Reveal-Pfad, der genau hier zur Falle wird:
   Karten IM Fold tragen deshalb bewusst KEIN data-animate (sie laegen sonst als
   `.js [data-animate]{opacity:0}` unter display:none, wo der IntersectionObserver
   sie nie aufdeckt). Der Umschalter ist eine gewoehnliche .btn-secondary —
   keine zweite Button-Optik. */
.card-fold {
  margin-top: var(--space-8);
}

.card-fold__toggle {
  /* display:flex statt des inline-flex aus .btn — nur so zentriert margin-inline
     den Umschalter; entfernt zugleich den Default-Marker (display:list-item). */
  display: flex;
  width: fit-content;
  margin-inline: auto;
  list-style: none;
}

.card-fold__toggle::-webkit-details-marker { display: none; }
.card-fold__toggle::marker { content: ""; }

.card-fold__count {
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

.card-fold__label--less { display: none; }
.card-fold[open] .card-fold__label--more { display: none; }
.card-fold[open] .card-fold__label--less { display: inline; }

.card-fold__grid {
  margin-top: var(--space-8);
  /* KEIN eigener counter-reset: `.services-grid` setzt svc-card zurueck, und das
     zweite Raster ist Nachfahre eines FOLGENDEN Geschwisters des ersten — der
     Zaehler des ersten Rasters reicht also bis hierher. Ohne dieses `none` fingen
     die eingeklappten Karten wieder bei 01 an, und die Bahn haette zweimal
     01/02/03 (im Screenshot des ersten Aufklappens genau so gemessen). */
  counter-reset: none;
}

/* Flex-Stretch + Stretched-Link + Bild-Support */
.service-card {
  display: flex;
  flex-direction: column;
  position: relative;   /* Anker für Stretched-Link-Overlay */
  /* overflow VISIBLE: sonst würde der performante ::after-Glow-Halo abgeschnitten.
     Das Card-Bild wird stattdessen in .service-card-img selbst geclippt. */
  overflow: visible;
  isolation: isolate;
  background-clip: padding-box;
  cursor: default;
}
.service-card:has(a.service-card-link[href]:not(.service-card-link--disabled)) {
  cursor: pointer;
}
.service-card-text { flex: 1; }

/* Card-Thumbnail oben, flush zum Rand (negiert Card-Padding). Clippt das Bild an
   die oberen Card-Radien — übernimmt das, was vorher overflow:hidden der Card tat. */
.service-card-img {
  margin: calc(-1 * var(--space-8)) calc(-1 * var(--space-8)) var(--space-6);
  overflow: hidden;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
}
.service-card-img picture,
.service-card-img img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
/* Bild-Zoom siehe zentrale "Interactive Card"-Regel (var(--card-img-zoom)). */

/* Stretched-Link: gesamte Karte ist klickbar */
a.service-card-link[href]::after,
.card-stretched-link[href]::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
}
/* Spec-Zeile (Kenndaten, rot/klein) */
.service-card-spec {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  margin: var(--space-3) 0 var(--space-4);
}

/* Bullet-Liste in Karten (für Rohrschneiden-Features) */
.service-card-bullets {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-4);
}
.service-card-bullets li {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  padding-left: var(--space-5);
  position: relative;
  margin-bottom: var(--space-2);
  line-height: var(--leading-snug);
}
.service-card-bullets li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--color-accent-text);
  font-weight: var(--font-weight-bold);
}

/* Dark-Section Karten-Variante */
.dark-section .service-card {
  background: var(--on-dark-surface-soft);
  border-color: var(--on-dark-border-soft);
  box-shadow: none;
}
.dark-section .service-card:has(a.service-card-link[href]:not(.service-card-link--disabled)):is(:hover, :focus-within) {
  background: var(--on-dark-surface-strong);
  border-color: var(--color-accent);
}
.dark-section .service-card-title      { color: var(--on-dark-text); }
.dark-section .service-card-text       { color: var(--color-text-muted); }
.dark-section .service-card-bullets li { color: var(--color-text-muted); }
.dark-section .service-card-spec       { color: var(--color-accent-text); }

/* ── Rohrschneiden Decision Strip ─────────────────────────── */
.rohr-decision-strip {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  background: var(--on-dark-surface-soft);
  border: 1px solid var(--on-dark-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8) var(--space-10);
}
.rohr-decision-strip__item {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.rohr-decision-strip__range {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-text);
  line-height: 1;
}
.rohr-decision-strip__label {
  font-size: var(--text-sm);
  color: var(--color-gray-400);
  line-height: var(--leading-relaxed);
}
.rohr-decision-strip__method {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--on-dark-text);
  margin-top: var(--space-1);
}
.rohr-decision-strip__divider {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-dark-text-quiet);
  font-size: var(--text-2xl);
  flex-shrink: 0;
}
@media (max-width: 640px) {
  .rohr-decision-strip {
    flex-direction: column;
    padding: var(--space-6);
    gap: var(--space-5);
  }
  .rohr-decision-strip__divider { transform: rotate(90deg); }
}
/* Light-Variante, wenn die Rohr-Sektion als regulärer (heller) Prozess-Schritt
   läuft statt als dunkles Highlight. Kontext-scoped (.proc-stage) → die noch nicht
   migrierte dunkle dark-section-Nutzung anderer Sprachen bleibt unberührt. */
.proc-stage .rohr-decision-strip {
  background: var(--color-bg-alt);
  border-color: var(--color-border);
}
.proc-stage .rohr-decision-strip__label   { color: var(--color-text-muted); }
.proc-stage .rohr-decision-strip__method  { color: var(--color-text); }
.proc-stage .rohr-decision-strip__divider { color: var(--color-text-light); }
/* Verfahrens-Link im Decision-Strip → klar klickbar (Akzent + Pfeil-Nudge). */
a.rohr-decision-strip__method {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  transition: color var(--transition-fast);
}
a.rohr-decision-strip__method span { transition: transform var(--transition-fast); }
a.rohr-decision-strip__method:hover span,
a.rohr-decision-strip__method:focus-visible span { transform: translateX(3px); }
a.rohr-decision-strip__method:hover,
a.rohr-decision-strip__method:focus-visible { text-decoration: underline; text-underline-offset: 3px; outline: none; }
.proc-stage a.rohr-decision-strip__method { color: var(--color-accent-text); }
.proc-stage a.rohr-decision-strip__method:hover,
.proc-stage a.rohr-decision-strip__method:focus-visible { color: var(--color-accent-text); }

/* ── V2 Leistungsdetail-Template ─────────────────────────── */

/* Hero image band – adapts to the image's natural aspect ratio (no crop) */
.hero-image-wrapper { width: 100%; }
.hero-image-wrapper__img { width: 100%; height: auto; display: block; }

/* process-list: DL für Verfahren / Prozesse mit Label + Beschreibung */
.process-list { display: flex; flex-direction: column; gap: 1.5rem; margin: 1.5rem 0; }
.process-list__item { display: grid; grid-template-columns: 1fr; gap: 0.25rem; }
@media (min-width: 640px) { .process-list__item { grid-template-columns: minmax(0, 220px) var(--grid-track-fluid); gap: 1rem; align-items: baseline; } }
.process-list__label { font-weight: var(--font-weight-semibold); color: var(--color-heading); min-width: 0; overflow-wrap: break-word; -webkit-hyphens: auto; hyphens: auto; }
.process-list__label a { color: var(--color-accent-text); text-decoration: none; }
.process-list__label a:hover { text-decoration: underline; }
.process-list__text { color: var(--color-text); margin: 0; }
.dark-section .process-list__label { color: var(--color-heading); }
.dark-section .process-list__text { color: var(--color-text-muted); }

/* why-list: DL für Stärken / Gründe als Key–Value-Paare */
.why-list { display: flex; flex-direction: column; gap: 1rem; margin: 1.5rem 0; }
.why-list__item { display: grid; grid-template-columns: 1fr; gap: 0.25rem; }
@media (min-width: 640px) { .why-list__item { grid-template-columns: minmax(0, 180px) var(--grid-track-fluid); gap: 1rem; align-items: baseline; } }
.why-list__key { font-weight: var(--font-weight-semibold); color: var(--color-heading); min-width: 0; overflow-wrap: break-word; -webkit-hyphens: auto; hyphens: auto; }
.why-list__text { color: var(--color-text); margin: 0; }
.dark-section .why-list__key { color: var(--color-heading); }
.dark-section .why-list__text { color: var(--color-text-muted); }

/* section-link */
.section-link-wrap { margin-top: 1.5rem; }
.section-link { color: var(--color-accent-text); font-weight: var(--font-weight-medium); text-decoration: none; }
.section-link:hover { text-decoration: underline; }
.dark-section .section-link { color: var(--color-accent-text); }

/* ── Timeline Section ────────────────────────────────────────
   Premium enterprise timeline with animated connector,
   glassmorphism cards, icons, and sophisticated micro-interactions.
   ─────────────────────────────────────────────────────────── */
.timeline-section {
  position: relative;
  padding: clamp(5rem, 8vw, 8rem) 0;
  background:
    radial-gradient(circle at 20% 50%, rgb(var(--c-info) / 0.04), transparent 45%),
    radial-gradient(circle at 80% 50%, rgb(var(--c-red) / 0.03), transparent 45%),
    linear-gradient(180deg, var(--color-bg-alt), var(--color-bg));
  overflow: visible;
  contain: layout style;
}

.timeline {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding: var(--space-8) 0;
  margin-top: var(--space-12);
}

.timeline::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 2px;
  background: linear-gradient(180deg,
    rgb(var(--c-red) / 0.3),
    rgb(var(--c-red) / 0.15),
    rgb(var(--c-red) / 0.3));
  transform: translateX(-50%);
  transform-origin: top center;
  animation: timelineGrow 1.2s ease-out forwards;
}

@keyframes timelineGrow {
  from { height: 0; }
  to { height: 100%; }
}

.timeline-item {
  position: relative;
  display: flex;
}
/* Reveal is driven by the shared [data-animate] + IntersectionObserver system
   (on .timeline-content for the redesigned DE cards → only the card slides in,
   the dot stays glued to the spine; on .timeline-item for not-yet-ported langs).
   No always-on load animation → the milestones animate in as you scroll to them. */

/* Alternate left/right layout */
.timeline-item:nth-child(odd) {
  flex-direction: row;
}

.timeline-item:nth-child(even) {
  flex-direction: row-reverse;
}

.timeline-dot {
  position: absolute;
  left: 50%;
  top: 32px;
  transform: translateX(-50%);
  z-index: 10; /* ssot-ok: local stacking (timeline dot above its connector line) */
  width: 20px;
  height: 20px;
  background: var(--color-bg);
  border: 3px solid var(--color-accent);
  border-radius: 50%;
  box-shadow:
    0 0 0 4px rgb(var(--c-red) / 0.1),
    0 4px 12px rgb(var(--c-red) / 0.2);
  transition: all 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.timeline-item.active .timeline-dot,
.timeline-item:hover .timeline-dot {
  width: 28px;
  height: 28px;
  top: 28px;
  background: var(--color-accent);
  box-shadow:
    0 0 0 6px rgb(var(--c-red) / 0.15),
    0 8px 24px rgb(var(--c-red) / 0.35);
}

.timeline-dot::after {
  content: "";
  position: absolute;
  inset: 50%;
  width: 8px;
  height: 8px;
  background: var(--color-bg);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity 350ms ease;
}

.timeline-item.active .timeline-dot::after,
.timeline-item:hover .timeline-dot::after {
  opacity: 1;
}

.timeline-content {
  width: 48%;
  padding: 0 var(--space-8);
}

.timeline-year {
  font-family: var(--font-display);
  font-size: clamp(0.95rem, 1.2vw, 1.25rem);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-text);
  letter-spacing: var(--tracking-wide);
  margin-bottom: var(--space-3);
}

.timeline-card {
  position: relative;
  padding: var(--space-8);
  background:
    linear-gradient(135deg, var(--color-bg), var(--color-bg-alt));
  border: 1px solid var(--on-dark-border-bright);
  border-radius: var(--radius-2xl);
  box-shadow:
    0 16px 48px rgb(var(--c-shadow) / 0.06),
    0 6px 24px rgb(var(--c-shadow) / 0.04),
    inset 0 1px 0 rgb(var(--c-white) / 0.8);
  transition: all 400ms cubic-bezier(0.34, 1.56, 0.64, 1);
  overflow: hidden;
  contain: layout style paint;
}

.timeline-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-2xl);
  padding: 1px;
  background: linear-gradient(135deg,
    rgb(var(--c-red) / 0.1),
    rgb(var(--c-info) / 0.08),
    rgb(var(--c-red) / 0.06));
  -webkit-mask:
    linear-gradient(rgb(var(--c-white)) 0 0) content-box,
    linear-gradient(rgb(var(--c-white)) 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 350ms ease;
  pointer-events: none;
}

.timeline-item:hover .timeline-card::before {
  opacity: 1;
}

.timeline-item:hover .timeline-card {
  background:
    linear-gradient(135deg, var(--color-bg), var(--color-bg-alt));
  border-color: rgb(var(--c-red) / 0.15);
  box-shadow:
    0 24px 64px rgb(var(--c-red) / 0.12),
    0 8px 32px rgb(var(--c-shadow) / 0.08),
    inset 0 1px 0 rgb(var(--c-white) / 0.9);
  transform: translate3d(0, -4px, 0);
}

.timeline-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-4);
  background:
    linear-gradient(135deg, var(--color-accent), var(--color-accent-light));
  border-radius: 50%;
  box-shadow:
    0 8px 20px rgb(var(--c-red) / 0.25),
    inset 0 2px 0 rgb(var(--c-white) / 0.2);
  transition: transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 350ms ease;
}

.timeline-item:hover .timeline-icon {
  transform: scale(1.12) rotate(-6deg);
  box-shadow:
    0 12px 32px rgb(var(--c-red) / 0.35),
    inset 0 2px 0 rgb(var(--c-white) / 0.3);
}

.timeline-icon i {
  color: var(--color-text-inverse);
  font-size: var(--text-2xl);
  filter: drop-shadow(0 2px 4px rgb(var(--c-black) / 0.15));
}

.timeline-card h3 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin-bottom: 0.6rem;
  transition: color 350ms ease;
}

.timeline-item:hover .timeline-card h3 {
  color: var(--color-accent-text);
}

.timeline-card p {
  font-size: 0.95rem;
  color: var(--color-text-light);
  line-height: 1.65;
  margin: 0;
  transition: color 350ms ease;
}

.timeline-item:hover .timeline-card p {
  color: var(--color-text);
}

/* ── Mobile Timeline ─────────────────────────────────────── */
@media (max-width: 1024px) {
  .timeline {
    gap: var(--space-10);
  }

  .timeline::before {
    left: 16px;
  }

  .timeline-item {
    flex-direction: row !important;
  }

  .timeline-dot {
    left: 16px;
  }

  .timeline-content {
    width: calc(100% - 60px);
    padding: 0 var(--space-8) 0 var(--space-12);
  }

  .timeline-year {
    font-size: 1.05rem;
  }

  .timeline-card {
    padding: var(--space-7);
  }
}

@media (max-width: 680px) {
  .timeline-section {
    padding: clamp(3.5rem, 6vw, 6rem) 0;
  }

  .timeline {
    gap: var(--space-8);
    padding: var(--space-4) 0;
    margin-top: var(--space-8);
  }

  .timeline::before {
    left: 12px;
  }

  .timeline-dot {
    left: 12px;
    width: 16px;
    height: 16px;
    border-width: 2.5px;
    top: 26px;
  }

  .timeline-item.active .timeline-dot,
  .timeline-item:hover .timeline-dot {
    width: 24px;
    height: 24px;
    top: 22px;
  }

  .timeline-content {
    width: calc(100% - 50px);
    padding: 0 var(--space-6) 0 var(--space-10);
  }

  .timeline-year {
    font-size: 0.95rem;
  }

  .timeline-card {
    padding: var(--space-6);
    border-radius: 16px;
  }

  .timeline-card::before {
    border-radius: 16px;
  }

  .timeline-icon {
    width: 40px;
    height: 40px;
    margin-bottom: var(--space-3);
  }

  .timeline-icon i {
    font-size: 1.2rem;
  }

  .timeline-card h3 {
    font-size: 1.1rem;
  }

  .timeline-card p {
    font-size: 0.9rem;
  }
}

@media (max-width: 420px) {
  .timeline::before {
    left: 10px;
  }

  .timeline-dot {
    left: 10px;
  }

  .timeline-content {
    width: calc(100% - 40px);
    padding: 0 var(--space-5) 0 2.25rem;
  }

  .timeline-card {
    padding: var(--space-5);
  }
}

/* ════════════════════════════════════════════════════════════════════════
   Timeline · Media-Story-Cards (Über-uns „Meilensteine", Champions-League)
   ────────────────────────────────────────────────────────────────────────
   Bild + Text „smart" zu einer erzählenden Karte verschmolzen. Reizt die
   zentralen Card-Tokens aus (--card-lift, --card-img-zoom, --card-img-zoom-*),
   bewusst OHNE den roten Klick-Halo (--glow): diese Cards erzählen, sie sind
   nicht verlinkt → eigene, architektonische Hover-Tiefe (Graphit + Akzentkante).
   Die äußere Bahn (.timeline / -item / -dot / ::before-Spine) bleibt unverändert.
   HINWEIS: Die obigen .timeline-card/.timeline-icon-Regeln bleiben bestehen,
   bis die übrigen Sprach-Templates auf .tl-card portiert sind — danach entfernen.
   ════════════════════════════════════════════════════════════════════════ */
.tl-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius-2xl);
  background: linear-gradient(135deg, var(--color-bg), var(--color-bg-alt));
  /* --color-border flippt im Dark auf eine sichtbare helle Haarlinie; der vorherige
     Schatten-Kanal bei 8% Deckung wurde im Dark reines Schwarz-auf-Dunkel = unsichtbar (Rand +
     Elevation weg). Schatten dürfen im Dark verschwinden (Elevation trägt die hellere Fläche),
     der Rand nicht — er ist die einzige Abgrenzung, wenn der Karten-Gradient an der Seiten-BG startet. */
  border: 1px solid var(--color-border);
  box-shadow:
    0 16px 48px rgb(var(--c-shadow) / 0.07),
    0 4px 14px rgb(var(--c-shadow) / 0.04);
  transition:
    transform var(--card-img-zoom-speed) var(--glow-ease),
    box-shadow var(--card-img-zoom-speed) var(--glow-ease),
    border-color var(--card-img-zoom-speed) var(--glow-ease);
  contain: layout style;
}

/* ── Media-Zone ──────────────────────────────────────────────── */
.tl-card-media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: rgb(var(--c-shadow) / 0.06);
}
.tl-card-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
  transform: translateZ(0);
  transition: transform var(--card-img-zoom-speed) var(--card-img-zoom-ease);
}
/* Personen-/Hochformat-Motive: Kopf oben halten statt mittig beschneiden. */
.tl-card-media--portrait .tl-card-img { object-position: center 22%; }

/* Lesbarkeits-Scrim unten (für Jahr + Tag-Chip) */
.tl-card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgb(var(--c-shadow-deep) / 0.62) 0%,
    rgb(var(--c-shadow-deep) / 0.18) 26%,
    transparent 52%);
  pointer-events: none;
}

/* Jahr — großes Display-Badge, überlappt das Bild unten links */
.tl-card-year {
  position: absolute;
  left: var(--space-5);
  bottom: var(--space-4);
  z-index: 2;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.2vw, 2.2rem);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-inverse);
  text-shadow: 0 2px 14px rgb(var(--c-shadow-deep) / 0.55);
}
.tl-card-year::before {
  content: "";
  display: block;
  width: 34px;
  height: 3px;
  margin-bottom: 0.55rem;
  border-radius: 3px;
  background: var(--color-accent);
  box-shadow: 0 0 14px rgb(var(--c-red) / 0.6);
}

/* Tag-Chip — z. B. „Meisterstück von Karl Bock" / „Hermann Bock" */
.tl-card-tag {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  max-width: calc(100% - 2 * var(--space-4));
  padding: 0.4rem 0.7rem;
  font-size: 0.74rem;
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-inverse);
  background: rgb(var(--c-shadow-deep) / 0.5);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(140%);
  backdrop-filter: blur(var(--blur-md)) saturate(140%);
  border: 1px solid var(--on-dark-border-strong);
  border-radius: var(--badge-radius);
}
.tl-card-tag i { flex: none; color: var(--color-accent-text); font-size: 0.85em; }

/* ── Body ────────────────────────────────────────────────────── */
.tl-card-body {
  padding: var(--space-6) var(--space-6) var(--space-7);
}
.tl-card-title {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0 0 0.55rem;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  transition: color var(--glow-speed) var(--glow-ease);
}
.tl-card-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--color-text-inverse);
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-light));
  box-shadow:
    0 8px 18px rgb(var(--c-red) / 0.28),
    inset 0 2px 0 rgb(var(--c-white) / 0.22);
  transition: transform var(--card-img-zoom-speed) var(--glow-ease);
}
.tl-card-ico i { font-size: 1.05rem; filter: drop-shadow(0 2px 4px rgb(var(--c-black) / 0.18)); }
.tl-card-text {
  margin: 0;
  font-size: 0.97rem;
  line-height: 1.65;
  color: var(--color-text-light);
}
.tl-card-text strong { color: var(--color-text); font-weight: var(--font-weight-semibold); }

/* ── Kompakt-Variante (ohne Bild) — z. B. 1970er ─────────────── */
.tl-card--compact {
  background:
    linear-gradient(135deg, rgb(var(--c-red) / 0.05), var(--color-bg-alt)),
    var(--color-bg);
  border-color: rgb(var(--c-red) / 0.12);
}
.tl-card--compact .tl-card-body { padding: var(--space-7) var(--space-6); }
.tl-card-year--inline {
  position: static;
  display: inline-block;
  margin-bottom: 0.55rem;
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--color-accent-text);
  text-shadow: none;
}
.tl-card-year--inline::before { display: none; }

/* ── Aktiv-Variante (Heute) — roter Abschluss-Akzent ─────────── */
.tl-card--active {
  border-color: rgb(var(--c-red) / 0.35);
  box-shadow:
    0 20px 54px rgb(var(--c-red) / 0.14),
    0 6px 18px rgb(var(--c-shadow) / 0.06);
}
.tl-card--active .tl-card-tag {
  background: rgb(var(--c-red) / 0.85);
  border-color: var(--on-dark-border-strong);
}
.tl-card--active .tl-card-tag i { color: var(--color-text-inverse); }

/* ── Hover — Lift + Bild-Zoom + Architektur-Tiefe (kein Klick-Halo) ── */
@media (hover: hover) {
  .tl-card:hover {
    transform: var(--card-lift);
    border-color: rgb(var(--c-red) / 0.22);
    box-shadow:
      0 28px 70px rgb(var(--c-shadow) / 0.13),
      0 10px 28px rgb(var(--c-red) / 0.10);
  }
  .tl-card:hover .tl-card-img { transform: translateZ(0) scale(var(--card-img-zoom)); }
  .tl-card:hover .tl-card-title { color: var(--color-accent-text); }
  .tl-card:hover .tl-card-ico { transform: scale(1.08) rotate(-6deg); }
}
@media (prefers-reduced-motion: reduce) {
  .tl-card, .tl-card-img, .tl-card-ico, .tl-card-title { transition: none; }
  .tl-card:hover, .tl-card:hover .tl-card-img, .tl-card:hover .tl-card-ico { transform: none; }
}

/* ── Responsive ──────────────────────────────────────────────── */
@media (max-width: 680px) {
  .tl-card-body { padding: var(--space-5) var(--space-5) var(--space-6); }
  .tl-card--compact .tl-card-body { padding: var(--space-6) var(--space-5); }
  .tl-card-title { gap: 0.6rem; font-size: 1.12rem; }
  .tl-card-ico { width: 36px; height: 36px; }
  .tl-card-ico i { font-size: 0.95rem; }
  .tl-card-text { font-size: 0.92rem; }
  .tl-card-year { left: var(--space-4); bottom: var(--space-3); }
  .tl-card-tag { font-size: 0.7rem; padding: 0.34rem 0.6rem; }
}


/* ── Sprach-Assistent / Language suggestion (ADR 0007) ──────────── */
.bm-ls-banner {
  position: fixed;
  left: 0; right: 0; top: 0;
  width: 100%;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  box-shadow: 0 6px 24px rgb(var(--c-black) / 0.12);
  z-index: var(--z-toast);
  font-family: var(--font-base);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}
/* EINE kompakte Zeile (kein stapelnder Block mehr): Globus · Text · [Wechseln]
   · [🌐 andere Sprache] · [×]. Buttons behalten ihre Breite, der Text schrumpft. */
.bm-ls-inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-2) var(--space-6);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: nowrap;
}
.bm-ls-globe {
  flex-shrink: 0;
  color: var(--color-heading);
}
.bm-ls-text {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  color: var(--color-text);
  font-weight: var(--font-weight-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-ls-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-shrink: 0;
}
/* „Andere Sprache" — Icon-Pill, öffnet den bestehenden Header-Umschalter (SSOT). */
.bm-ls-more {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 9px;
  border-radius: var(--radius-md);
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.bm-ls-more:hover,
.bm-ls-more:focus-visible {
  background: var(--color-bg-alt);
  border-color: var(--color-heading);
  color: var(--color-heading);
  outline: none;
}
.bm-ls-more svg { flex-shrink: 0; }
.bm-ls-more__caret { opacity: 0.7; }
.bm-ls-close {
  background: transparent;
  border: 0;
  font-size: var(--text-2xl);
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
  padding: 0 var(--space-1);
  flex-shrink: 0;
}
.bm-ls-close:hover { color: var(--color-text); }
@media (max-width: 640px) {
  .bm-ls-inner { padding: var(--space-2) var(--space-3); gap: var(--space-2); }
  /* Text darf auf max. 2 Zeilen umbrechen statt zu strecken; Zeile bleibt kompakt. */
  .bm-ls-text {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    font-size: var(--text-xs);
  }
  .bm-ls-more__caret { display: none; }
  /* Das Maß des CTA gehört NICHT hierher: `.bm-ls-switch.btn` in
     components/buttons.css ist die Eigentümer-Regel und gibt ihm bereits
     Chip-Maß (min-height-sm / padding-sm / text-sm). Eine zweite Regel hier
     wäre (0,1,0) gegen (0,2,0) — wirkungslos — und vor allem eine zweite
     Wahrheit für dasselbe Maß. Änderungswunsch am CTA → dort ändern. */
}
@media (max-width: 480px) {
  /* Der führende Globus ist rein dekorativ (aria-hidden) und dubliert das Motiv
     des „andere Sprache"-Buttons zwei Elemente weiter rechts — auf Telefonbreite
     ist er der erste Kandidat für den Platz, den Text und CTA brauchen.
     Zwei Klassen (0,2,0) sind Pflicht: components/icons.css lädt NACH main.css
     und setzt `.bm-icon { display: inline-block }` — einklassig verliert diese
     Regel den Quellreihenfolge-Tiebreak und der Globus bliebe stehen. */
  .bm-ls-inner .bm-ls-globe { display: none; }
}

/* ── Spec table — reusable, scannable spec/comparison grid ───── */
/* Wide data tables (spec_table / comparison-table) auf schmalen Viewports:
   horizontaler Scroll-Container mit Kanten-Fade-Affordance. `.table-responsive`
   ist der NICHT scrollende Rahmen (position: relative für die Fades), der innere
   `__scroll` scrollt. `min-width: 0` ist Pflicht, damit der Container in einem
   Grid-/Flex-Kind (z.B. section-media) unter die Content-Mindestbreite schrumpfen
   darf statt die Tabelle das Layout aufreißen zu lassen (der klassische
   Overflow-Footgun). JS (assets/js/scroll-affordance.js) toggelt is-scrollable /
   at-start / at-end via [data-scroll-x]; ohne JS bleibt es ein simpler Scroller. */
.table-responsive {
  position: relative;
  min-width: 0;
  margin-top: var(--space-6);
}
.table-responsive__scroll {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--color-border) transparent;
}
.table-responsive__scroll::-webkit-scrollbar { height: 8px; }
.table-responsive__scroll::-webkit-scrollbar-track { background: transparent; }
.table-responsive__scroll::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: var(--radius-full);
}
/* Kanten-Fades: signalisieren „hier gibt es mehr" und blenden sich am jeweiligen
   Rand aus (JS entfernt die Klasse). Rein dekorativ → pointer-events: none. */
.table-responsive::before,
.table-responsive::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  width: 2.75rem;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--glow-speed) var(--glow-ease);
}
.table-responsive::before {
  left: 0;
  background: linear-gradient(to right, rgb(var(--c-shadow) / 0.16), transparent);
}
.table-responsive::after {
  right: 0;
  background: linear-gradient(to left, rgb(var(--c-shadow) / 0.16), transparent);
}
.table-responsive.is-scrollable:not(.at-start)::before { opacity: 1; }
.table-responsive.is-scrollable:not(.at-end)::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .table-responsive::before,
  .table-responsive::after { transition: none; }
}
.spec-table {
  width: 100%;
  /* Lesbare Mindestbreite → auf schmalen Viewports scrollt die Tabelle horizontal
     (im `.table-responsive__scroll`) statt Zellen unleserlich umzubrechen. */
  min-width: 34rem;
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  font-size: var(--text-sm);
  color: var(--color-text);
}
.spec-table thead th {
  background: var(--color-bg-alt);
  color: var(--color-heading);
  font-weight: var(--font-weight-bold);
  text-align: left;
  white-space: nowrap;
}
.spec-table th,
.spec-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  border-right: 1px solid var(--color-border);
  vertical-align: middle;
  text-align: left;
}
.spec-table tbody th[scope="row"] {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}
.spec-table tbody tr:nth-child(even) td,
.spec-table tbody tr:nth-child(even) th[scope="row"] {
  background: var(--color-bg-alt);
}
.spec-table tbody tr:last-child th,
.spec-table tbody tr:last-child td { border-bottom: 0; }
.spec-table th:last-child,
.spec-table td:last-child { border-right: 0; }
/* Dunkle Sektionen: `--color-bg`/`-text`/`-border` sind in `.dark-section` bereits
   geflippt (Tabelle wird dunkel + heller Text). NUR `--color-bg-alt` (Kopfzeile +
   Zebra) flippt nicht → sonst grelle helle Bänder. Diese SSOT-Variante gibt Kopf und
   Zebra einen dunklen Ton, damit die spec-table auf JEDER Sektion (hell ODER dunkel)
   sauber aussieht — robust gegen umsortierte/eingeschobene Sektionen. */
.dark-section .spec-table thead th {
  background: var(--on-dark-surface-soft);
  color: var(--on-dark-text);
}
.dark-section .spec-table tbody th[scope="row"] { color: var(--on-dark-text); }
.dark-section .spec-table tbody tr:nth-child(even) td,
.dark-section .spec-table tbody tr:nth-child(even) th[scope="row"] {
  background: var(--on-dark-surface-faint);
}
@media (max-width: 640px) {
  .spec-table { font-size: var(--text-xs); }
  .spec-table th,
  .spec-table td { padding: var(--space-2) var(--space-3); }
}
