/* ==========================================================================
   GALVORN — styles.css
   Tokens extracted from test-claude.fig · 12-col grid · 80px margin · 24px gutter
   Breakpoint scope: 1440px reference (fluid below via max-width; further
   breakpoints get added as media-query overrides in a later pass)
   ========================================================================== */

/* ---------- Fonts (variable, one file per style = fast) ---------- */
@font-face {
  font-family: "Red Hat Display";
  src: url("../assets/fonts/RedHatDisplay-VF.woff2") format("woff2-variations");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}
/* ---------- Design tokens ---------- */
:root {
  /* brand (Figma variables) */
  --blue-05: #AAC0ED;
  --blue-1: #5682DC;
  --blue-3: #253D70;
  --blue-35: #162648;     /* Sektionston der Karten-Bänder (Figma 297:727) */
  --blue-4: #0C1C3E;
  --blue-5: #070E20;
  --yellow: #E2B22B;
  --yellow-2: #D99F00;
  /* Färbt ein weißes Bild in --yellow um (in Chrome gemessen: #E1B128).
     Die Ortssymbole sind <img>-Dateien, color greift dort nicht. */
  --filter-gold: brightness(0) saturate(100%) invert(92%) sepia(14%) saturate(4594%) hue-rotate(338deg) brightness(94%) contrast(88%);
  --error: #C4453A;        /* Fehlerrot auf Hell — 4,93:1 auf Weiß */
  --error-hell: #F0857A;   /* Fehlerrot auf Dunkel */
  --charcoal: #37414F;
  --white: #FFFFFF;
  --black: #000000;
  --dark-grey-2: #252525;

  /* greys (consolidated from page usage) */
  --grey-100: #F4F4F4;
  --grey-200: #ECECEC;
  --grey-300: #E3E3E3;
  --grey-400: #CFCFCF;
  --grey-500: #9A9A9A;
  --grey-600: #6B6B6B;
  --grey-800: #2A2A2A;
  /* Echtes Schwarz: #1E1E1E wirkte mit 400er-Schnitt + Antialiasing „grau" */
  --text-dark: #000000;
  --train-window: #46618A;

  /* gradients */
  --grad-hero: linear-gradient(135deg, var(--blue-5) 0%, var(--blue-4) 100%);
  --grad-panel: linear-gradient(180deg, var(--blue-3) 0%, var(--blue-4) 100%);
  --grad-card: linear-gradient(120deg, var(--blue-5) 0%, var(--blue-4) 100%);

  /* type */
  --font: "Red Hat Display", system-ui, -apple-system, "Segoe UI", sans-serif;
  --fs-display: 64px;      /* page hero H1 (unified from 62/64) */
  --fs-stat: 68px;
  --fs-h2: 40px;
  --fs-lead: 24px;
  --fs-body: 16px;
  --fs-small: 12px;
  --ls-wide: 0.05em;       /* 5% */
  --ls-wider: 0.10em;      /* 10% */
  --ls-widest: 0.11em;     /* 11% */

  /* spacing — 8px system */
  --s-1: 8px;  --s-2: 16px; --s-3: 24px; --s-4: 32px; --s-5: 40px;
  --s-6: 48px; --s-8: 64px; --s-10: 80px; --s-12: 96px; --s-16: 128px;

  /* layout */
  --page-margin: 80px;
  --content-max: 1280px;
  /* Spaltenmaße des 12er-Rasters: 80 px Rand, 24 px Rinne.
     Damit hängen Textbreiten am Raster statt an gegriffenen Zahlen.
     --sp6 heißt "sechs Spalten breit". */
  --spalte: calc((var(--content-max) - 11 * var(--gutter)) / 12);
  --sp2:  calc(2  * var(--spalte) + 1  * var(--gutter));
  --sp3:  calc(3  * var(--spalte) + 2  * var(--gutter));
  --sp4:  calc(4  * var(--spalte) + 3  * var(--gutter));
  --sp5:  calc(5  * var(--spalte) + 4  * var(--gutter));
  --sp6:  calc(6  * var(--spalte) + 5  * var(--gutter));
  --sp7:  calc(7  * var(--spalte) + 6  * var(--gutter));
  --sp8:  calc(8  * var(--spalte) + 7  * var(--gutter));
  --sp9:  calc(9  * var(--spalte) + 8  * var(--gutter));
  --sp10: calc(10 * var(--spalte) + 9  * var(--gutter));
  --sp11: calc(11 * var(--spalte) + 10 * var(--gutter));
  --gutter: 24px;

  /* radii */
  --r-card: 16px;
  --r-pill: 110px;
  --r-tile: 8px;
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  letter-spacing: var(--ls-wide);
  /* Grundwert 1: alle einzeiligen Elemente (Label, Badges, Kennzahlen, H3)
     sind gegen diesen Wert auf das Figma-Raster gesetzt. Nicht global ändern —
     das verschiebt die halbe Seite. Fließtext bekommt seinen Wert unten. */
  line-height: 1;
  color: var(--text-dark);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }
ul[class], ol[class] { padding: 0; list-style: none; }
button { font: inherit; letter-spacing: inherit; cursor: pointer; border: 0; background: none; }
:focus-visible { outline: 2px solid var(--yellow); outline-offset: 4px; border-radius: 2px; }
::selection { background: var(--blue-1); color: var(--white); }

/* ---------- Layout: container + 12-col grid ---------- */
.wrap {
  max-width: calc(var(--content-max) + 2 * var(--page-margin));
  margin-inline: auto;
  padding-inline: var(--page-margin);
}
.grid12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
}

/* ---------- Typography helpers ---------- */
.display {
  font-size: var(--fs-display);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}
.h2 {
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: 0;
}
.lead {
  font-size: var(--fs-lead);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: var(--ls-wide);
}
.body-copy { line-height: 1.5; }        /* UX fix: multi-line body reads at 150%, not 100% */
.overline {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
}
.small-caps {
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
}
.on-dark { color: var(--white); }

/* ---------- CTA buttons (5 Figma variants) ---------- */
.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 40px;
  border-radius: var(--r-pill);
  font-size: var(--fs-body);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
  line-height: 1.3;
  white-space: nowrap;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1), background-color .34s ease, border-color .34s ease;
}
.cta:hover { transform: translateY(-4px); }
.cta:active { transform: translateY(0); }

/* Die Glas-Variante wurde im Aug 2026 ausgemustert („wirkt alt") —
   Primärknöpfe auf Dunkel sind jetzt durchgehend cta--white. */

.cta--white { color: var(--black); background: var(--white); box-shadow: 0 4px 24px rgba(0,0,0,.25); }
.cta--white:hover { background: var(--grey-200); }

.cta--blue { color: var(--white); background: var(--blue-4); padding: 16px 40px; }
.cta--blue:hover { background: var(--blue-3); }

.cta--outline { color: var(--white); background: transparent; border: 1px solid var(--white); padding: 16px 40px; }
.cta--outline:hover { background: rgba(255,255,255,.1); }

.cta--outline-narrow { color: var(--white); background: transparent; border: 1px solid var(--white); padding: 12px 24px; }
.cta--outline-narrow:hover { background: rgba(255,255,255,.1); }

/* dark-context outline (on white sections) */
.cta--outline-dark { color: var(--blue-4); border: 1px solid var(--blue-4); background: transparent; padding: 16px 40px; }
.cta--outline-dark:hover { background: var(--blue-4); color: var(--white); }

/* ---------- Header / nav ---------- */
/* Fixiert statt absolut: beim Scrollen nach unten gleitet die Leiste weg,
   beim ersten Scroll nach oben kommt sie zurück (Klassen setzt main.js).
   Ab dem ersten Scroll bekommt sie einen dunklen Glas-Hintergrund, damit
   sie auf hellen Sektionen lesbar bleibt; ganz oben ist sie transparent
   und liegt wie bisher auf dem dunklen Hero. */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  transition: transform .35s cubic-bezier(.2,.7,.3,1), background-color .25s ease,
              box-shadow .25s ease;
}
.site-header--scrolled {
  background-color: rgba(7, 14, 32, .88);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  backdrop-filter: blur(12px) saturate(140%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .08), 0 8px 24px rgba(0, 0, 0, .25);
}
.site-header--hidden { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) {
  .site-header { transition: background-color .25s ease, box-shadow .25s ease; }
}
.site-header--solid { position: static; background: var(--blue-5); }

/* Seitenwechsel: eine ruhige Überblendung statt hartem Schnitt (View
   Transitions über Seitengrenzen). Nur die Kopfzeile bleibt stehen; die
   Bühne bewegt oder dehnt sich bewusst nicht mit — das wirkte verspielt.
   Browser ohne Unterstützung wechseln die Seite wie bisher. */
@view-transition { navigation: auto; }
.site-header { view-transition-name: kopfzeile; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .28s;
  animation-timing-function: ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}
/* Schlanke Leiste. Ganz oben auf dem Hero 24 px Luft nach oben (klebte
   mit 16 px sichtbar am Fensterrand), ab dem ersten Scroll wieder 16/16 —
   mit 32-px-Logo sind das dann 64 px Gesamthöhe. */
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-10);
  padding-top: var(--s-3);
  padding-bottom: var(--s-2);
  transition: padding-top .25s ease;
}
.site-header--scrolled .nav { padding-top: var(--s-2); }
.nav__logo img { height: 32px; width: auto; }
/* Wird die Zeile knapp, darf der Browser weder Logo noch Pfeile stauchen
   und keine Beschriftung umbrechen. Stattdessen rücken die Punkte ab 1400 px
   enger zusammen, ab 1280 px übernimmt der Menüknopf (siehe dort). */
.nav__logo, .nav__links > li, .nav__droptoggle svg { flex-shrink: 0; }
.nav__links {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  font-size: var(--fs-body);
}
.nav__links a,
.nav__links .nav__droptoggle { color: var(--white); letter-spacing: var(--ls-wide); padding: 4px 0; position: relative;
  font: inherit; background: none; border: 0; cursor: pointer; }
/* Hover: feine weiße Linie wächst aus der Mitte, rund und leicht
   durchscheinend — ruhiger als der frühere gelbe Balken von links. */
.nav__links a::before,
.nav__links .nav__droptoggle::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -6px;
  height: 1.5px;
  border-radius: 1px;
  background: currentColor;
  opacity: .9;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform .28s cubic-bezier(.2, .7, .3, 1);
}
.nav__links a:hover::before,
.nav__links a:focus-visible::before,
.nav__links .nav__droptoggle:hover::before,
.nav__links .nav__droptoggle:focus-visible::before,
.nav__item--dropdown[data-open] .nav__droptoggle::before { transform: scaleX(1); }
.nav__links a[aria-current="page"],
.nav__links .nav__droptoggle[aria-current="page"] { font-weight: 900; }
/* width-lock: invisible bold ghost reserves the bold width, so the bar never shifts */
.nav__lbl { display: inline-block; text-align: center; white-space: nowrap; }
.nav__lbl::after {
  content: attr(data-label);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 900;
}
.nav--dark .nav__links a,
.nav--dark .nav__links .nav__droptoggle { color: var(--black); }

/* Bereiche-Menü: öffnet per Klick (main.js setzt [data-open]).
   Aufbau wie im Lector-Menü: Sprechblase mit Spitze zum Umschalter,
   zwei Spalten, jeder Eintrag mit Symbol in einer ruhigen Kachel. */
.nav__item--dropdown { position: relative; }
.nav__droptoggle {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--white); padding: 4px 0;
}
.nav__links .nav__droptoggle::before { right: 20px; }
.nav--dark .nav__droptoggle { color: var(--black); }
/* Offen = Wort fett. Die Breite ist über .nav__lbl::after schon reserviert,
   dadurch verschiebt sich nichts. */
.nav__item--dropdown[data-open] .nav__droptoggle { font-weight: 900; }
/* Pfeil: im Ruhezustand so schmal wie die normale Schrift, offen oder auf
   der aktiven Seite so kräftig wie das fette Wort. */
.nav__chev { transition: transform .2s ease; }
.nav__chev path { stroke-width: 2.25; transition: stroke-width .2s ease; }
.nav__droptoggle[aria-current="page"] .nav__chev path,
.nav__item--dropdown[data-open] .nav__chev path { stroke-width: 3.5; }
.nav__item--dropdown[data-open] .nav__chev { transform: rotate(180deg); }

.nav__dropdown {
  position: absolute;
  top: calc(100% + 20px);
  left: 50%;
  translate: -50% 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(max-content, 1fr));
  gap: var(--s-1) var(--s-2);
  padding: var(--s-2);
  background: var(--blue-5);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--r-card);
  box-shadow: 0 16px 48px rgba(0, 0, 0, .4);
  /* Zu: unsichtbar und aus der Tab-Reihenfolge, aber animierbar */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-6px);
  /* Schließen schnell, Öffnen (unten) etwas weicher */
  transition: opacity .1s ease-out, transform .1s ease-out, visibility 0s linear .1s;
}
/* Spitze zeigt auf den Umschalter */
.nav__dropdown::before {
  content: "";
  position: absolute;
  top: -7px; left: 50%;
  width: 12px; height: 12px;
  margin-left: -6px;
  background: var(--blue-5);
  border-left: 1px solid rgba(255, 255, 255, .12);
  border-top: 1px solid rgba(255, 255, 255, .12);
  border-top-left-radius: 3px;
  transform: rotate(45deg);
}
/* Unsichtbare Brücke über den Spalt, damit das Menü nicht flackert,
   wenn die Maus vom Umschalter hinüberwandert */
.nav__dropdown::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -20px;
  height: 20px;
}
.nav__item--dropdown[data-open] .nav__dropdown {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition: opacity .18s ease, transform .18s ease;
}
.nav__links .nav__dd-item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-3) var(--s-1) var(--s-1);
  border-radius: 12px;
  color: var(--white);
  letter-spacing: var(--ls-wide);
  white-space: nowrap;
  transition: background-color .15s ease;
}
/* Kein gelber Unterstrich im Menü — dort trägt die Kachel den Hover */
.nav__links .nav__dd-item::before { display: none; }
.nav__dd-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 48px; height: 48px;
  border-radius: 12px;
  background: rgba(170, 192, 237, .1);
  color: var(--blue-05);
  transition: background-color .15s ease, color .15s ease;
}
.nav__links .nav__dd-item:hover,
.nav__links .nav__dd-item:focus-visible { background: rgba(255, 255, 255, .06); }
.nav__dd-item:hover .nav__dd-icon,
.nav__dd-item:focus-visible .nav__dd-icon,
.nav__dd-item[aria-current="page"] .nav__dd-icon {
  background: rgba(255, 255, 255, .14);
  color: var(--white);
}
/* Fett springt hier nicht: jede Zeile hat ihren eigenen Platz im Raster */
.nav__links .nav__dd-item[aria-current="page"] { font-weight: 700; }
/* Schleier über der Seite, solange das Bereiche-Menü offen ist (main.js
   hängt ihn an <body>). Liegt unter der Kopfzeile (z-index 50). */
.nav-schleier {
  position: fixed;
  inset: 0;
  z-index: 49;
  background: rgba(7, 14, 32, .55);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .12s ease-out, visibility 0s linear .12s;
}
.nav-schleier.ist-an {
  opacity: 1;
  visibility: visible;
  transition: opacity .22s ease;
}
@media (prefers-reduced-motion: reduce) {
  .nav-schleier, .nav-schleier.ist-an { transition: none; }
  .nav__dropdown, .nav__item--dropdown[data-open] .nav__dropdown { transition: none; transform: none; }
  .nav__chev, .nav__chev path { transition: none; }
}

/* ---------- Decorative silhouettes ("figures") ---------- */
/* Figma: ellipse head + fading body bar, layer-blurred. --d = head diameter. */
.person {
  transform-origin: 50% 100%;
  --d: 28px;
  --tint: #FFFFFF;
  --pblur: 1.2px;
  position: absolute;
  width: var(--d);
  height: calc(var(--d) * 3.86);
  pointer-events: none;
}
.person::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: var(--d); height: var(--d);
  border-radius: 50%;
  background: var(--tint);
  filter: blur(var(--pblur));
}
.person::after {
  content: "";
  position: absolute;
  top: calc(var(--d) * 1.21); left: 0;
  width: var(--d);
  height: calc(var(--d) * 2.64);
  border-radius: calc(var(--d) * 8);
  /* Der Körper verliert nach unten NUR Deckkraft, nie die Farbe: einfarbige
     Fläche + Alpha-Maske. Ein Farbverlauf zu „transparent" (= transparentes
     SCHWARZ) lief je nach Browser durch dunkle Mischtöne — die Figuren
     wirkten „unten dunkelblau". Eine Maske blendet rein über den Alphakanal. */
  background: var(--tint);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  filter: blur(var(--pblur));
}
/* Gelb = markiert. Außerhalb der animierten Hero-Szene tragen gelbe Figuren
   dieselbe Unschärfe wie alle anderen — „erkannt = scharf" ist ein Erzähl-
   mittel der Detektionsszene, kein globaler Look (sah sonst uneinheitlich aus). */
.person--yellow { --tint: var(--yellow); }
.hero .person--yellow { --pblur: 0px; }   /* erkannt = scharf, nur in der Szene */
.person--lightblue { --tint: var(--blue-05); }
.person--sharp { --pblur: 1.2px; }

/* ---------- Train graphic (hero) ---------- */
.train {
  position: absolute;
  height: 104px;
}
/* Der Korpus trägt die ICE-Form — Insassen und Labels liegen darüber und werden NICHT beschnitten */
.train__body {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: var(--s-6);
  padding: var(--s-4) 336px var(--s-4) var(--s-10);
  background: var(--grad-panel);
  clip-path: path("M0 20 Q0 0 20 0 L1440 0 C1590 0 1675 46 1720 96 L1720 104 L20 104 Q0 104 0 84 Z");
  filter: blur(.3px);
}
.train__body i {
  flex: 0 0 80px;
  height: 40px;
  background: var(--train-window);
  border-radius: var(--r-tile);
}
/* speed stripe along the flank */
.train__body::before {
  content: "";
  position: absolute;
  left: 24px; right: 24px; bottom: 16px;
  height: 4px;
  border-radius: 2px;
  background: var(--yellow);
  opacity: .55;
}
/* sleek windshield slit in the nose */
.train__body::after {
  content: "";
  position: absolute;
  right: 158px; top: 24px;
  width: 62px; height: 14px;
  background: var(--train-window);
  border-radius: 8px 10px 8px 6px;
  transform: rotate(13deg);
}
/* Dome-Kamera unter der Decke, kompakt */
.train .train__cam {
  position: absolute;
  top: 4px;
  width: 14px; height: 8px;
  border-radius: 0 0 14px 14px / 0 0 8px 8px;
  background: var(--blue-05);
}
.train .train__cam svg { display: none; }
.train .train__cam::before {
  content: "";
  position: absolute;
  left: -2px; top: -2px;
  width: 18px; height: 2px;
  border-radius: 1px;
  background: var(--blue-05);
}
.train .train__cam .led {
  position: absolute;
  left: 50%; top: 1.8px;
  margin-left: -2px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--blue-5);
  animation: cam-blink 1.4s steps(2, jump-none) infinite;
}
/* passengers ride WITH the train (children -> they drift and zoom together) */
.train .person { position: absolute; animation: none; filter: none; }
.train .pass { bottom: 12px; }
.train .person--yellow { position: absolute; inset: 0; }

/* ---------- Section rhythm ---------- */
.section { padding-block: var(--s-12); }
.section--dark { background: var(--blue-4); color: var(--white); }
.section--night { background: var(--blue-35); color: var(--white); }
.section--gradient { background: var(--grad-hero); color: var(--white); }
.section-title { display: grid; gap: var(--s-3); max-width: var(--sp7); }
.section-title .sub { max-width: var(--sp6); }

/* ---------- Solution tile cards (3×2 home grid + lösungen page) ---------- */
/* Sechs Rasterspuren, jede Kachel belegt zwei. Bei fünf Kacheln rückt die
   zweite Reihe in die Mitte (Spur 2–5), sonst sähe es aus, als fehle eine. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--gutter);
}
.tile-grid > * { grid-column: span 2; }
.tile-grid > :nth-child(4):nth-last-child(2) { grid-column: 2 / span 2; }
.tile {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 170px;
  padding: var(--s-3);
  background: var(--grad-card);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1), background-color .34s ease, border-color .34s ease;
}
.tile:hover { transform: translateY(-4px); }
.tile:active { transform: translateY(0); }
.tile__label {
  position: relative;
  z-index: 1;
  color: var(--white);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--ls-widest);
  text-align: center;
  line-height: 1.3;
  transition: color .34s cubic-bezier(.2, .7, .3, 1);
}
.tile__icon {
  position: absolute;
  pointer-events: none;
  /* Die 24 % lagen früher als fill-opacity in den SVG-Dateien. Jetzt steuert
     das CSS sie, damit der Hover das Zeichen auf volle Deckkraft ziehen kann. */
  opacity: .24;
  /* Der Goldfilter wird nicht überblendet: zwischen Weiß und Gold rechnet der
     Browser die Filterkette Schritt für Schritt und landet dabei kurz bei Pink.
     Beim Hineinfahren springt die Farbe sofort um (das Symbol ist da noch fast
     durchsichtig), beim Hinausfahren erst, wenn es wieder ausgeblendet ist. */
  transition: opacity .34s cubic-bezier(.2, .7, .3, 1);
}
.tile:hover .tile__icon,
.tile:focus-visible .tile__icon { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .tile__icon, .tile__label,
  .tile:hover .tile__icon,
  .tile:focus-visible .tile__icon { transition: none; }
}

/* ---------- Stats ---------- */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gutter); text-align: center; }
.stat { display: grid; gap: var(--s-1); justify-items: center; color: var(--blue-4); }
.stat__value { font-size: var(--fs-stat); font-weight: 700; letter-spacing: var(--ls-wide); }
.stat__label { font-weight: 600; text-transform: uppercase; letter-spacing: var(--ls-wider); }

/* ---------- Glass feature cards (privacy quartet) ---------- */
/* Karten nach Figma-Entwurf 297:727 (Aug 2026): keine Kästen — Spalten mit
   feinen SENKRECHTEN Trennlinien, weißes Kontur-Icon (32 px), Titel 16 px
   extrabold versal, Fließtext weiß. Nicht klickbar → kein Hover.
   --3 ist die dreispaltige Variante (Soziale Einrichtungen). */
.glass-grid { display: grid; grid-template-columns: repeat(4, 1fr); row-gap: var(--s-6); }
.glass-grid--3 { grid-template-columns: repeat(3, 1fr); }
/* Die Trennlinien gehören ZWISCHEN die Spalten, nicht an die Karten:
   seitliches Polster von 32 px hält den Text beidseitig von der Linie fern. */
.glass-card {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: var(--s-2);
  padding: 0 var(--s-4);
  text-align: left;
}
.glass-grid .glass-card:not(:nth-child(4n + 1)) { border-left: 1px solid rgba(255, 255, 255, .35); }
.glass-grid--3 .glass-card:not(:nth-child(4n + 1)) { border-left: 0; }
.glass-grid--3 .glass-card:not(:nth-child(3n + 1)) { border-left: 1px solid rgba(255, 255, 255, .35); }
.glass-card__icon {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  color: var(--yellow);
}
.glass-card__icon svg { width: 32px; height: 32px; }
.glass-card h3 {
  font-size: var(--fs-body);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
}
.glass-card p { line-height: 1.4; color: var(--white); }

/* ---------- Badges (hero trust pills) ---------- */
.badges { display: flex; justify-content: center; gap: var(--s-6); flex-wrap: wrap; }
/* Nur Kontur, kein Glas — so sind die Pillen klar vom CTA unterscheidbar */
.badge {
  padding: 16px 24px;
  border-radius: 50px;
  background: transparent;
  border: 1px solid rgba(255,255,255,.45);
  color: var(--white);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0;
  white-space: nowrap;
}

/* ---------- Footer ---------- */
/* ---------- Fußzeile ---------------------------------------------------
   12 Spalten, 80 px Seitenrand, 24 px Rinne, Abstände in 8er-Schritten.
   Marke 4 Spalten, die drei Verweisspalten 3 + 2 + 3.
   ---------------------------------------------------------------------- */
.site-footer {
  position: relative;
  background: var(--blue-5);
  color: var(--white);
  overflow: hidden;
  padding-top: var(--s-8);
  padding-bottom: var(--s-4);
}
.site-footer__inner {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
}
.site-footer__marke { grid-column: span 4; display: grid; gap: var(--s-2); }
.site-footer__marke img { height: 32px; width: auto; }
.site-footer__slogan { margin: 0; color: var(--white); }
.site-footer__text {
  margin: 0;
  max-width: 34ch;
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255, 255, 255, .72);
}
.site-footer__spalte { display: grid; gap: var(--s-2); align-content: start; }
/* Eigene Klassen statt Positionszählung: nth-of-type zählt je Elementtyp,
   und die Spalten sind teils <nav>, teils <div>. */
.site-footer__spalte--bereiche { grid-column: span 3; }
.site-footer__spalte--unternehmen { grid-column: span 2; }
.site-footer__spalte--kontakt { grid-column: span 3; }
.site-footer__titel { margin: 0; font-size: var(--fs-small); color: var(--white); }
/* Der Reset oben greift nur bei ul[class]; die Listen hier tragen keine. */
.site-footer ul { padding: 0; list-style: none; }
.site-footer__spalte ul { display: grid; gap: var(--s-1); }
.site-footer__spalte a {
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, .72);
  transition: color .15s ease;
}
.site-footer__spalte a:hover,
.site-footer__spalte a:focus-visible { color: var(--white); }
.site-footer__adresse {
  font-style: normal;
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255, 255, 255, .72);
}

/* Untere Leiste: Copyright links, Rechtliches rechts */
.site-footer__leiste {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-3);
  position: relative;
  margin-top: var(--s-6);
  padding-top: var(--s-3);
}
/* Trennlinie bündig zur Inhaltskante — ein border-top auf dem gepolsterten
   Wrapper liefe sonst über die volle Fensterbreite. */
.site-footer__leiste::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--page-margin);
  right: var(--page-margin);
  height: 1px;
  background: rgba(255, 255, 255, .14);
}
.site-footer__leiste p { margin: 0; color: rgba(255, 255, 255, .72); }
.site-footer__rechtlich { display: flex; gap: var(--s-3); }
.site-footer__rechtlich a { color: rgba(255, 255, 255, .72); transition: color .15s ease; }
.site-footer__rechtlich a:hover,
.site-footer__rechtlich a:focus-visible { color: var(--white); }
.site-footer a:hover { color: var(--blue-05); }

/* ---------- Fließtext-Links ----------
   Links im laufenden Text sind auf allen Seiten unterstrichen. Der Scope auf
   <main> nimmt Navigation, Footer und Cookie-Banner aus; die :not()-Liste
   nimmt Links aus, die als Fläche gestaltet sind (Buttons, Kacheln, Karten). */
main :is(p, li, dd, dt, blockquote, figcaption, .body-copy, .lead, .prose)
  a:not(.cta, .tile, .navy-card, .callout__link, .contact-social__link, [class*="card"], [class*="__more"]) {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---------- Long-form prose (Datenschutz / Impressum) ---------- */
.prose { line-height: 1.6; letter-spacing: 0.01em; max-width: 65ch; }
.prose h2 { font-size: 28px; font-weight: 800; line-height: 1.3; margin-top: var(--s-8); scroll-margin-top: 120px; }
.prose h3 { font-size: 18px; font-weight: 700; line-height: 1.4; margin-top: var(--s-5); scroll-margin-top: 120px; }
.prose h4 { font-size: 16px; font-weight: 700; line-height: 1.4; margin-top: var(--s-3); scroll-margin-top: 120px; }
.prose p, .prose ul, .prose ol { margin-top: var(--s-2); }
.prose ul { padding-left: 20px; list-style: disc; }
.prose a { color: var(--blue-1); text-decoration: underline; text-underline-offset: 2px; }
.prose strong { font-weight: 700; }

/* sticky in-page nav for long documents */
.doc-layout {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
}
.doc-toc {
  grid-column: 1 / span 4;
  position: sticky;
  top: var(--s-5);
  display: grid;
  gap: 2px;
  padding-right: var(--s-3);
}
.doc-toc a {
  padding: 12px 16px;
  border-left: 2px solid var(--grey-300);
  color: var(--grey-600);
  line-height: 1.4;
  letter-spacing: 0.01em;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.doc-toc a:hover { color: var(--text-dark); background: var(--grey-100); }
.doc-toc a.is-active { border-color: var(--yellow); color: var(--text-dark); font-weight: 700; }
/* Zweite Ebene der Randnavigation — bei einem 30-KB-Rechtstext reichen
   fünf Hauptabschnitte allein nicht zum Navigieren. */
.doc-toc a.doc-toc__sub {
  padding-left: var(--s-4);
  font-size: 14px;
  color: var(--grey-500);
}
.doc-toc { max-height: calc(100vh - var(--s-10)); overflow-y: auto; }
.doc-body { grid-column: 5 / span 8; }

/* ---------- Startseite: hero ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  padding-block: 0;
  overflow: hidden;
  display: flex;
  align-items: stretch;
}
/* deckt alles ab, was in die Textzone ragt — auch beim Hineinzoomen */
.hero__veil {
  position: absolute;
  inset: 0;
  background: var(--grad-hero);
  pointer-events: none;
  -webkit-mask-image:
    linear-gradient(180deg, transparent 0%, transparent 34%, rgba(0,0,0,.72) 39%, #000 44%),
    linear-gradient(90deg, #000 0%, #000 71%, transparent 78%);
  mask-image:
    linear-gradient(180deg, transparent 0%, transparent 34%, rgba(0,0,0,.72) 39%, #000 44%),
    linear-gradient(90deg, #000 0%, #000 71%, transparent 78%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
.hero__graphics {
  position: absolute;
  inset: 48px 0 auto 0;
  height: 880px;
  pointer-events: none;
  /* Bühne blendet nach unten aus — Textzone bleibt komplett frei */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 95%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 95%, transparent 100%);
  -webkit-mask-repeat: repeat-x;   /* vertikal NICHT kacheln: unterhalb der Bühne ist Schluss */
  mask-repeat: repeat-x;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
.hero__graphics .train {
  left: -138px;
  top: 88px;
  width: 1720px;
}
.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding-top: clamp(500px, 62vh, 620px);
  padding-bottom: clamp(56px, 8vh, 112px);
}

.hero__title {
  display: grid;
  justify-items: start;
  gap: var(--s-2);   /* Titel sitzt immer 16 px über dem Untertitel */
  max-width: var(--sp10);
}
.hero__title .lead { color: var(--white); }
/* Claim und Pillen bekommen bewusst viel Luft — der Absatz stand vorher
   gedrängt zwischen CTA und Badges. */
.hero__claim {
  max-width: 900px;
  margin: clamp(120px, 18vh, 200px) auto 0;
  text-align: center;
}
.hero .badges { margin-top: clamp(80px, 12vh, 128px); justify-content: center; gap: var(--s-3); }

/* ---------- Startseite: privacy / closing sections ---------- */
/* Unten doppelt so viel Luft: darunter folgt der Abschluss-Verlauf nahtlos,
   ohne Luft liefe der Button optisch in den Abschluss und die Fußzeile hinein. */
.privacy { position: relative; overflow: hidden; padding-block: var(--s-8) var(--s-16); }
.privacy__deco { position: absolute; inset: 0; pointer-events: none; }
.closing-cta { position: relative; overflow: hidden; padding-block: var(--s-16); }
.closing-cta__deco { position: absolute; inset: 0; pointer-events: none; }
.block-rechts { display: grid; justify-items: end; text-align: right; }
/* Satz rückt an die Überschrift (16 px wie im Hero), zum Button bleiben 40 px */
.closing-cta h2 + p { margin-top: calc(var(--s-2) - var(--s-5)); }

/* last dark section flows seamlessly into the #070E20 footer */
.closing-cta, .section--flow {
  background: linear-gradient(180deg, var(--blue-4) 0%, var(--blue-5) 100%);
  color: var(--white);
}
/* Der Verlauf beginnt in --blue-4 und schließt damit nahtlos an section--dark
   an. Steht er unter einem section--night-Band (Startseite: Datenschutz by
   Design), beginnt er in dessen Ton, sonst entsteht an der Grenze eine Kante. */
.section--night + .closing-cta,
.section--night + .section--flow {
  background: linear-gradient(180deg, var(--blue-35) 0%, var(--blue-5) 100%);
}

/* ---------- Startseite: retrofit diagram ---------- */
.retrofit { display: grid; gap: 0; }
.retrofit__diagram { width: 100%; height: auto; }
.retrofit__banner { width: 100%; height: auto; border-radius: var(--r-tile); }

/* ==========================================================================
   Subpage components
   ========================================================================== */

/* ---------- Short page hero (subpages) ---------- */
/* Feste Bühnenhöhe: jede Unterseite ist exakt gleich hoch (480px bei 1440),
   Titel und Text sitzen MITTIG in der Bühne (padding-top hält nur die
   Navigation frei). --fluid (Kontakt-Chat) darf nach unten wachsen. */
.page-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--grad-hero);
  color: var(--white);
  height: 480px;
  padding-top: 96px;
  padding-bottom: var(--s-4);
  overflow: hidden;
}
/* Kontakt-Bühne: bewusste Ausnahme mit fester Mehrhöhe für das Chat-Fenster —
   der Verlauf hat feste Maße, dadurch springt beim Antworten nichts. */

.page-hero .lead { font-size: 20px; }
.page-hero__inner {
  display: grid;
  gap: var(--s-2);   /* Titel sitzt immer 16 px über dem Untertitel */
  justify-items: center;
  text-align: center;
  /* Figma: Titelblock 1176 px breit und mittig — das sind 11 Spalten.
     Dieses Element trägt zugleich .wrap, das die 80 px Seitenrand als
     Polsterung mitbringt. Die müssen dazugerechnet werden, sonst bleiben
     vom Text nur 1016 px übrig. */
  max-width: calc(var(--sp11) + 2 * var(--page-margin));
  margin-inline: auto;
}
/* Unterseiten (zentriertes Layout): Titel eine Stufe kleiner als der Start-Hero */
.page-hero .display { font-size: 56px; }
.page-hero__inner .lead { max-width: var(--sp8); }
.page-hero .eyebrow {
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--blue-05);
}

/* ---------- Yellow statement band ---------- */
/* Haltungs-Statement: ruhig, redaktionell — kein Warnbanner */
.statement-band {
  background: var(--grey-100);
  color: var(--text-dark);
  padding-block: var(--s-10);
}
.statement-band__inner {
  max-width: var(--sp9);
  margin-inline: auto;
  text-align: center;
  display: grid;
  gap: var(--s-3);
  justify-items: center;
}
.statement-band .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--yellow-2);
}
.statement-band .eyebrow::before,
.statement-band .eyebrow::after {
  content: "";
  width: 34px; height: 2px;
  background: var(--yellow);
  border-radius: 1px;
}
.statement-band p {
  font-size: 26px;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 0.01em;
  text-wrap: balance;
}
.statement-band p b { font-weight: 800; }

/* ---------- Typographic "KEINE …" rows (Datenschutz redesign) ---------- */
.type-rows { display: grid; }
.type-row {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: var(--gutter);
  align-items: center;
  padding-block: var(--s-5);
  border-top: 0.5px solid rgba(255, 255, 255, .35);
}
.type-row:first-child { border-top: 0; }
.type-row h3 {
  font-size: 48px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
  line-height: 1.05;
}
.type-row h3 .accent { color: var(--yellow); }
.type-row p { line-height: 1.5; max-width: var(--sp5); justify-self: end; text-align: left; }

/* ---------- Borderless feature list (icon + copy, no boxes) ---------- */
/* Gleiche Sprache wie die Datenschutz-Karten (Figma 297:727): Spalten mit
   senkrechten Trennlinien ZWISCHEN den Positionen, gelbes Icon, linksbündig.
   Nicht klickbar → kein Hover. */
.feature-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  row-gap: var(--s-8);
}
.feature-list .feature {
  display: grid;
  gap: var(--s-2);
  align-content: start;
  justify-items: start;
  padding: 0 var(--s-4);
}
.feature-list .feature:not(:nth-child(3n + 1)) { border-left: 1px solid rgba(255, 255, 255, .35); }
.feature p { max-width: var(--sp3); }
.feature__icon {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  color: var(--yellow);
}
.feature__icon svg { width: 32px; height: 32px; }
.feature h3 {
  font-size: var(--fs-body);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
}
.feature p { line-height: 1.4; color: var(--white); }

/* Helle Variante (weiße Sektionen): dunkle Trennlinien, schwarzer Text */
.feature-list--light .feature:not(:nth-child(3n + 1)) { border-left-color: rgba(12, 28, 62, .18); }
.feature-list--light .feature__icon { color: var(--yellow-2); }
.feature-list--light .feature p { color: var(--text-dark); }

/* Bündige Variante (Bahnseite): die erste Spalte jeder Reihe steht ohne
   Einzug und mit dem Symbol an der Kante, links auf einer Linie mit
   Überschrift und Text darüber. Die Trennlinien bleiben, wo sie sind. */
.feature-list--buendig .feature:nth-child(3n + 1) { padding-left: 0; }
.feature-list--buendig .feature__icon { place-items: center start; }

/* on light backgrounds */

/* ---------- Ledger rows (regulatory standards) ---------- */
.ledger { display: grid; }
.ledger__row {
  display: grid;
  grid-template-columns: 4fr 8fr;
  gap: var(--gutter);
  align-items: center;
  padding-block: var(--s-4);
  border-top: 1px solid var(--grey-300);
}
.ledger__row:last-child { border-bottom: 1px solid var(--grey-300); }
.ledger__row h3 {
  font-size: 32px;
  font-weight: 800;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--blue-4);
}
.ledger__row p { line-height: 1.5; max-width: var(--sp7); }
/* Dunkle Variante für blaue Sektionen (Bahnseite „Gefördert umsetzen“) */
.ledger--dunkel .ledger__row { border-color: rgba(255, 255, 255, .22); }
.ledger--dunkel .ledger__row h3 { color: var(--yellow); }
.ledger--dunkel .ledger__row p { color: rgba(255, 255, 255, .88); }
/* Satz links, Button rechts; bricht auf schmalen Schirmen untereinander */
.ledger-abschluss {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-3);
}
.ledger-abschluss p { max-width: var(--sp7); }

/* ---------- Comparison table ---------- */
.compare table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  text-align: center;
}
.compare th, .compare td {
  padding: var(--s-4) var(--s-3);
  border-top: 0.5px solid rgba(255, 255, 255, .5);
  vertical-align: middle;
  line-height: 1.4;
}
.compare thead th, .compare thead td { border-top: 0; }
.compare col.compare-col--label { width: 22%; }
.compare th[scope="row"] { font-weight: 700; text-transform: uppercase; letter-spacing: var(--ls-wide); }
.compare thead th { font-weight: 700; text-transform: uppercase; letter-spacing: var(--ls-wide); }
/* highlighted Galvorn column as real cell backgrounds (no floating overlay) */
.compare thead th:last-child, .compare td.galvorn { background: var(--blue-3); font-weight: 700; }
.compare thead th:last-child { border-radius: var(--r-card) var(--r-card) 0 0; }
.compare tbody tr:last-child td.galvorn { border-radius: 0 0 var(--r-card) var(--r-card); }

/* ---------- Navy cards (Lösungen overview) ---------- */
/* ---------- Lösungskarten ---------------------------------------------
   Schwesterkarte zu den Kacheln der Startseite: gleiche Bewegung beim
   Überfahren (4 px anheben, Symbol auf volle Deckkraft), aber eigener
   Charakter durch Rahmen, Fließtext und Pfeil.

   Bewusst OHNE wiederholte Textzeile: sechsmal "Mehr erfahren" nebeneinander
   verstößt gegen WCAG 2.4.4 — Screenreader lesen die Linkliste vor, und sechs
   gleich benannte Verweise auf sechs verschiedene Ziele sind dort nicht
   unterscheidbar. Die ganze Karte ist der Verweis, ihr zugänglicher Name ist
   die Überschrift. Der Pfeil ist die sichtbare Zusage, kein zweiter Link.

   Alle Maße in geraden Zahlen.
   -------------------------------------------------------------------- */
.navy-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gutter); }
.navy-card {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--s-2);
  overflow: hidden;
  padding: var(--s-4);
  background: var(--blue-4);
  border-radius: var(--r-card);
  color: var(--white);
  text-align: left;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1), background-color .34s ease;
}
.navy-card:hover,
.navy-card:focus-visible {
  transform: translateY(-4px);
  background: #102448;
}
.navy-card:active { transform: translateY(0); }

/* Ortssymbol unten rechts, gespiegelt — es zeigt damit in die Karte hinein */
.navy-card__icon {
  position: absolute;
  right: -32px; bottom: -32px;
  width: 144px; height: 144px;
  opacity: .34;
  transform: scaleX(-1);
  pointer-events: none;
  /* Goldfilter springt statt zu überblenden, Begründung bei .tile__icon */
  transition: opacity .34s cubic-bezier(.2, .7, .3, 1);
}
/* Wie auf der Startseite hellt das Symbol beim Überfahren auf (weiß, kein
   Gold mehr). Dort geht es auf volle Deckkraft, hier nur auf 60 %: die
   Kacheln tragen nur ein kurzes Wort, diese Karten einen Absatz, der
   lesbar bleiben muss. */
.navy-card:hover .navy-card__icon,
.navy-card:focus-visible .navy-card__icon { opacity: .6; }

.navy-card h3 {
  position: relative;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  transition: color .34s cubic-bezier(.2, .7, .3, 1);
}
.navy-card p {
  position: relative;
  line-height: 1.5;
  color: rgba(255, 255, 255, .78);
}
.navy-card__pfeil {
  position: relative;
  display: inline-flex;
  color: var(--yellow);
  transition: transform .34s cubic-bezier(.2, .7, .3, 1);
}
.navy-card:hover .navy-card__pfeil,
.navy-card:focus-visible .navy-card__pfeil { transform: translateX(8px); }
@media (prefers-reduced-motion: reduce) {
  .navy-card, .navy-card__icon, .navy-card__pfeil, .navy-card h3,
  .navy-card:hover .navy-card__icon,
  .navy-card:focus-visible .navy-card__icon { transition: none; }
}

/* ---------- Prinzipien 01/02/03 ----------------------------------------
   Alle Werte direkt aus test-claude.fig, Sektion 1440x1216.
   Die Ziffern sind in Figma Geschwister der Textblöcke und liegen frei über
   der Sektion — sie brechen bewusst aus der 1280er Inhaltsspalte aus.
   .principles__inner spannt die volle Breite und hält den Seitenrand als
   Polsterung — waagerecht gelten deshalb die Figma-Werte unverändert,
   senkrecht Figma-y minus 64 (obere Polsterung der Sektion).
   Figma: 01 @1181,100 · 02 @60,362 · 03 @1128,678 · je 200px Black, Weiß 20 %
   ---------------------------------------------------------------------- */
.principles { position: relative; overflow: hidden; }
.principles__inner { position: relative; }

.principles__num {
  position: absolute;
  z-index: 0;
  font-size: 200px;
  font-weight: 900;
  /* 265 / 200 — in Figma steht "lh:100%", das ist dort die natürliche
     Zeilenhöhe der Schrift, nicht 1.0 */
  line-height: 1.325;
  letter-spacing: 0;
  color: rgba(255, 255, 255, .2);
  pointer-events: none;
  user-select: none;
}
/* 01 und 03 hängen an der rechten Wrap-Kante statt an festen left-Werten:
   mit left:1181px ragten sie bei Fenstern unter 1440 px aus dem Wrap und
   wurden vom overflow:hidden der Sektion abgeschnitten. right:48/56px
   ergibt bei voller Breite dieselbe Position, bleibt aber überall sichtbar. */
.principles__num--1 { right: 48px; top: 36px; }
.principles__num--2 { left: 60px;  top: 298px; }
.principles__num--3 { right: 56px; top: 614px; }

.principle { position: relative; display: grid; gap: var(--s-1); }
.principle h3, .principle p { position: relative; z-index: 1; }
.principle h3 {
  font-size: 64px;
  font-weight: 700;
  line-height: 1.328;          /* Figma: 85 px Zeilenkasten bei 64 px */
  letter-spacing: var(--ls-wide);
  white-space: nowrap;
}
.principle p {
  font-size: var(--fs-lead);
  font-weight: 400;
  line-height: 1.3333;         /* Figma: 32 px je Zeile bei 24 px */
  letter-spacing: var(--ls-wide);
}

/* 01 und 03 stehen rechtsbündig an der Inhaltskante, 02 linksbündig */
.principle--right { text-align: right; justify-items: end; }
.principle--1 { margin-top: 80px; }
.principle--1 p { max-width: 628px; }
.principle--2 { margin-top: 120px; justify-items: start; }
.principle--2 h3 { width: 973px; text-align: center; }
.principle--2 p { max-width: 856px; }
.principle--3 { margin-top: 152px; }
.principle--3 h3 { max-width: 780px; }
/* Figma nennt 780; die Schrift bricht hier erst ab 790 auf zwei Zeilen um */
.principle--3 p { max-width: 792px; }

.principles__cta { margin-top: 32px; text-align: right; }

/* ---------- Detail pages ---------- */
/* „Was Galvorn leisten kann" — helle Variante der Karten-Sprache aus dem
   Figma-Entwurf 297:727: keine Kästen, senkrechte Trennlinien ZWISCHEN den
   Spalten, gelbes Icon, linksbündig. Nicht klickbar → kein Hover. */
.detail-cards { display: grid; grid-template-columns: repeat(4, 1fr); row-gap: var(--s-6); }
.detail-cards--3 { grid-template-columns: repeat(3, 1fr); }
.detail-card {
  display: grid;
  justify-items: start;
  align-content: start;
  gap: var(--s-2);
  padding: 0 var(--s-4);
  color: var(--text-dark);
  text-align: left;
}
.detail-cards .detail-card:not(:nth-child(4n + 1)) { border-left: 1px solid rgba(12, 28, 62, .18); }
.detail-cards--3 .detail-card:not(:nth-child(4n + 1)) { border-left: 0; }
.detail-cards--3 .detail-card:not(:nth-child(3n + 1)) { border-left: 1px solid rgba(12, 28, 62, .18); }
.detail-card .kicker {
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--yellow-2);
}
.detail-card h3 {
  font-size: var(--fs-body);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
  margin-top: -8px;
}
.detail-card .detail-card__icon {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  color: var(--yellow-2);
}
.detail-card .detail-card__icon svg { width: 32px; height: 32px; }
.detail-card p { line-height: 1.4; color: var(--text-dark); }

/* split: stacked rows + visual */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gutter); align-items: stretch; }
.split__rows { display: grid; gap: var(--s-2); align-content: start; }
.split-row {
  display: grid;
  gap: var(--s-1);
  padding: var(--s-3);
  background: var(--white);
  border: 1px solid var(--grey-300);
  border-radius: var(--r-tile);
}
.split-row h3 { font-size: var(--fs-body); font-weight: 700; letter-spacing: var(--ls-wide); }
.split-row p { line-height: 1.5; color: var(--text-dark); letter-spacing: 0.01em; }
/* Gerätebilder (Startseite und Ortsseiten): Karten links, ein Bildbereich
   rechts. Mit data-geraete zeigt er das Bild der überfahrenen Karte, sonst
   ein festes Bild. Der Bildbereich hat das Format der Bilder (16:10), das
   Bild füllt ihn ganz: kein Rand, und das eingebrannte KI-Zeichen bleibt
   vollständig. Die Karten strecken sich auf seine Höhe, ab etwa 1280 px
   Breite sind beide gleich hoch. Schmaler sind die Karten höher, dann steht
   der Bildbereich mittig daneben. */
.geraete { grid-template-columns: 5fr 7fr; align-items: center; }
.geraete .split__rows { align-self: stretch; display: flex; flex-direction: column; gap: var(--s-1); }
.geraete .split-row { flex: 1 0 auto; align-content: center; padding: var(--s-2) 20px; }
.geraete__karte { cursor: pointer; transition: border-color .2s ease, box-shadow .2s ease; }
.geraete__karte.ist-aktiv { border-color: var(--blue-1); box-shadow: 0 0 0 1px var(--blue-1); }
.img-slot.geraete__buehne { aspect-ratio: 16 / 10; min-height: 0; background: #0B1A3D; }
.geraete__buehne::before { display: none; }
.geraete__bild {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .3s ease;
}
.geraete__bild.ist-aktiv { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .geraete__karte, .geraete__bild { transition: none; }
}

/* image placeholder in brand style */
.img-slot {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 260px;
  border-radius: var(--r-card);
  background: var(--grad-card);
  overflow: hidden;
}
.img-slot::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 70% 30%, rgba(86, 130, 220, .25), transparent 60%),
    radial-gradient(ellipse at 20% 80%, rgba(226, 178, 43, .12), transparent 55%);
}
.img-slot span {
  position: relative;
  color: rgba(255, 255, 255, .7);
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  padding: 10px 24px;
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: var(--r-pill);
}

/* side-note paragraph (e.g. Bremen Robotics hint) */
.note-aside {
  max-width: var(--sp6);
  padding-left: var(--s-3);
  border-left: 2px solid var(--yellow);
  color: var(--text-dark);
  letter-spacing: 0.01em;
}

/* press link cards (light) */

/* ---------- Accordion (Über Galvorn) ---------- */
.accordion {
  background: var(--white);
  border-radius: var(--r-card);
  padding: var(--s-4) var(--s-8);
  box-shadow: 0 4px 24px rgba(0, 0, 0, .25);
}
.accordion details { border-top: 0.5px solid var(--black); }
.accordion details:first-child { border-top: 0; }
.accordion summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-3);
  padding-block: 16px;
  cursor: pointer;
  list-style: none;
  color: var(--black);
  letter-spacing: var(--ls-wide);
}
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary svg { flex: 0 0 auto; transition: transform .18s ease; }
.accordion details[open] summary svg { transform: rotate(180deg); }
.accordion details[open] summary { font-weight: 700; }
.accordion .accordion__body { padding: 0 0 var(--s-3); line-height: 1.5; max-width: var(--sp8); color: var(--text-dark); }
.accordion .accordion__body p + p { margin-top: var(--s-2); }

/* ---------- Press cards (Über Galvorn, dark) ---------- */
/* Kleine mittige Zwischenüberschrift im Pressebereich („Highlights“ / „Alle
   Berichte“). Bewusst klein und grau, damit die H2 „Pressestimmen“ die Sektion
   führt und die beiden Blöcke nur voneinander getrennt werden. */
.press-label {
  text-align: center;
  font-size: var(--fs-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--grey-600);
}
/* Nur die Highlights werden hervorgehoben. Markengelb erreicht auf Weiß nur
   2.36:1 und liegt damit unter AA (4.5:1 für 12px) — auf Wunsch so gesetzt.
   Die Marke nutzt das Gelb sonst ausschließlich auf dunklem Grund (8.50:1). */
.press-label--gelb { color: var(--yellow-2); }
.press-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gutter); }
/* Feedback Aug 2026: Karten im Blau-Verlauf der Orte-Kacheln auf weißer
   Sektion, komplett klickbar (Stretched Link), Hover-Lift wie die Kacheln. */
.press-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 0.5px solid var(--charcoal);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1);
}
.press-card:has(.press-card__more:hover) { transform: translateY(-4px); }
.press-card:has(.press-card__more:active) { transform: translateY(0); }
/* Stretched Link: macht die ganze Karte klickbar, ohne ein zweites <a>
   um die Karte zu legen (verschachtelte Links sind ungültiges HTML). */
.press-card__more::after { content: ""; position: absolute; inset: 0; }
.press-card__img {
  position: relative;
  height: 160px;
  background: var(--blue-1);
}
/* Artikelbilder als Duotone: Sättigung auf null, dunkelblau überlagert —
   so fügt sich jedes gezogene Pressebild automatisch ins Design, ohne dass
   Bilder von Hand bearbeitet werden müssen (gilt auch für künftige). */
.press-card__img img {
  width: 100%; height: 100%;
  object-fit: cover;
}
.press-card__img::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(47, 107, 229, .2);
}
/* Play-Symbol für Video-Beiträge (karte.play in presse.json), im Stil des
   Startknopfs der Videobühne, nur kleiner. Liegt über dem Farbschleier. */
.press-card__play {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.press-card__play svg {
  box-sizing: content-box;
  width: 22px; height: 22px;
  padding: 13px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .3);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath fill-rule='evenodd' d='M32 0a32 32 0 1 1 0 64a32 32 0 1 1 0-64zM27 22v20l17-10z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath fill-rule='evenodd' d='M32 0a32 32 0 1 1 0 64a32 32 0 1 1 0-64zM27 22v20l17-10z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  /* das gezeichnete Dreieck unsichtbar, sichtbar ist die Aussparung */
  color: transparent;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1), background-color .34s ease;
}
.press-card:has(.press-card__more:hover) .press-card__play svg { transform: scale(1.08); background-color: rgba(255, 255, 255, .45); }
.press-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-2);
  /* --grad-card lief nur von #070E20 nach #0C1C3E — zu dicht beieinander, um
     als Verlauf sichtbar zu sein. Alle Stopps bleiben zwischen --blue-3 und
     --blue-5, damit das gelbe Quellen-Label überall mindestens 4.5:1 hält
     (bei --blue-3 exakt 4.50:1). */
  background-image: linear-gradient(150deg, var(--blue-3) 0%, var(--blue-4) 52%, var(--blue-5) 100%);
  /* Doppelt so groß wie der Textteil, damit der Verlauf beim Hover verschoben
     werden kann: background-position ist animierbar, ein Gradient selbst nicht. */
  background-size: 200% 200%;
  background-position: 0% 0%;
  transition: background-position .8s cubic-bezier(.2, .7, .3, 1);
  color: var(--white);
  flex: 1;
}
/* Hover: der Verlauf wandert diagonal durch den Textteil — das Licht zieht
   über die Karte, ohne dass Farben ausgetauscht werden. */
.press-card:has(.press-card__more:hover) .press-card__body { background-position: 100% 100%; }
@media (prefers-reduced-motion: reduce) {
  .press-card__body { transition: none; }
  .press-card:has(.press-card__more:hover) .press-card__body { background-position: 0% 0%; }
}
.press-card__meta { display: flex; justify-content: space-between; gap: var(--s-2); font-weight: 700; color: var(--yellow-2); }
.press-card h3 { font-size: var(--fs-body); font-weight: 700; letter-spacing: var(--ls-wide); line-height: 1.3; }
.press-card p { line-height: 1.5; }
.press-card__more {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: 700;
  margin-top: auto;
}
.press-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  margin-top: var(--s-8);
  /* Die Karten stehen seit Aug 2026 auf weißer Sektion (siehe .press-card) —
     der Pager erbte davor das Weiß der alten Navy-Sektion und war unsichtbar. */
  color: var(--text-dark);
}
.press-pager button { color: inherit; display: grid; place-items: center; }
.press-pager button[disabled] { opacity: .4; cursor: default; }

/* ---------- Forms (Kontakt / Jetzt starten) ---------- */
.form-grid { display: grid; gap: var(--s-2); }
.field { display: grid; gap: 8px; }
.field label,
.field__legend { font-size: var(--fs-small); font-weight: 600; text-transform: uppercase; letter-spacing: var(--ls-wider); }
.field__legend { margin: 0; }
.field input, .field textarea, .field select {
  font: inherit;
  letter-spacing: 0.01em;
  padding: 16px;
  border: 1px solid var(--grey-400);
  border-radius: var(--r-tile);
  background: var(--white);
  color: var(--text-dark);
  width: 100%;
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: 2px solid var(--blue-1);
  outline-offset: 0;
  border-color: var(--blue-1);
}
.field textarea { min-height: 140px; resize: vertical; line-height: 1.5; }
.field--row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }

.panel {
  background: var(--white);
  border: 1px solid var(--grey-300);
  border-radius: var(--r-card);
  padding: var(--s-4);
  display: grid;
  gap: var(--s-3);
  align-content: start;
}
.panel > h2, .panel > h3 { font-size: 24px; font-weight: 800; line-height: 1.25; }
.panel .hint { color: var(--grey-600); line-height: 1.5; letter-spacing: 0.01em; }

/* dark glass panel variant */
.panel--glass {
  background: rgba(255, 255, 255, .1);
  border: 0.5px solid rgba(255, 255, 255, .4);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--white);
}
.panel--glass .field input, .panel--glass .field textarea, .panel--glass .field select {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .35);
  color: var(--white);
}
.panel--glass .field ::placeholder { color: rgba(255, 255, 255, .6); }
.panel--glass .hint { color: rgba(255, 255, 255, .75); }

/* Die Spalten sind unterschiedlich hoch (links das Formular, rechts die
   Kontaktdaten). Ohne align-self würde die kürzere auf Zeilenhöhe gestreckt
   und stünde als hoher leerer Kasten da. */
.contact-cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gutter); }
.contact-cols > * { align-self: start; }
/* Kontaktseite: die zwei Formularkästen sollen gleich hoch sein, deshalb
   stehen sie in derselben Rasterzeile, und die Kontaktdaten rutschen in die
   zweite Zeile der linken Spalte. Ausdrückliche Platzierung, weil die
   Reihenfolge im Markup (Formular, Kontaktdaten, Newsletter) die ist, in der
   es auf dem Telefon gestapelt werden soll.
   align-self: stretch hebt für die zwei Kästen das start aus .contact-cols
   auf — sonst behielte jeder seine Eigenhöhe und das Gleichziehen fiele aus. */
.contact-cols--formulare > :nth-child(1) { grid-area: 1 / 1; align-self: stretch; }
.contact-cols--formulare > :nth-child(2) { grid-area: 2 / 1; align-self: stretch; }
.contact-cols--formulare > :nth-child(3) { grid-area: 1 / 2; align-self: stretch; }
.contact-cols--formulare > :nth-child(4) { grid-area: 2 / 2; align-self: stretch; }

/* Die zwei Formularkästen sind gleich hoch, ihre Knöpfe standen aber
   verschieden tief — das kürzere Formular hörte einfach früher auf. Jetzt
   bekommt das Formular die Resthöhe des Kastens (1fr) und schiebt seine
   letzte Zeile, die mit dem Knopf, nach unten.
   Das Formular ist dafür eine Flexspalte: als Raster bliebe margin-top:auto
   wirkungslos, weil der freie Platz dort hinter der letzten Zeile liegt und
   nicht in ihr. Die Darstellung ändert sich dadurch nicht, .form-grid ist
   ohnehin einspaltig und der gap gilt in beiden Verfahren.
   Angesprochen wird ausdrücklich der Kasten um den Absendeknopf, nicht das
   letzte Kind: main.js hängt an jedes Formular noch Honigtopf und Zeitstempel
   an: :last-child traf damit ein unsichtbares Eingabefeld und verschob nichts. */
.contact-cols--formulare > :nth-child(1),
.contact-cols--formulare > :nth-child(3) { grid-template-rows: auto 1fr; }
.contact-cols--formulare > :nth-child(1) > form,
.contact-cols--formulare > :nth-child(3) > form { display: flex; flex-direction: column; }
.contact-cols--formulare > :nth-child(1) > form > :has(> button[type="submit"]),
.contact-cols--formulare > :nth-child(3) > form > :has(> button[type="submit"]) { margin-top: auto; }

.contact-facts { display: grid; gap: var(--s-2); align-content: start; }
.contact-facts a { font-weight: 700; }
.contact-facts a:hover { color: var(--blue-05); }
/* Profile nur als Symbol. Mit Beschriftung griffen die Fließtext-Link-Regeln
   (fett und unterstrichen) und der Kasten wirkte überladen. Die runde Fläche
   von 40px hält das Ziel trotz 20px-Symbol gut treffbar, den Namen trägt das
   aria-label. */
.contact-social { display: flex; gap: var(--s-1); }
.contact-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--grey-300);
  border-radius: 50%;
  color: var(--grey-600);
  transition: color .15s ease, border-color .15s ease;
}
.contact-social a:hover { color: var(--blue-1); border-color: var(--blue-1); }
.contact-social svg { flex: none; }

/* ---------- Nächste Veranstaltung (Kontaktseite) ---------- */
/* Links Name und Einladung, rechts Termin, Ort und Anmeldung in einer
   Karte. Ohne Bild: Datum und Ort sind der Inhalt. */
.termin {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-8);
  align-items: center;
}
/* Augenbraue und Überschrift gehören eng zusammen, die Einladung darunter
   braucht Luft. */
.termin__eyebrow {
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--yellow);
  margin-bottom: var(--s-1);
}
.termin__titel::after {
  content: "";
  display: block;
  width: 88px; height: 4px;
  margin-top: var(--s-3);
  border-radius: 2px;
  background: var(--yellow);
}
.termin__akzent { color: var(--yellow); }
.termin__hinweis {
  max-width: 44ch;
  margin-top: var(--s-4);
  line-height: 1.6;
  color: rgba(255, 255, 255, .76);
}
.termin__karte {
  display: grid;
  gap: var(--s-5);
  justify-items: start;
  padding: var(--s-5);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--r-card);
  background: rgba(255, 255, 255, .04);
}
.termin__daten { display: grid; gap: var(--s-3); }
.termin__daten li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-2);
  align-items: start;
  font-size: var(--fs-lead);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: var(--ls-wide);
}
/* Symbol optisch auf die erste Textzeile setzen. */
.termin__symbol { color: var(--yellow); padding-top: 2px; }
.termin__symbol svg { width: 28px; height: 28px; display: block; }

/* booking slots */
.slots { display: flex; flex-wrap: wrap; gap: var(--s-1); }
/* Das Radio-Feld bleibt bedienbar, ist aber unsichtbar — sichtbar ist sein
   Label. Nicht mit display:none arbeiten, sonst verliert es den Fokus. */
.slot__feld, .cal-day__feld {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.slot {
  display: inline-block;
  padding: 10px 24px;
  border: 1px solid var(--grey-400);
  border-radius: var(--r-pill);
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  cursor: pointer;
}
.slot:hover,
.slot__feld:checked + .slot { border-color: var(--blue-4); background: var(--blue-4); color: var(--white); }
.slot__feld:focus-visible + .slot { outline: 2px solid var(--blue-1); outline-offset: 2px; }
.slots-gruppe { border: 0; padding: 0; margin: 0; min-inline-size: 0; }

/* light variant of type-rows (on white sections) */
.type-rows--light .type-row { border-color: var(--grey-300); }
.type-rows--light .type-row h3 { color: var(--blue-4); }
.type-rows--light .type-row h3 .accent { color: var(--yellow-2); }

/* blurred star decoration (Datenschutz regulatory section) */
.stars-deco {
  position: absolute;
  right: -60px;
  top: 46px;
  width: 608px;
  height: 608px;
  opacity: .6;
  filter: blur(8px);
  pointer-events: none;
}
/* Spiegelbildlich am linken Rand (Bereich Behörden & Leitstellen). Die
   Breakpoints setzen nur right; ist left gesetzt, ignoriert der Browser
   right bei fester Breite, die Sterne bleiben also links. */
.stars-deco--links { left: -60px; right: auto; }

/* calendar (Kontakt) */
.calendar { width: 100%; border-collapse: collapse; table-layout: fixed; }
.calendar th {
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--grey-600);
  padding-bottom: var(--s-1);
}
.calendar td { text-align: center; padding: 2px; }
.calendar-gruppe { border: 0; padding: 0; margin: 0; min-inline-size: 0; }
.cal-day {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1.4;
  border-radius: var(--r-tile);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-dark);
  cursor: pointer;
}
.cal-day:hover { background: var(--grey-100); }
/* Wochenenden sind nicht buchbar und deshalb gar kein Bedienelement mehr */
.cal-day--zu { color: var(--grey-400); cursor: default; }
.cal-day--zu:hover { background: none; }
.cal-day__feld:checked + .cal-day { background: var(--blue-4); color: var(--white); }
.cal-day__feld:focus-visible + .cal-day { outline: 2px solid var(--blue-1); outline-offset: -2px; }

/* ---------- Pilot stats (Jetzt starten) ---------- */

/* ---------- Pilotprogramm: Leistungen oben ---------- */
/* Sprungziel unter der festen Kopfzeile freihalten */
.h2[id] { scroll-margin-top: 112px; }
.pilot-enthalten__hinweis { font-size: 14px; color: rgba(12, 28, 62, .6); }
/* Leistungsliste auf der Pilotseite: dunkelblaue Symbole, größere Titel
   in normaler Schreibung, enger gesetzt als die Liste auf der Startseite. */
.feature-list--pilot { row-gap: var(--s-5); }
.feature-list--pilot .feature { gap: var(--s-1); padding-inline: var(--s-3); }
.feature-list--pilot.feature-list--buendig .feature:nth-child(3n + 1) { padding-left: 0; }
.feature-list--pilot .feature__icon { width: 40px; height: 40px; }
.feature-list--pilot .feature__icon svg { width: 28px; height: 28px; }
.feature-list--pilot .feature h3 {
  font-size: 22px;
  font-weight: 800;
  line-height: 1.25;
  text-transform: none;
  letter-spacing: 0;
  color: var(--blue-4);
}

/* ---------- Pilotprogramm: Zeitplan ----------
   Eine durchgehende Spur über acht Monate; jede Phase ist so breit wie
   ihre Monate (--monate). Darunter Monat, Phase und ein Satz.
   Die Pilotphase trägt Gold — sie ist der Kern des Angebots. */
.zeitplan {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  /* Einzelmonate brauchen eine Mindestbreite für ihren Satz; die Pilotphase
     bleibt dennoch deutlich die längste Strecke. */
  grid-template-columns: repeat(3, minmax(184px, 1fr)) 3fr 2fr;
  column-gap: 4px;
}
.zeitplan__phase { display: grid; align-content: start; gap: var(--s-1); padding-right: var(--s-2); }
.zeitplan__balken {
  display: block;
  height: 8px;
  margin-block: 4px var(--s-2);
  border-radius: 4px;
  background: var(--blue-3);
}
.zeitplan__phase:first-child .zeitplan__balken { background: var(--blue-05); }
.zeitplan__phase--einbau .zeitplan__balken { background: var(--blue-1); }
.zeitplan__phase--test .zeitplan__balken { background: var(--blue-3); }
.zeitplan__phase--pilot .zeitplan__balken { background: var(--yellow); }
.zeitplan__phase--rollout .zeitplan__balken { background: var(--blue-4); }
.zeitplan__monat {
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--text-dark);
}
.zeitplan h3 { font-size: var(--fs-body); font-weight: 800; text-transform: uppercase; letter-spacing: var(--ls-wide); color: var(--blue-4); }
.zeitplan p { line-height: 1.4; color: var(--text-dark); max-width: 28ch; }
/* Einblenden: die Spur füllt sich von links nach rechts */
@media (prefers-reduced-motion: no-preference) {
  .zeitplan.reveal .zeitplan__balken { transform: scaleX(0); transform-origin: left; }
  .zeitplan.reveal.in-view .zeitplan__balken {
    transform: none;
    transition: transform .5s cubic-bezier(.2, .7, .3, 1) calc(var(--i) * .12s);
  }
}

/* Rücksprung aus dem Angebotsbereich zu den Leistungen */
.umfang__mehr {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  justify-self: start;
  padding: 10px 20px;
  border: 1px solid rgba(255, 255, 255, .6);
  border-radius: var(--r-pill);
  color: var(--white);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  transition: background-color .2s ease, border-color .2s ease;
}
.umfang__mehr:hover,
.umfang__mehr:focus-visible { background: rgba(255, 255, 255, .1); border-color: var(--white); }


/* ==========================================================================
   Motion: scroll reveals + hero scene
   ========================================================================== */

/* scroll-triggered reveal (elements get .reveal via JS, .in-view when visible) */
/* WICHTIG: `translate` statt `transform` — sonst überschreibt das Reveal jeden Hover-Transform */
.reveal {
  opacity: 0;
  translate: 0 28px;
  /* transform/Farben MÜSSEN hier mitlaufen — sonst überschreibt die Shorthand die Hover-Transition */
  transition:
    opacity .7s cubic-bezier(.2, .6, .2, 1),
    translate .7s cubic-bezier(.2, .6, .2, 1),
    transform .34s cubic-bezier(.2, .7, .3, 1),
    background-color .34s ease,
    border-color .34s ease;
  transition-delay: var(--reveal-delay, 0s), var(--reveal-delay, 0s), 0s, 0s, 0s;
}
.reveal.in-view { opacity: 1; translate: 0 0; }

/* plaza life: everyone bobs and wanders, varied builds */
.hero .person {
  animation:
    person-bob var(--bob, 4s) ease-in-out infinite alternate,
    person-wander var(--wander, 11s) ease-in-out infinite alternate;
}
/* sanftes Wiegen um den Fußpunkt — kein vertikales Schweben */
@keyframes person-bob {
  from { rotate: -1.1deg; }
  to { rotate: 1.1deg; }
}
@keyframes person-wander {
  0%   { transform: translateX(0); }
  35%  { transform: translateX(calc(var(--wx, 40px) * .55)); }
  70%  { transform: translateX(calc(var(--wx, 40px) * .3)); }
  100% { transform: translateX(var(--wx, 40px)); }
}
/* builds */
.person--skinny::after { width: calc(var(--d) * 0.68); left: calc(var(--d) * 0.16); }
/* couples / families walk & stand together */
.pgroup {
  position: absolute;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  animation: person-wander var(--wander, 24s) ease-in-out infinite alternate;
}
.pgroup .person { position: relative; left: auto; top: auto; }
.hero .pgroup .person { animation: person-bob var(--bob, 6s) ease-in-out infinite alternate; }
/* passers-by crossing the plaza */

/* ==========================================================================
   Hero-Szene — 40-Sekunden-Schleife, immer nur ein Vorgang:
   0,0s– 4,2s  der Zug fährt ein
   4,2s– 7,2s  Fahrgäste steigen ein
   7,2s–21,2s  Zoom in den Wagen: Streit → Schlägerei → B geht zu Boden →
               markiert und beobachtet → zwei Fahrgäste helfen B auf → Zoom heraus
  23,6s–28,0s  Fahrgäste steigen aus
  26,4s–33,8s  Koffer wird hereingetragen und abgestellt — markiert wird NUR
               der Koffer, die Person geht unmarkiert weiter
  33,2s–34,6s  der Zug fährt ab
  34,8s–40,0s  eine Person auf dem Bahnsteig sackt zusammen, Label NOTFALL

   Der frühere erste Takt (auffällige Person, 0–6s) ist entfallen; alle Takte
   sind deshalb um 13 Prozentpunkte nach vorn gerückt, und am Ende ist Platz
   für den Notfall-Takt frei geworden.
   ========================================================================== */

/* the ICE arrives nose-first from the LEFT, stands through everything, departs at the end */
.hero__graphics .train { animation: train-run 40s linear infinite; }
@keyframes train-run {
  0%, 2% { translate: -1952px 0; }
  4%  { translate: -1248px 0; }
  7%  { translate: -520px 0; }
  9%  { translate: -240px 0; }
  10.5% { translate: -176px 0; }   /* eingefahren — durchgehend in eine Richtung */
  83%  { translate: -176px 0; }
  84.5% { translate: 448px 0; }
  86.5%, 100% { translate: 1952px 0; }
}

/* Gleis: eine klare Schiene mit direkt anliegenden Schwellen */
.scene__track {
  position: absolute;
  left: -144px; top: 192px;
  width: calc(100% + 280px); height: 8px;
  background:
    linear-gradient(rgba(170, 192, 237, .42), rgba(170, 192, 237, .42)) 0 0 / 100% 2px no-repeat,
    repeating-linear-gradient(90deg,
      rgba(170, 192, 237, .17) 0 4px,
      transparent 4px 30px) 0 2px / 100% 6px no-repeat;
}

.hero__graphics { animation: hero-zoom 40s ease-in-out infinite; transform-origin: 61% 13%; }
@keyframes hero-zoom {
  0%, 18%  { transform: none; }
  24%      { transform: scale(1.7); }
  53%      { transform: scale(1.7); }
  59%, 100% { transform: none; }
}

.scene { position: absolute; inset: 0; pointer-events: none; }
.scene .person { animation: none; }

/* shared reticle look */
.scene__ret {
  position: absolute;
  opacity: 0;
  --corner: 14px;
  --thick: 2px;
  background:
    linear-gradient(var(--yellow), var(--yellow)) 0 0 / var(--corner) var(--thick) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 0 0 / var(--thick) var(--corner) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 100% 0 / var(--corner) var(--thick) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 100% 0 / var(--thick) var(--corner) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 0 100% / var(--corner) var(--thick) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 0 100% / var(--thick) var(--corner) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 100% 100% / var(--corner) var(--thick) no-repeat,
    linear-gradient(var(--yellow), var(--yellow)) 100% 100% / var(--thick) var(--corner) no-repeat;
}
.scene__ret svg { display: none; }
/* Label-Pille über dem Rahmen */
.det-label {
  position: absolute;
  left: 50%; bottom: 100%;
  margin-bottom: 8px;
  translate: -50% 0;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--yellow);
  color: var(--blue-5);          /* dunkel auf Gelb = 8.5:1 statt 1.97:1 (WCAG AA) */
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(7, 14, 32, .45);
}
.train .scene__ret--fight .det-label {
  margin-bottom: 8px;
  padding: 2px 8px;
  font-size: 10px;
  letter-spacing: .06em;
}
.train .scene__ret--fight {
  z-index: 3; --corner: 10px; --thick: 1.6px; }

/* --- beat 2/3: the train and its passengers --- */
.hero .train .person { position: absolute; animation: none; --pblur: .7px; }
.hero .train .pass {
  bottom: 12px;
  animation: pass-sway var(--sway, 3.5s) ease-in-out infinite alternate;
}
@keyframes pass-sway {
  from { transform: translateX(0); }
  to { transform: translateX(8px); }
}

/* --- Aussteigende nach dem Zoom-out --- */
.hero .scene__exit.person {
  position: absolute;
  top: 192px;
  opacity: 0;
  animation: exit-train 40s linear infinite;
}
.hero .scene__exit--b.person { animation-name: exit-train-b; }
.hero .scene__exit--c.person { animation-name: exit-train-c; }
@keyframes exit-train {
  0%, 59% { opacity: 0; translate: 0 0; rotate: 0deg; }
  60% { opacity: 1; }
  62% { translate: 24px 56px; rotate: 2deg; }
  64% { translate: 48px 112px; rotate: -2deg; }
  66% { translate: 72px 168px; rotate: 2deg; }
  68% { opacity: 1; translate: 96px 216px; rotate: 0deg; }
  70%, 100% { opacity: 0; translate: 104px 232px; }
}
@keyframes exit-train-b {
  0%, 61% { opacity: 0; translate: 0 0; rotate: 0deg; }
  62% { opacity: 1; }
  64% { translate: -24px 56px; rotate: -2deg; }
  66% { translate: -48px 112px; rotate: 2deg; }
  68% { translate: -72px 168px; rotate: -2deg; }
  70% { opacity: 1; translate: -88px 216px; rotate: 0deg; }
  72%, 100% { opacity: 0; translate: -96px 232px; }
}
@keyframes exit-train-c {
  0%, 63% { opacity: 0; translate: 0 0; rotate: 0deg; }
  64% { opacity: 1; }
  66% { translate: 16px 64px; rotate: 2deg; }
  68% { translate: 32px 128px; rotate: -2deg; }
  70% { translate: 48px 192px; rotate: 2deg; }
  72% { opacity: 1; translate: 64px 240px; rotate: 0deg; }
  74%, 100% { opacity: 0; translate: 72px 256px; }
}

/* --- beat 4: the brawl --- */
.train .scene__fighter {
  position: absolute;
  z-index: 2;
  bottom: 8px;
  width: var(--d);
  height: calc(var(--d) * 3.86);
  transform-origin: 50% 100%;
  animation: fight-a 40s linear infinite;
}
.train .scene__fighter .person { left: 0; top: 0; --pblur: .7px; animation: none; }
.train .scene__fighter .person--yellow { --pblur: 0px; }
.train .scene__fighter .person--yellow {
  opacity: 0;
  animation: fight-flag 40s linear infinite;
}
.train .scene__fighter--b { animation-name: fight-b; }

@keyframes fight-a {
  0%, 25% { transform: none; }
  26% { transform: translateX(2px) rotate(3deg); }
  27.2% { transform: translateX(-2px) rotate(-2deg); }
  28.4% { transform: translateX(2px) rotate(3deg); }
  29.6% { transform: translateX(-2px) rotate(-2deg); }
  30.8% { transform: translateX(2px) rotate(2deg); }
  32.3% { transform: translateX(8px) rotate(4deg); }
  33.5% { transform: translateX(20px) rotate(15deg); }
  34.7% { transform: translateX(6px) rotate(3deg); }
  35.9% { transform: translateX(22px) rotate(16deg); }
  37.1% { transform: translateX(6px) rotate(2deg); }
  38.3% { transform: translateX(24px) rotate(18deg); }
  39.5% { transform: translateX(6px) rotate(2deg); }
  41% { transform: translateX(2px) rotate(0deg); }
  42.5%, 100% { transform: none; }
}
@keyframes fight-b {
  0%, 25% { transform: none; }
  26% { transform: translateX(-2px) rotate(-3deg); }
  27.2% { transform: translateX(2px) rotate(2deg); }
  28.4% { transform: translateX(-2px) rotate(-3deg); }
  29.6% { transform: translateX(2px) rotate(2deg); }
  30.8% { transform: translateX(-2px) rotate(-2deg); }
  32.3% { transform: translateX(-8px) rotate(-4deg); }
  33.5% { transform: translateX(-4px) rotate(6deg); }
  35% { transform: translateX(-16px) rotate(-13deg); }
  36.5% { transform: translateX(-2px) rotate(4deg); }
  38.3% { transform: translateX(6px) rotate(24deg); }
  39.5% { transform: translateX(12px) rotate(56deg); }
  41% { transform: translateX(16px) rotate(86deg); }
  52.5% { transform: translateX(16px) rotate(86deg); }
  55% { transform: translateX(8px) rotate(30deg); }
  57%, 100% { transform: none; }
}
@keyframes fight-flag {
  0%, 34% { opacity: 0; }
  35.5% { opacity: 1; }
  51.5% { opacity: 1; }
  54%, 100% { opacity: 0; }
}
.scene__fighter .person.base { animation: base-hide-fight 40s linear infinite; }
@keyframes base-hide-fight {
  0%, 34% { opacity: 1; }
  35.5% { opacity: 0; }
  51.5% { opacity: 0; }
  54%, 100% { opacity: 1; }
}

/* yellow fists */
.scene__fighter .fist {
  position: absolute;
  filter: blur(.7px);
  top: 30%;
  right: calc(var(--d) * -0.6);
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--white);
  opacity: 0;
  animation: jab-a 40s linear infinite, fist-color 40s linear infinite;
}
/* Fäuste wechseln zeitgleich mit den Körpern auf Gelb */
/* Übergang deckungsgleich mit fight-flag (47%→48.5% ein, 64.5%→67% aus) */
/* Farbe UND Unschärfe folgen dem Körper: unerkannt weich, erkannt scharf.
   Ohne den Filter stachen die Fäuste als einzige scharfe Punkte hervor. */
@keyframes fist-color {
  0%, 34% { background: var(--white); filter: blur(.7px); }
  35.5%, 51.5% { background: var(--yellow); filter: blur(0px); }
  54%, 100% { background: var(--white); filter: blur(.7px); }
}
.scene__fighter--b .fist {
  right: auto;
  left: calc(var(--d) * -0.6);
  animation-name: jab-b, fist-color;
}
@keyframes jab-a {
  0%, 32% { opacity: 0; transform: translate(0, 0); }
  32.7% { opacity: 1; transform: translate(2px, -4px); }
  33.5% { transform: translate(22px, -8px); }
  34.7% { transform: translate(2px, 0); }
  35.9% { transform: translate(24px, -10px); }
  37.1% { transform: translate(4px, 0); }
  38.3% { transform: translate(26px, -8px); }
  39.5% { transform: translate(2px, 0); }
  40.5% { opacity: 1; transform: translate(2px, 0); }
  42%, 100% { opacity: 0; transform: translate(0, 0); }
}
@keyframes jab-b {
  0%, 33% { opacity: 0; transform: translate(0, 0); }
  33.7% { opacity: 1; transform: translate(-2px, -4px); }
  35% { transform: translate(-22px, -8px); }
  36.3% { transform: translate(-2px, 0); }
  38%, 100% { opacity: 0; transform: translate(0, 0); }
}

/* smaller reticle over the brawl, rides inside the train */
.train .scene__ret--fight {
  left: 66.2%; top: 24px;
  width: 130px; height: 82px;
  animation: ret-fight 40s ease-in-out infinite;
}
@keyframes ret-fight {
  0%, 34% { opacity: 0; transform: scale(1.4); }
  36%   { opacity: 1; transform: scale(1); }
  38.5% { transform: scale(1.08); }
  40.5% { transform: scale(1); }
  51.5% { opacity: 1; }
  54.5%, 100% { opacity: 0; transform: scale(1.2); }
}

/* --- beat 6: the suitcase --- */
.scene__walker {
  position: absolute;
  left: -80px; top: 276px;
  width: 28px; height: 108px;
  animation: walk 40s linear infinite;
}
/* Die Person bleibt durchgehend grau: markiert wird der Koffer, nicht sie.
   Vorher wechselte sie beim Abstellen auf Gelb und trug das Label "Person". */
.scene__walker .person { position: absolute; left: 0; top: 0; }
@keyframes walk {
  0%, 66% { transform: translateX(0) rotate(0deg); }
  67.5% { transform: translateX(190px) rotate(2.5deg); }
  69% { transform: translateX(400px) rotate(-2.5deg); }
  70.5% { transform: translateX(610px) rotate(2.5deg); }
  72% { transform: translateX(820px) rotate(-2.5deg); }
  73.3% { transform: translateX(1000px) rotate(2deg); }
  74.3% { transform: translateX(1060px) rotate(0deg); }
  76.5% { transform: translateX(1060px) rotate(0deg); }  /* stellt den Koffer ab */
  77.6% { transform: translateX(1180px) rotate(10deg); } /* und rennt */
  78.7% { transform: translateX(1310px) rotate(6deg); }
  79.8% { transform: translateX(1440px) rotate(11deg); }
  80.9% { transform: translateX(1560px) rotate(7deg); }
  82% { transform: translateX(1680px) rotate(11deg); }
  84.5%, 100% { transform: translateX(1900px) rotate(9deg); }
}
/* Hier standen walker-flag und ret-walker: die Person wurde beim Abstellen
   gelb und bekam den Rahmen mit dem Label "Person". Beides ist weg — die
   Erkennung gilt dem Gegenstand. */

/* --- Letzter Takt: eine Person auf dem Bahnsteig sackt zusammen --- */
.scene__fall {
  position: absolute;
  /* Auf dem freien Stück Bahnsteig rechts der Mitte — dort, wo vorher die
     Fußgängerszene lief. Weiter unten liegt die Überschrift darüber. */
  left: 75.5%; top: 250px;
  width: var(--d); height: calc(var(--d) * 3.86);
  animation: fall-show 40s linear infinite;
}
/* Kippen steckt im inneren Element, damit der Rahmen gerade stehen bleibt —
   dasselbe Vorgehen wie früher bei der Fußgängerszene. */
.scene__fall__body {
  position: absolute; inset: 0;
  transform-origin: 50% 100%;
  animation: fall-tilt 40s ease-in infinite;
}
.scene__fall .person { position: absolute; left: 0; top: 0; --pblur: .6px; }
.scene__fall .person.person--yellow {
  --pblur: 0px;
  opacity: 0;
  animation: fall-flag 40s linear infinite;
}
.scene__fall .person.base { animation: fall-hide 40s linear infinite; }
/* Die Person steht die ganze Schleife über auf dem Bahnsteig und blendet nur
   an der Nahtstelle kurz weg, damit der Sturz nicht rückwärts abläuft. */
@keyframes fall-show {
  0% { opacity: 0; }
  1.5%, 98.5% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes fall-tilt {
  0%, 87% { transform: rotate(0deg); }
  88.2%   { transform: rotate(-8deg); }    /* knickt ein */
  90%     { transform: rotate(-82deg); }
  91%     { transform: rotate(-88deg); }   /* liegt */
  100%    { transform: rotate(-88deg); }
}
@keyframes fall-flag {
  0%, 91% { opacity: 0; }
  92.2%   { opacity: 1; }
  100%    { opacity: 1; }
}
@keyframes fall-hide {
  0%, 91% { opacity: 1; }
  92.2%, 100% { opacity: 0; }
}
.scene__fall .scene__ret--fall {
  left: calc(var(--d, 30px) * -4.1); top: calc(var(--d, 30px) * 3);
  width: calc(var(--d, 30px) * 5.2); height: calc(var(--d, 30px) * 1.75);
  animation: ret-fall 40s ease-in-out infinite;
}
@keyframes ret-fall {
  0%, 91% { opacity: 0; transform: scale(1.5); }
  92.2%   { opacity: 1; transform: scale(1); }
  93.8%   { transform: scale(1.08); }
  95.5%   { transform: scale(1); }
  99%     { opacity: 1; }
  100%    { opacity: 0; }
}

/* ---------- Gepäck: Farbe über currentColor, damit bei Erkennung ALLES mitwechselt ---------- */
/* Gepäck und Hunde: gleiche Unschärfe UND Deckkraft wie die Figurenkörper,
   die durch ihren Verlauf nach unten hin leichter werden */
/* Vorgemischtes Grau-Blau (Weiß 58 % über Bühnen-Blau) statt Deckkraft —
   Gepäck bleibt deckend und scheint hinter Figuren nicht mehr durch.
   Bei Erkennung wechselt currentColor unverändert auf Gelb. */
.case, .duffel, .pack, .brief, .bag--held {
  color: #989DA8;
  filter: blur(var(--pblur, 1.2px));
}

/* Rollkoffer: Korpus mit Naht, Teleskopgriff, zwei Rollen */
.case {
  position: absolute;
  width: 18px; height: 24px;
  border-radius: 4px;
  background:
    linear-gradient(rgba(12, 28, 62, .32), rgba(12, 28, 62, .32)) 0 8px / 100% 1.5px no-repeat,
    currentColor;
}
.case::before {                      /* Teleskopgriff */
  content: "";
  position: absolute;
  left: 50%; translate: -50% 0; top: -10px;
  width: 10px; height: 10px;
  border: 2px solid currentColor;
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
}
.case::after {                       /* zwei Rollen, skalieren mit der Breite */
  content: "";
  position: absolute;
  left: 2px; right: 2px; bottom: -2px;
  height: 4px;
  background:
    radial-gradient(circle 2px at 2px 2px, currentColor 98%, transparent 100%) left center / 50% 100% no-repeat,
    radial-gradient(circle 2px at calc(100% - 2px) 2px, currentColor 98%, transparent 100%) right center / 50% 100% no-repeat;
}
/* gezogen links: Griff kippt zur Person, Rollen stehen außen */
.person .case--pulled {
  left: calc(var(--d) * -0.9); bottom: 1px; top: auto;
  width: 16px; height: 20px;
  rotate: 21deg;
  transform-origin: 0% 100%;
}
.person .case--pulled-r {
  left: auto; right: calc(var(--d) * -0.9);
  rotate: -21deg;
  transform-origin: 100% 100%;
}
.person .case--stand {
  left: calc(var(--d) * 0.95); bottom: 1px; top: auto;
  width: 16px; height: 20px;
}

/* Reisetasche */
.duffel {
  position: absolute;
  left: calc(var(--d) * 0.8); bottom: calc(var(--d) * 0.75); top: auto;
  width: 20px; height: 10px;
  border-radius: 6px;
  background: currentColor;
}
.duffel::before {
  content: "";
  position: absolute;
  left: 6px; top: -6px;
  width: 10px; height: 6px;
  border: 1.6px solid currentColor;
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
}

/* Rucksack */
.pack {
  position: absolute;
  left: calc(var(--d) * -0.5); top: calc(var(--d) * 1.15);
  width: 14px; height: 18px;
  border-radius: 6px 6px 4px 4px;
  background: currentColor;
}
.pack::before {
  content: "";
  position: absolute;
  left: 50%; translate: -50% 0; top: -4px;
  width: 8px; height: 6px;
  border: 1.6px solid currentColor;
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
}

/* Aktenkoffer */
.brief {
  position: absolute;
  left: calc(var(--d) * 0.82); bottom: calc(var(--d) * 0.7); top: auto;
  width: 18px; height: 12px;
  border-radius: 2px;
  background:
    linear-gradient(rgba(12, 28, 62, .3), rgba(12, 28, 62, .3)) 0 6px / 100% 1.2px no-repeat,
    currentColor;
}
.brief::before {
  content: "";
  position: absolute;
  left: 6px; top: -4px;
  width: 8px; height: 6px;
  border: 1.6px solid currentColor;
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
}

/* Handtasche */
.bag--held {
  position: absolute;
  left: calc(var(--d) * 0.82); bottom: calc(var(--d) * 0.8); top: auto;
  width: 14px; height: 12px;
  border-radius: 2px 2px 4px 4px;
  background: currentColor;
}
.bag--held::before {
  content: "";
  position: absolute;
  left: 3.5px; top: -6px;
  width: 8px; height: 8px;
  border: 1.6px solid currentColor;
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
}

/* ---------- Hund ---------- */
.dog {
  position: absolute;
  width: 22px; height: 10px;
  border-radius: 6px 6px 4px 4px;
  background: currentColor;
  color: #9197A2;   /* Weiß 55 % über Bühnen-Blau, vorgemischt = deckend */
  filter: blur(var(--pblur, 1.2px));
}
.dog__head {
  position: absolute;
  right: -6px; top: -8px;
  width: 8px; height: 8px;
  border-radius: 50% 50% 45% 45%;
  background: currentColor;
}
.dog__head::before {            /* Schnauze */
  content: "";
  position: absolute;
  right: -3.5px; top: 3.5px;
  width: 6px; height: 3.5px;
  border-radius: 2px;
  background: currentColor;
}
.dog__head::after {             /* Ohr */
  content: "";
  position: absolute;
  left: 0.5px; top: -2px;
  width: 3.5px; height: 6px;
  border-radius: 2px 2px 1px 1px;
  background: currentColor;
  rotate: -12deg;
}
.dog__tail {
  position: absolute;
  left: -6px; top: -4px;
  width: 2.6px; height: 8px;
  border-radius: 2px;
  background: currentColor;
  transform-origin: 50% 100%;
  animation: tail-wag .42s ease-in-out infinite alternate;
}
@keyframes tail-wag {
  from { rotate: 18deg; }
  to { rotate: 54deg; }
}
/* Beine: nth-child, weil Kopf und Rute als Geschwister mitzählen; Positionen in %, damit sie mitskalieren */
.dog__leg {
  position: absolute;
  bottom: -4px;
  width: 2.2px; height: 6px;
  border-radius: 0 0 1px 1px;
  background: currentColor;
  transform-origin: 50% 0;
}
.dog__leg:nth-child(3) { left: 13%; }   /* Hinterbeine */
.dog__leg:nth-child(4) { left: 27%; }
.dog__leg:nth-child(5) { left: 63%; }   /* Vorderbeine */
.dog__leg:nth-child(6) { left: 78%; }
@keyframes trot {
  from { rotate: -18deg; }
  to { rotate: 18deg; }
}
.hero .dog--idle { animation: none; }   /* Hunde schweben nicht — nur Rute und Beine bewegen sich */
.dog--flip { scale: -1 1; }
.dog--sm { width: 18px; height: 8px; }
.dog--sm .dog__head { width: 6.5px; height: 6.5px; right: -6px; top: -5.5px; }
/* in the walker's hand until the drop */
/* der Täter zieht den Koffer hinter sich her */
.scene__walker .case--carried {
  left: calc(var(--d, 28px) * -0.9); bottom: 1px; top: auto;
  width: 16px; height: 20px;
  rotate: 21deg;
  transform-origin: 0% 100%;
  animation: bag-carried 40s linear infinite;
}
@keyframes bag-carried {
  0%, 89% { opacity: 1; }
  90%, 100% { opacity: 0; }
}
/* left behind at the drop point */
.scene__bagdrop {
  left: 1006px; top: 360px;
  width: 18px; height: 24px;
  opacity: 0;
  animation: bag-drop 40s linear infinite;
}
@keyframes bag-drop {
  0%, 76% { opacity: 0; color: var(--white); filter: blur(.3px); }
  76.8% { opacity: 1; color: var(--white); filter: blur(.3px); }
  77.8% { color: var(--white); filter: blur(.3px); }
  78.5% { color: var(--yellow); filter: blur(0px); opacity: 1; }
  85.2% { opacity: 1; color: var(--yellow); filter: blur(0px); }
  86.8%, 100% { opacity: 0; filter: blur(0px); }
}
.scene__bagdrop .ping {
  content: "";
  position: absolute;
  inset: -14px -10px -8px -10px;
  border: 2px solid var(--yellow);
  border-radius: 10px;
  opacity: 0;
  animation: bag-ping 40s linear infinite;
}
@keyframes bag-ping {
  0%, 78% { opacity: 0; transform: scale(1.6); }
  79% { opacity: 1; transform: scale(1); }
  80.8% { opacity: .4; transform: scale(1.3); }
  82.5% { opacity: 1; transform: scale(1); }
  84.5% { opacity: 1; }
  86.5%, 100% { opacity: 0; }
}
.scene__ret--bag {
  left: 976px; top: 330px;
  width: 80px; height: 74px;
  animation: ret-bag 40s ease-in-out infinite;
}
@keyframes ret-bag {
  0%, 77.8% { opacity: 0; transform: scale(1.5); }
  79%     { opacity: 1; transform: scale(1); }
  80.8%   { transform: scale(1.08); }
  82.5%   { transform: scale(1); }
  85.2%   { opacity: 1; }
  86.8%, 100% { opacity: 0; }
}

@keyframes cam-blink {
  from { background: var(--blue-5); }
  to { background: var(--yellow); }
}

/* ---------- Typography helpers ---------- */
.h3 { font-size: 24px; font-weight: 800; line-height: 1.3; }
.section-title .sub { line-height: 1.5; }


/* ---------- Utility ---------- */
.center { text-align: center; }
.stack-40 { display: grid; gap: var(--s-5); justify-items: center; }
.mt-24 { margin-top: var(--s-3); }
.mt-40 { margin-top: var(--s-5); }
.mt-64 { margin-top: var(--s-8); }
.mt-80 { margin-top: var(--s-10); }
[hidden] { display: none !important; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.mt-48 { margin-top: var(--s-6); }
.mt-96 { margin-top: var(--s-12); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .reveal { opacity: 1; translate: 0 0; }
  .scene { display: none; }
}

/* ---------- Sprachumschalter: aktive Sprache klar erkennbar ---------- */
/* Sprachumschalter: gleiche Schrift und Höhe wie die Menüpunkte, klare
   Trennlinie, aktive Sprache fett + gelb unterstrichen. Die inaktive Sprache
   bleibt voll deckend — nur das Gewicht unterscheidet sie. */
.nav__lang { margin-left: var(--s-1); }
.nav__lang-inner { display: inline-flex; align-items: center; gap: 12px; }
.nav__lang b,
.nav__lang a {
  font-size: var(--fs-body);
  font-weight: 400;
  letter-spacing: var(--ls-wide);
  color: var(--white);
  padding: 4px 0;
}
.nav__lang b,
.nav__lang [data-sprache][aria-current] {
  font-weight: 800;
  box-shadow: 0 2px 0 0 var(--yellow);   /* Unterstrich zeigt die aktive Sprache */
}
.nav__lang-sep {
  width: 1px;
  height: 16px;
  background: rgba(255, 255, 255, .35);
}
.nav__lang a { transition: color .15s ease; }
.nav__lang a:not([aria-current]):hover,
.nav__lang a:not([aria-current]):focus-visible { color: var(--blue-05); }
.nav__lang a::before { display: none; }  /* kein Hover-Unterstrich wie bei Menüpunkten */
.nav--dark .nav__lang b { color: var(--black); }

/* ==========================================================================
   Cookie-Hinweis
   ========================================================================== */
.cookie {
  position: fixed;
  /* Volle Fensterbreite, bündig am unteren Rand — bewusst NICHT am
     80-px-Raster; nur der Inhalt bekommt den Seitenabstand als Polster. */
  left: 0; right: 0; bottom: 0;
  z-index: 200;
  padding: var(--s-3) var(--page-margin);
  /* Flache Leiste statt Kasten: so verdeckt der Hinweis den Hero-Knopf nicht.
     Text links, Schaltflächen rechts. */
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: var(--s-4);
  row-gap: var(--s-1);
  border-radius: 0;
  background: linear-gradient(160deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, .06)), var(--blue-5);
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, .34);
  box-shadow: 0 -12px 40px rgba(0, 0, 0, .35);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  color: var(--white);
  translate: 0 0;
  transition: translate .4s cubic-bezier(.2, .7, .3, 1), opacity .4s ease;
}
.cookie > h2 { grid-column: 1; margin: 0; }
.cookie > p { grid-column: 1; margin: 0; }
.cookie .cookie__actions { grid-column: 2; grid-row: 1 / span 2; }
.cookie[hidden] { display: none; }
.cookie--leaving { translate: 0 24px; opacity: 0; }
.cookie h2 {
  font-size: var(--fs-body);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
}
.cookie p { line-height: 1.5; }
.cookie a { text-decoration: underline; text-underline-offset: 2px; }
.cookie a:hover { color: var(--blue-05); }
.cookie__actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.cookie .cta { padding: 12px 24px; }

/* ==========================================================================
   404
   ========================================================================== */
.notfound {
  min-height: 100vh;
  display: grid;
  place-content: center;
  text-align: center;
  gap: var(--s-4);
  background: var(--grad-hero);
  color: var(--white);
  padding: var(--s-10);
}
.notfound__code {
  font-size: 160px;
  font-weight: 900;
  line-height: .9;
  letter-spacing: var(--ls-wide);
  color: rgba(255, 255, 255, .16);
}
.notfound h1 { font-size: var(--fs-h2); font-weight: 800; line-height: 1.25; }
.notfound p { line-height: 1.5; max-width: var(--sp5); margin-inline: auto; }
.notfound__actions { display: flex; gap: var(--s-2); justify-content: center; flex-wrap: wrap; margin-top: var(--s-2); }

/* Presse-Karten ohne Bild: typografischer Platzhalter im Markenlook
   (fremde Artikel-Screenshots wären urheberrechtlich geschützt) */
.press-card__img--text {
  display: grid;
  place-items: center;
  padding: var(--s-3);
  background: var(--grad-card);
}
.press-card__img--text::after { display: none; }
.press-card__img--text span {
  font-size: 18px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-align: center;
  color: rgba(255, 255, 255, .82);
}

/* ==========================================================================
   Formular-Zustände: Validierung, Senden, Rückmeldung
   ========================================================================== */
/* Fehlermeldung sitzt auf der Label-Zeile und ist absolut positioniert —
   dadurch verschiebt sich beim Einblenden kein einziges Feld. */
.field { position: relative; }
.field__error {
  display: none;
  position: absolute;
  top: 0; right: 0;
  max-width: 68%;
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--error);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.field--invalid .field__error { display: block; }
.field--invalid input,
.field--invalid textarea,
.field--invalid select { border-color: var(--error); }
.panel--glass .field--invalid input,
.panel--glass .field--invalid textarea { border-color: var(--error-hell); }
.panel--glass .field__error { color: var(--error-hell); }

/* Einwilligung und Newsletter: Kästchen neben Fließtext, nicht im Label-Stil.
   Der Platz für die Fehlermeldung ist dauerhaft reserviert (16 px). */
.field--consent { padding-bottom: var(--s-3); }
/* Die Einwilligung ist eine eigene Gruppe, kein weiteres Auswahlfeld */
.field:not(.field--consent) + .field--consent { margin-top: var(--s-1); }
.field--consent .field__error {
  top: auto; bottom: 0;
  left: 0; right: auto;
  max-width: 100%;
}
.field .check {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: var(--s-1);
  align-items: start;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: 0.01em;
  cursor: pointer;
}
.field .check input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 4px 0 0;
  padding: 0;
  border-radius: 4px;
  accent-color: var(--blue-1);
  cursor: pointer;
}
.field .check a { color: inherit; text-underline-offset: 2px; }
.field--invalid .check { color: var(--error); }
.panel--glass .field--invalid .check { color: var(--error-hell); }
.field--invalid .check input[type="checkbox"] { outline: 2px solid var(--error); outline-offset: 2px; }

/* Ladezustand des Absende-Buttons */
.cta[data-busy] { pointer-events: none; opacity: .72; }
.cta[data-busy]::after {
  content: "";
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { rotate: 360deg; } }

/* Rückmeldung nach dem Absenden */
.form-status {
  display: none;
  gap: var(--s-2);
  align-items: flex-start;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-tile);
  line-height: 1.5;
}
.form-status[data-state] { display: flex; }
.form-status[data-state="ok"] {
  background: rgba(46, 125, 80, .12);
  border: 1px solid rgba(46, 125, 80, .5);
  color: #1E5C2E;
}
.form-status[data-state="error"] {
  background: rgba(196, 69, 58, .1);
  border: 1px solid rgba(196, 69, 58, .5);
  color: #A5352B;
}
.panel--glass .form-status[data-state="ok"] { background: rgba(255,255,255,.14); border-color: rgba(140, 220, 160, .6); color: #BFE9CB; }
.panel--glass .form-status[data-state="error"] { background: rgba(255,255,255,.14); border-color: rgba(240, 133, 122, .6); color: #F3AEA6; }

/* ==========================================================================
   Sprung zum Inhalt — nur sichtbar, wenn er den Fokus hat
   ========================================================================== */
.skip-link {
  position: absolute;
  left: var(--s-2); top: -100px;
  z-index: 1000;
  padding: var(--s-1) var(--s-2);
  background: var(--yellow);
  color: var(--blue-5);
  font-size: var(--fs-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  border-radius: var(--r-tile);
  transition: top .15s ease;
}
.skip-link:focus { top: var(--s-2); }
main:focus { outline: none; }

/* Fließtext bekommt immer eine lesbare Zeilenhöhe, auch wenn ein neuer Block
   vergisst, sie zu setzen. Bewusst nur diese Elemente: p, Tabellenzellen und
   Beschriftungen führen mehrzeiligen Text, Badges und Kennzahlen nicht. */
p, td, th, dd, blockquote, figcaption { line-height: 1.5; }

/* ==========================================================================
   Zeilenumbrüche in Überschriften
   Ohne Hilfe bricht der Browser gierig um: er füllt jede Zeile bis zum Rand
   und lässt am Ende ein einzelnes Wort stehen — „AI WATCH IN BAHNEN UND" /
   „BUSSEN". text-wrap: balance verteilt die Wörter gleichmäßig auf alle
   Zeilen, sodass keine Zeile allein steht. Browser ohne Unterstützung
   ignorieren die Regel und brechen wie bisher um.
   ========================================================================== */
h1, h2, h3,
.h2, .hero__title, .page-hero__inner h1,
.section-title h2,
.detail-card h3, .navy-card h3, .tile__label,
.glass-card h3, .feature h3, .type-row h3 {
  text-wrap: balance;
}

/* .principle h3 bleibt bewusst draußen. Die drei Überschriften der Sektion
   „Was alle Lösungen verbindet" stehen in Figma einzeilig und tragen dafür
   white-space: nowrap. Beide Eigenschaften steuern denselben Teilwert
   (text-wrap-mode) — ein balance an dieser Stelle hebt das nowrap auf und
   „Nachrüsten statt austauschen" bricht auf zwei Zeilen um. */

/* Fließtext bekommt "pretty" statt "balance": das verhindert nur die
   Schusterjunge-Zeile am Absatzende, ohne die Zeilenlängen anzugleichen —
   bei langen Absätzen wäre balance zu teuer und sähe unruhig aus. */
p, .body-copy, .lead, .sub {
  text-wrap: pretty;
}

/* ==========================================================================
   Bühnen-Requisiten der Unterseiten-Heroes (.ph-*)
   Jede Unterseite bekommt eine eigene kleine Szene statt der immergleichen
   drei Figuren. Die Requisiten sind bewusst zurückhaltend (aria-hidden,
   pointer-events: none) und nutzen die globalen Figuren/Gepäck-Bausteine.
   ========================================================================== */
.page-hero [aria-hidden] { pointer-events: none; }

/* Haltestellen: Mast mit gelbem H-Schild */
.page-hero .ph-mast {
  position: absolute;
  width: 3px; height: 112px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .35);
}
.page-hero .ph-mast::before {          /* Schild sitzt oben am Mast */
  content: "H";
  position: absolute;
  top: -8px; left: 50%;
  translate: -50% 0;
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--yellow);
  color: var(--blue-5);
  font-size: 13px;
  font-weight: 800;
  opacity: .9;
}

/* Bahnen: angedeutetes Gleis am Bühnenboden */

/* Baustellen: schraffierte Absperrbake */
.page-hero .ph-bake {
  position: absolute;
  width: 10px; height: 56px;
  border-radius: 3px;
  background: repeating-linear-gradient(-45deg,
    var(--yellow) 0 8px, rgba(255, 255, 255, .75) 8px 16px);
  opacity: .65;
}
.page-hero .ph-bake::before {          /* Standfuß */
  content: "";
  position: absolute;
  left: -7px; right: -7px; bottom: -4px;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .3);
}

/* Individuelle Orte: Erkennungsrahmen steht ruhig um eine Figur */
.page-hero .scene__ret { opacity: .85; }
.page-hero .scene__ret .det-label { opacity: 1; }

/* Kamera-Dome wie im Start-Hero, für Kontext an Deckenkante */

/* ==========================================================================
   KI-Chat (Kontakt-Hero) — Attrappe: zeigt, wie Frage und Antwort aussehen
   ========================================================================== */
.ki-chat {
  width: min(640px, 100%);
  display: grid;
  gap: var(--s-2);
  justify-self: center;
}
/* Festes Chat-Fenster: Höhe steht, Blasen stapeln von unten, Älteres
   scrollt — Breite und Höhe des Panels ändern sich beim Antworten NIE. */
.ki-chat__verlauf {
  display: grid;
  gap: var(--s-1);
  text-align: left;
  height: 280px;
  overflow-y: auto;
  align-content: end;
  padding-right: 4px;             /* Luft für die Scrollleiste */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .3) transparent;
}
.chat-bubble {
  max-width: 85%;
  padding: 12px 20px;
  border-radius: 20px;
  line-height: 1.5;
  font-size: var(--fs-body);
  letter-spacing: var(--ls-wide);
}
.chat-bubble--frage {
  justify-self: end;
  background: var(--white);
  color: var(--text-dark);
  border-bottom-right-radius: 4px;
}
.chat-bubble--antwort {
  justify-self: start;
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .25);
  color: var(--white);
  border-bottom-left-radius: 4px;
}
/* drei pulsierende Punkte, solange die Antwort "tippt" */
.chat-bubble--tippt { display: inline-flex; gap: 4px; padding-block: 16px; }
.chat-bubble--tippt i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .7);
  animation: chat-punkt 1s ease-in-out infinite;
}
.chat-bubble--tippt i:nth-child(2) { animation-delay: .16s; }
.chat-bubble--tippt i:nth-child(3) { animation-delay: .32s; }
@keyframes chat-punkt { 50% { opacity: .25; translate: 0 -2px; } }
.ki-chat__form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s-1);
  align-items: center;
}
.ki-chat__form input {
  min-width: 0;
  padding: 16px 24px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .40);
  background: rgba(255, 255, 255, .10);
  color: var(--white);
  font: inherit;
  letter-spacing: inherit;
}
.ki-chat__form input::placeholder { color: rgba(255, 255, 255, .55); }
.ki-chat__form input:focus-visible { outline-offset: 2px; }
.ki-chat__hinweis { color: rgba(255, 255, 255, .55); text-align: center; }

/* ==========================================================================
   Video-Sektion (Startseite) — Standbild, Video lädt erst auf Klick
   ========================================================================== */
/* Schmaler als die volle Inhaltsbreite (8 Spalten, mittig), Seitenverhältnis
   bleibt 16:9 — so sind Titel, Untertitel UND Video gemeinsam im Blick. */
.video-buehne {
  position: relative;
  max-width: var(--sp8);
  margin-inline: auto;
  /* 4:3 wie das Demovideo selbst (1440 × 1080). Vorher stand hier 16/9 und
     object-fit:cover darunter — das hätte dem neuen Film oben und unten je
     ein Achtel abgeschnitten und damit die Überschrift und den Hinweis
     "alle Szenen gestellt" aus dem Bild genommen. */
  aspect-ratio: 4 / 3;
  border-radius: var(--r-card);
  overflow: hidden;
  /* Das Standbild ist bis auf die Videowand durchsichtig, der Grund kommt
     von hier. Gleiches Blau wie section--dark: auf der Startseite geht die
     Bühne damit nahtlos in den Abschnitt über, auf hellem Grund steht sie
     als blaue Karte. */
  background: var(--blue-4);
}
.video-buehne img,
.video-buehne video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Schlichter Abspielknopf: weiße Scheibe, dunkles Dreieck — kein Verlauf
   über dem Standbild, keine Glas-Effekte. Klickfläche bleibt die ganze Bühne. */
.video-buehne__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  width: 100%;
  cursor: pointer;
}
/* Startknopf: weißer Kreis, zu 70 % durchsichtig, das Dreieck ist
   ausgestanzt. Durch das Dreieck sieht man das Standbild ungetrübt, die
   Maske schneidet auch Unschärfe und Schatten dort weg. Dieselbe Maske
   trägt das Play-Zeichen der Pressekarten. */
.video-buehne__play-kreis {
  display: grid;
  place-items: center;
  width: 64px; height: 64px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .3);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath fill-rule='evenodd' d='M32 0a32 32 0 1 1 0 64a32 32 0 1 1 0-64zM27 22v20l17-10z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath fill-rule='evenodd' d='M32 0a32 32 0 1 1 0 64a32 32 0 1 1 0-64zM27 22v20l17-10z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1), background-color .34s ease;
}
.video-buehne__play:hover .video-buehne__play-kreis,
.video-buehne__play:focus-visible .video-buehne__play-kreis { transform: scale(1.08); background-color: rgba(255, 255, 255, .45); }
/* Das weiße Dreieck im Markup bleibt für alte Fassungen, zu sehen ist es nicht mehr */
.video-buehne__play-kreis svg { visibility: hidden; }

/* Startseite: Auf großen Bildschirmen stehen Überschrift und Text links
   neben dem Video, oben bündig. Darunter wie gehabt übereinander. */
/* Gleicher Verlauf wie das Standbild und der Anfang des Videos, damit man
   die Fläche des Videos erkennt */
.video-quer .video-buehne { background: linear-gradient(135deg, #010822 0%, #021231 50%, #071D45 100%); }
@media (min-width: 1025px) {
  .video-quer {
    display: grid;
    grid-template-columns: var(--sp5) 1fr;
    gap: var(--gutter);
    align-items: start;
  }
  .video-quer .video-buehne { margin: 0; max-width: none; }
}

/* Nur Einzeldatei (galvorn.html): Die Zwillings-Startseite der jeweils
   anderen Sprache bleibt gerendert, aber unsichtbar — ihre Animationen
   laufen weiter, damit der Sprachwechsel die Hero-Szene nicht neu startet. */
.page--lautlos {
  visibility: hidden;
  position: absolute;
  inset: 0 auto auto 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  pointer-events: none;
}

/* ==========================================================================
   Danke-Zustand nach dem Absenden — ersetzt das Formular ([data-danke])
   ========================================================================== */
/* Pilotprogramm: Leistungsumfang neben dem Formular. Im Markup steht er
   zuerst (schmal: über dem Formular), breit rückt er per order nach rechts. */
.angebot { display: grid; grid-template-columns: 7fr 5fr; gap: var(--s-8); align-items: start; }
.angebot > .umfang { order: 2; }
.umfang { display: grid; gap: var(--s-3); }
.umfang h3 { font-size: 24px; font-weight: 800; }
.umfang ul { list-style: none; margin: 0; padding: 0; border-top: 1px solid rgba(255, 255, 255, .22); }
.umfang li {
  display: flex; align-items: center; gap: var(--s-2);
  padding-block: 14px;
  border-bottom: 1px solid rgba(255, 255, 255, .22);
  font-weight: 700;
}
.umfang li svg { flex-shrink: 0; color: var(--yellow); }
.umfang__hinweis { font-size: 14px; opacity: .75; }

.form-danke {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: var(--s-2);
  padding-block: var(--s-6);
}
.form-danke__icon {
  display: grid;
  place-items: center;
  width: 64px; height: 64px;
  border-radius: 50%;
  background: rgba(226, 178, 43, .16);
  color: var(--yellow-2);
}
.form-danke h3 {
  font-size: 24px;
  font-weight: 800;
}
.form-danke p {
  max-width: 44ch;
  opacity: .75;
}

/* ==========================================================================
   Callout — helles Panel mit Icon (z. B. „Die Kontrolle bleibt bei Ihnen."
   unter „Was wir nicht wollen"). Hell, damit auf dunklen wie hellen
   Sektionen kein zweiter Blauton entsteht; Icon gegen die Textwüste.
   --quer = volle Breite, Kopf links, Text rechts.
   ========================================================================== */
.callout {
  display: grid;
  gap: var(--s-2);
  align-content: start;
  padding: var(--s-5);
  background: var(--grey-100);
  color: var(--text-dark);
  border-radius: var(--r-card);
}
.callout__icon {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  color: var(--yellow-2);
}
.callout h3 {
  font-size: 24px;
  font-weight: 800;
  line-height: 1.3;
}
.callout p { line-height: 1.5; }
.callout__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  margin-top: var(--s-1);
  font-weight: 700;
  color: var(--yellow-2);
}
.callout__link:hover,
.callout__link:focus-visible { text-decoration: underline; text-underline-offset: 4px; }
.callout--quer {
  grid-template-columns: var(--sp4) 1fr;
  gap: var(--gutter);
  align-items: start;
}
.callout__kopf { display: grid; gap: var(--s-2); justify-items: start; }
.callout__inhalt { display: grid; gap: var(--s-2); justify-items: start; }
.callout--quer .callout__inhalt p { max-width: var(--sp6); }

/* ==========================================================================
   BREAKPOINTS — Tablet und Mobil
   ==========================================================================
   Der Entwurf oben ist auf 1440 px gesetzt. Alles ab hier sind reine
   Übersteuerungen nach unten (max-width). Oberhalb von 1400 px greift
   nichts davon — die Fassung für große Bildschirme bleibt unverändert.

   Stufen:
     1400  Seitenrand schrumpft, Raster bleibt zwölfspaltig
     1180  vierspaltige Karten werden zweispaltig, Schrift eine Stufe kleiner
     1024  MENÜKNOPF (dieselbe Grenze steht in main.js), Spalten paarweise
      760  ein Strang: alles untereinander, Telefon-Typografie
      480  kleine Telefone: Knöpfe dürfen umbrechen, letzte Feinheiten

   Die --sp*-Tokens (Spaltenbreiten) bleiben absichtlich stehen: sie werden
   fast überall als max-width benutzt und sind damit unterhalb ihrer Größe
   von selbst wirkungslos. Angefasst wird nur, was feste Breiten oder feste
   Spaltenzahlen hat — dort entsteht der Überlauf.
   ========================================================================== */

/* Touch-Geräte kennen kein Überfahren. Die Startseiten-Kacheln zeigen ihr
   Ortssymbol deshalb gleich etwas deutlicher, und ein Antippen gibt sofort
   eine sichtbare Rückmeldung (heller Grund, Symbol voll da). */
@media (hover: none) {
  .tile__icon { opacity: .4; }
  .tile:active { transform: scale(.98); background: var(--blue-3); }
  .tile:active .tile__icon { opacity: 1; }
  .navy-card__icon { opacity: .45; }
  .navy-card:active { transform: scale(.98); background: #102448; }
  .cta:active { transform: scale(.97); }
}

/* Der Menüknopf steht in jeder Seite im Markup, ist aber nur bis
   1280 px sichtbar. Auf großen Bildschirmen existiert er für Auge und
   Screenreader nicht — display:none nimmt ihn auch aus der Tab-Reihenfolge. */
.nav__burger { display: none; }
.nav__mobil-cta { display: none; }

/* ---------- Ab hier passt der 80-px-Rand nicht mehr ---------- */
@media (max-width: 1400px) {
  :root { --page-margin: 48px; }
  /* Menüzeile: sechs Hauptpunkte passen hier nur mit 32 px Abstand */
  .nav__links { gap: var(--s-4); }
}

@media (max-width: 1180px) {
  :root {
    --page-margin: 40px;
    --fs-display: 52px;
    --fs-stat: 56px;
    --fs-h2: 34px;
  }
  .section { padding-block: var(--s-10); }
  .page-hero .display { font-size: 44px; }

  /* Vierspaltige Kartenbänder werden zweispaltig — die Trennlinien wandern
     mit, sonst stünde in jeder Zeile eine Linie an der falschen Stelle. */
  .glass-grid, .detail-cards { grid-template-columns: repeat(2, 1fr); }
  .glass-grid.glass-grid .glass-card,
  .detail-cards.detail-cards .detail-card { border-left: 0; }
  .glass-grid.glass-grid .glass-card:not(:nth-child(2n + 1)) { border-left: 1px solid rgba(255, 255, 255, .35); }
  .detail-cards.detail-cards .detail-card:not(:nth-child(2n + 1)) { border-left: 1px solid rgba(12, 28, 62, .18); }

  /* Die Ziffern 01/02/03 hängen an Figma-Koordinaten; hier eine Stufe
     kleiner, damit sie nicht in den Text der Nachbarspalte ragen. */
  .principles__num { font-size: 148px; }
  .principle h3 { font-size: 44px; }
  .principle--2 h3 { width: auto; }
}

/* ==========================================================================
   1280 — die Menüzeile passt nicht mehr in eine Reihe
   Mit „Verantwortung“ als eigenem Hauptpunkt braucht die Zeile
   rund 1000 px neben dem Logo. Darunter klappt das Menü hinter den Knopf.
   Die Grenze steht auch in main.js (MENUE_GRENZE).
   ========================================================================== */
@media (max-width: 1280px) {
  /* ---------- Menüknopf statt Menüzeile ---------- */
  /* Die Leiste bricht um: Logo und Knopf bleiben oben, die Punkte klappen
     als volle Zeile darunter auf. Gesteuert über [data-menu-open] auf der
     Kopfzeile — dasselbe Attribut setzt main.js. */
  .nav { flex-wrap: wrap; gap: var(--s-2); }
  .nav__burger {
    display: grid;
    place-items: center;
    width: 44px; height: 44px;      /* volle Antippfläche, auch wenn das Zeichen kleiner ist */
    margin-right: calc(var(--s-1) * -1);
    color: var(--white);
    background: none;
    border: 0;
    border-radius: var(--r-tile);
  }
  .nav--dark .nav__burger { color: var(--black); }
  .nav__burger-striche {
    display: grid;
    gap: 5px;
    width: 22px;
  }
  .nav__burger-striche i {
    display: block;
    height: 2px;
    border-radius: 1px;
    background: currentColor;
    transition: transform .24s cubic-bezier(.2, .7, .3, 1), opacity .18s ease;
  }
  /* Offen: aus den drei Strichen wird ein Kreuz */
  .site-header[data-menu-open] .nav__burger-striche i:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .site-header[data-menu-open] .nav__burger-striche i:nth-child(2) { opacity: 0; }
  .site-header[data-menu-open] .nav__burger-striche i:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* Solange das Menü offen ist, braucht die Leiste ihren eigenen Grund —
     sonst stünden die Punkte auf dem Hero-Bild. */
  .site-header[data-menu-open] {
    background-color: rgba(7, 14, 32, .97);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    backdrop-filter: blur(12px) saturate(140%);
  }

  .nav__links {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    /* Ist die Liste länger als der Bildschirm, scrollt sie in sich */
    max-height: calc(100vh - 72px);
    overflow-y: auto;
    padding-bottom: var(--s-2);
  }
  .site-header[data-menu-open] .nav__links {
    display: flex;
    animation: menue-auf .22s cubic-bezier(.2, .7, .3, 1);
  }
  .nav__links > li { border-top: 1px solid rgba(255, 255, 255, .1); }
  /* Größere Schrift und Antippfläche als in der Desktop-Leiste */
  .nav__links a,
  .nav__links .nav__droptoggle {
    display: block;
    width: 100%;
    padding: 16px 0;
    text-align: left;
    font-size: 18px;
  }
  /* Aktive Seite: goldene Marke links statt nur fetter Schrift */
  .nav__links > li > a[aria-current="page"],
  .nav__links > li > .nav__droptoggle[aria-current="page"] {
    box-shadow: inset 3px 0 0 var(--yellow);
    padding-left: var(--s-2);
  }
  /* Knopf „Angebot anfordern“ unten im Menü */
  .nav__mobil-cta { display: block; border-top: 0 !important; padding-top: var(--s-3); }
  .nav__links .nav__mobil-cta .cta {
    display: flex;
    width: 100%;
    padding: 14px 24px;
    font-size: 16px;
    text-align: center;
    color: var(--black);
    justify-content: center;
    background: var(--white);
    font-weight: 600;
  }
  .nav__links .nav__mobil-cta .cta::before { display: none; }
  /* Die Kopfzeile ist fest — Einblende-Effekte vom Scrollen gehören nicht hinein */
  .site-header .reveal { opacity: 1; translate: none; }
  .nav__lang .nav__lang-inner a,
  .nav__lang .nav__lang-inner b { padding: 4px 0; font-size: 16px; display: inline-block; width: auto; }
  .nav__links .nav__dd-item { font-size: 16px; }
  /* Der Unterstrich der Zeile fährt sonst über die volle Breite */
  .nav__links a::before,
  .nav__links .nav__droptoggle::before { display: none; }
  /* Der Platzhalter für die fette Schrift hält im Block-Layout keine Breite
     mehr frei und würde nur eine leere Zeile erzeugen. */
  .nav__lbl { display: block; text-align: left; }
  .nav__lbl::after { content: none; }

  /* Das Untermenü klappt in der Liste auf statt darüber zu schweben */
  .nav__item--dropdown { position: static; }
  /* Muss so spezifisch sein wie die Block-Regel oben, sonst gewinnt dort das
     display:block und der Pfeil rutscht unter die Beschriftung. */
  .nav__links .nav__droptoggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .nav__links .nav__droptoggle .nav__lbl { flex: 1 1 auto; }
  /* Im Menü untereinander, Symbole eine Nummer kleiner. Zu ist hier
     wirklich weg (display), sonst bliebe die Lücke in der Liste stehen. */
  .nav__dropdown {
    position: static;
    translate: none;
    display: none;
    grid-template-columns: 1fr;
    gap: 2px;
    padding: 0 0 var(--s-2);
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    transform: none;
  }
  .nav__dropdown::before,
  .nav__dropdown::after { content: none; }
  .nav__item--dropdown[data-open] .nav__dropdown { display: grid; }
  .nav__links .nav__dd-item {
    display: flex;
    padding: 6px var(--s-1);
    white-space: normal;
  }
  .nav__dd-icon { width: 40px; height: 40px; border-radius: 10px; }
  .nav__dd-icon svg { width: 22px; height: 22px; }
  .nav__lang { margin-left: 0; padding-block: var(--s-2); border-top: 0 !important; }
  .nav__lang-inner {
    padding: 6px 14px;
    border: 1px solid rgba(255, 255, 255, .25);
    border-radius: var(--r-pill);
  }
  /* Bereiche-Untermenü: ab Tablet-Hochformat zweispaltig wie am Desktop */
  .nav__dropdown { gap: 4px var(--s-2); padding-bottom: var(--s-2); }
}
@media (max-width: 1280px) and (min-width: 481px) {
  .nav__item--dropdown[data-open] .nav__dropdown { grid-template-columns: 1fr 1fr; }
}
@keyframes menue-auf {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .site-header[data-menu-open] .nav__links { animation: none; }
}

/* ==========================================================================
   1024 — Tablet hochkant
   ========================================================================== */
@media (max-width: 1024px) {
  :root {
    --fs-display: 44px;
    --fs-stat: 48px;
    --fs-h2: 30px;
    --fs-lead: 20px;
  }
  .section { padding-block: var(--s-8); }
  /* Überschrift → Inhalt und Abstände in der Sektion: Tablet braucht nicht
     die Desktop-Luft, sonst wird jede Seite unnötig lang. */
  .section-title { gap: var(--s-2); }
  .section .mt-64 { margin-top: var(--s-5); }
  .section .mt-40, .section .mt-48 { margin-top: var(--s-4); }
  .feature-list { row-gap: var(--s-6); }


  /* ---------- Bühnen ---------- */
  /* Die Hero-Szene ist auf 1440 px Entwurfsbreite gezeichnet: der Zug ist
     fest 1720 px breit (seine Nasenform steckt in einem clip-path und lässt
     sich nicht umbauen), die Figuren stehen an Prozentmarken. Auf schmalen
     Geräten muss deshalb die ganze Bühne maßstäblich schrumpfen — sonst
     stünde nur ein Ausschnitt im Bild und der Zug wäre an beiden Enden
     abgeschnitten. Verkleinert wird über die eigenständige scale-Eigenschaft,
     nicht über transform: transform ist durch die Zoom-Animation belegt,
     beide wirken multiplikativ übereinander.

     scale schrumpft aber auch die Kastenbreite. Damit die Bühne trotzdem von
     Kante zu Kante läuft, wird der Kasten um den Kehrwert breiter gemacht und
     so verschoben, dass die verkleinerte Fassung wieder genau auf der
     Bildbreite liegt. Rechenweg mit Faktor f und dem x-Ursprung 61 %
     (transform-origin der hero-zoom, der auch für scale gilt):
       sichtbare Breite = Breite × f   =>  Breite = 100 % / f
       linke Kante des Kastens         =  −61 % × (100 % / f − 100 %)

     f = 100vw / 1440px hält den Maßstab des Entwurfs über die ganze Spanne:
     bei 1440 px wäre f = 1, bei 390 px ist die Bühne 27 % groß — und der Zug
     steht mit der Nase am rechten Rand, genau wie am Schreibtisch. Länge
     durch Länge zu teilen ist CSS Values 4; Browser ohne diese Rechnung
     behalten den festen Vorgabewert und bekommen damit eine brauchbare,
     ebenfalls randlose Näherung. */
  .hero__graphics {
    --buehne: .5;
    scale: var(--buehne);
    inset-inline: calc(-.61 * (100% / var(--buehne) - 100%)) auto;
    width: calc(100% / var(--buehne));
  }
  @supports (scale: calc(100vw / 1440px)) {
    .hero__graphics { --buehne: calc(100vw / 1440px); }
  }
  /* Rahmen und Beschriftungen der Erkennung sind Bedienoberfläche, keine
     Szenerie: sie müssen lesbar bleiben, auch wenn die Bühne auf ein Viertel
     schrumpft. Deshalb rechnen sie den Maßstab wieder heraus — die Zahlen
     sind die gewünschten Bildschirmgrößen in px. */
  .hero__graphics .det-label {
    font-size: calc(12px / var(--buehne));
    padding: calc(4px / var(--buehne)) calc(10px / var(--buehne));
    margin-bottom: calc(7px / var(--buehne));
    box-shadow: 0 calc(2px / var(--buehne)) calc(8px / var(--buehne)) rgba(7, 14, 32, .45);
  }
  .hero__graphics .scene__ret {
    --corner: calc(7px / var(--buehne));
    --thick: calc(1.6px / var(--buehne));
  }
  /* Der Rahmen im Zug ist bewusst kleiner als die auf dem Bahnsteig und
     erscheint nur während der Heranfahrt (hero-zoom, Faktor 1,7) — er braucht
     denselben Ausgleich, aber in seiner eigenen, kleineren Abmessung. */
  .hero__graphics .train .scene__ret--fight {
    --corner: calc(5px / var(--buehne));
    --thick: calc(1.1px / var(--buehne));
  }
  .hero__graphics .train .scene__ret--fight .det-label {
    font-size: calc(8px / var(--buehne));
    padding: calc(1.5px / var(--buehne)) calc(5px / var(--buehne));
    margin-bottom: calc(5px / var(--buehne));
  }
  /* Der Schleier deckt auf großen Bildschirmen nur die linken 71 % ab —
     rechts soll die Szene frei stehen, weil der Text dort nicht hinreicht.
     Im Hochformat läuft der Text über die volle Breite, also muss auch der
     Schleier über die volle Breite decken und früher einsetzen. Eine
     einzelne Maskenebene genügt dafür; das Verrechnen zweier Ebenen
     (mask-composite) entfällt damit von selbst. */
  .hero__veil {
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 26%, rgba(0, 0, 0, .78) 33%, #000 40%);
    mask-image: linear-gradient(180deg, transparent 0%, transparent 26%, rgba(0, 0, 0, .78) 33%, #000 40%);
  }
  /* Der Text beginnt dort, wo die Bühne endet — und die Bühne wächst linear
     mit der Bildbreite (siehe Faktor f oben). Ein vh-Wert wäre hier falsch:
     die Szene misst sich an der Breite, nicht an der Höhe des Geräts.
     150 px + 45 vw entspricht der Unterkante der hintersten Figurenreihe. */
  .hero__inner { padding-top: calc(150px + 45vw); }
  .hero__claim { margin-top: var(--s-5); }
  .hero .badges { margin-top: var(--s-4); gap: var(--s-2); }
  .tile { min-height: 136px; }
  /* Zweispaltig mit ungerader Anzahl: alle Karten gleich breit, die letzte
     steht mittig. Dafür vier Rasterspuren, jede Karte belegt zwei; die
     übrige rückt auf Spur 2–3. */
  .feature-list, .navy-grid, .detail-cards--3, .glass-grid--3 { grid-template-columns: repeat(4, 1fr); }
  .feature-list > *, .navy-grid > *, .detail-cards--3 > *, .glass-grid--3 > * { grid-column: span 2; }
  .feature-list > :last-child:nth-child(odd),
  .navy-grid > :last-child:nth-child(odd),
  .detail-cards--3 > :last-child:nth-child(odd),
  .glass-grid--3 > :last-child:nth-child(odd) { grid-column: 2 / span 2; }
  /* Die mittige Karte hat links keine Trennlinie (2n + 1) — dafür bekommt
     sie oben eine, damit sie nicht frei im Raum schwebt */
  .feature-list.feature-list > .feature:last-child:nth-child(odd):not(:first-child) {
    padding-inline: var(--s-3);
  }

  /* Größere Abschnitte innerhalb einer Sektion (z. B. „Teil der JAAI Group“
     unter „Wofür wir stehen“) behalten deutlichen Abstand */
  .section .mt-80, .section .mt-96 { margin-top: var(--s-8); }

  /* Feste 480 px reichen nicht mehr für Titel plus Untertitel (und auf der
     Kontaktseite für das Chat-Fenster). Ab hier wächst die Bühne mit. */
  .page-hero {
    height: auto;
    min-height: 400px;
    padding-top: 112px;
    padding-bottom: var(--s-6);
  }
  .page-hero .display { font-size: 38px; }

  /* ---------- Dreispaltiges wird zweispaltig ---------- */
  /* Feature-Listen, Navy-, Leistungs- und Glaskarten: vier Spuren, siehe
     „ungerade Anzahl“ weiter oben in diesem Block */
  .press-grid { grid-template-columns: repeat(2, 1fr); }
  /* Startseiten-Kacheln zu zweit: vier Spuren, die übrige Kachel mittig */
  .tile-grid { grid-template-columns: repeat(4, 1fr); }
  .tile-grid > :nth-child(4):nth-last-child(2) { grid-column: span 2; }
  .tile-grid > :last-child:nth-child(odd) { grid-column: 2 / span 2; }
  .feature-list.feature-list .feature { border-left: 0; }
  .feature-list.feature-list .feature:not(:nth-child(2n + 1)) { border-left: 1px solid rgba(255, 255, 255, .35); }
  .feature-list--light.feature-list--light .feature:not(:nth-child(2n + 1)) { border-left-color: rgba(12, 28, 62, .18); }
  /* Pilotprogramm: Umfang über dem Formular statt daneben */
  .angebot { grid-template-columns: 1fr; gap: var(--s-5); }
  .angebot > .umfang { order: 0; }
  /* Die Liste steht oben schon ausführlich — hier zweispaltig und knapp,
     damit das Formular nicht weit nach unten rutscht. */
  .umfang ul { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s-4); }
  .umfang li { padding-block: 12px; line-height: 1.25; }
  .field--row { align-items: end; }
  /* bündig: jetzt ist die linke Spalte 2n + 1 */
  .feature-list--buendig.feature-list--buendig .feature:nth-child(n) { padding-left: var(--s-4); }
  .feature-list--buendig.feature-list--buendig .feature:nth-child(2n + 1) { padding-left: 0; }

  /* ---------- Zweispaltiges wird einspaltig ---------- */
  .split, .contact-cols, .callout--quer, .termin { grid-template-columns: 1fr; }
  .termin { gap: var(--s-5); }
  /* Einspaltig gibt es keine zweite Spalte mehr — die Platzierung muss
     weg, sonst legt das Raster für grid-area 1/2 eine implizite an. */
  .contact-cols--formulare > :nth-child(1),
  .contact-cols--formulare > :nth-child(2),
  .contact-cols--formulare > :nth-child(3),
  .contact-cols--formulare > :nth-child(4) { grid-area: auto; align-self: start; }
  /* Raster- und Flex-Kinder haben min-width:auto und schrumpfen deshalb nie
     unter ihre Eigenbreite. Bei Eingabefeldern ist das die vom Browser
     gesetzte Standardbreite (input size=20, textarea cols=20) — die schob
     den Kasten auf schmalen Telefonen über den Rand hinaus. */
  .panel, .form-grid, .field,
  .field input, .field textarea, .field select { min-width: 0; }
  .type-row { grid-template-columns: 1fr; gap: var(--s-2); }
  .type-row p { max-width: none; justify-self: start; }

  /* ---------- Lange Dokumente: Randnavigation nach oben ---------- */
  .doc-layout { grid-template-columns: 1fr; }
  .doc-toc {
    grid-column: 1;
    position: static;
    /* Ein Inhaltsverzeichnis mit 25 Punkten würde die Seite sonst auf
       Armeslänge nach unten schieben — hier rollt es in sich. */
    max-height: 240px;
    padding-right: 0;
  }
  .doc-body { grid-column: 1; }
  /* Die Rechtstexte führen ausgeschriebene Adressen wie
     „https://admin.typeform.com/to/…". Ein Rasterfeld ist nie schmaler als
     das längste unteilbare Wort darin, und overflow-wrap:break-word ändert
     diese Mindestbreite ausdrücklich NICHT — es bricht nur beim Zeichnen.
     Erst min-width:0 gibt die Spalte frei; den Umbruch besorgt dann die
     Regel weiter unten. */
  .doc-toc, .doc-body { min-width: 0; }
  .doc-toc a, .prose a { overflow-wrap: break-word; }

  /* ---------- Tabellen bekommen eine eigene Rollfläche ---------- */
  /* Umbrechen macht eine Vergleichstabelle unlesbar; seitliches Rollen
     erhält den Zeilenbezug. */
  .compare { overflow-x: auto; }
  .compare table { min-width: 620px; }
    /* Zeitplan senkrecht: Balken wird zur Linie links, Phasen untereinander */
  .zeitplan { grid-template-columns: 1fr; row-gap: 0; }
  .zeitplan__phase {
    grid-template-columns: 8px 1fr;
    column-gap: var(--s-3);
    row-gap: 4px;
    grid-template-rows: auto auto 1fr;
    padding: 0 0 var(--s-3);
  }
  .zeitplan__phase:last-child { padding-bottom: 0; }
  .zeitplan__balken {
    grid-column: 1;
    grid-row: 1 / span 3;
    height: auto;
    min-height: calc(32px * var(--monate));
    margin: 0;
  }
  .zeitplan.reveal .zeitplan__balken { transform-origin: top; transform: scaleY(0); }
  .zeitplan p { max-width: none; }

  /* ---------- Fußzeile: Marke über die volle Breite ---------- */
  .site-footer__marke { grid-column: span 12; }
  .site-footer__spalte--bereiche,
  .site-footer__spalte--unternehmen,
  .site-footer__spalte--kontakt { grid-column: span 4; }

  .accordion { padding: var(--s-3) var(--s-4); }
  .statement-band p { font-size: 22px; }
  .ledger__row h3 { font-size: 26px; }
  .stars-deco { width: 380px; height: 380px; right: -80px; }
}

/* ---------- Figuren an den Rand (bis 1024 px) ----------
   Die Figuren der Bühnen stehen an Prozentmarken, die auf 1440 px Breite
   neben dem Text liegen. Schmaler läuft der Text über die volle Breite und
   die Figuren standen mitten darin. Hier rücken sie in zwei schmale Bahnen
   an den linken und rechten Rand (Höhe bleibt), der Text bekommt seitlich
   Platz. In Inhaltssektionen, wo der Text bis an den Rand läuft, entfallen
   sie ganz. */
@media (max-width: 1024px) {
  .page-hero__inner { padding-inline: 64px; }
  .page-hero > [aria-hidden] > .person,
  .closing-cta__deco > .person { --d: 16px !important; }
  .page-hero > [aria-hidden] > .person:nth-child(even),
  .closing-cta__deco > .person:nth-child(even) { --d: 12px !important; }
  .page-hero > [aria-hidden] > [style*="left:"],
  .closing-cta__deco > [style*="left:"] { left: 14px !important; right: auto !important; }
  .page-hero > [aria-hidden] > [style*="right:"],
  .closing-cta__deco > [style*="right:"] { right: 14px !important; left: auto !important; }
  .page-hero > [aria-hidden] > .person:nth-child(even)[style*="left:"],
  .closing-cta__deco > .person:nth-child(even)[style*="left:"] { left: 38px !important; }
  .page-hero > [aria-hidden] > .person:nth-child(even)[style*="right:"],
  .closing-cta__deco > .person:nth-child(even)[style*="right:"] { right: 38px !important; }
  /* Schild, Baken, Hund und Erkennungsrahmen brauchen mehr Platz als die
     Randbahn hergibt */
  .page-hero .dog, .page-hero .scene__ret { display: none; }
  .page-hero .ph-bake + .ph-bake { left: 34px !important; }
  .closing-cta .wrap { padding-inline: calc(var(--page-margin) + 48px); }
  .section > [aria-hidden] > .person,
  .privacy__deco { display: none; }
}
@media (max-width: 480px) {
  .page-hero__inner { padding-inline: 44px; }
  .page-hero > [aria-hidden] > [style*="left:"],
  .closing-cta__deco > [style*="left:"] { left: 6px !important; }
  .page-hero > [aria-hidden] > [style*="right:"],
  .closing-cta__deco > [style*="right:"] { right: 6px !important; }
  .page-hero > [aria-hidden] > .person:nth-child(even)[style*="left:"],
  .closing-cta__deco > .person:nth-child(even)[style*="left:"] { left: 24px !important; }
  .page-hero > [aria-hidden] > .person:nth-child(even)[style*="right:"],
  .closing-cta__deco > .person:nth-child(even)[style*="right:"] { right: 24px !important; }
  .page-hero > [aria-hidden] > .person,
  .closing-cta__deco > .person { --d: 12px !important; }
  .page-hero > [aria-hidden] > .person:nth-child(even),
  .closing-cta__deco > .person:nth-child(even) { --d: 10px !important; }
  .closing-cta .wrap { padding-inline: calc(var(--page-margin) + 24px); }
}

/* ==========================================================================
   760 — Telefon: ein Strang
   ========================================================================== */
@media (max-width: 760px) {
  :root {
    --page-margin: 24px;
    --gutter: 16px;
    --fs-display: 34px;
    --fs-stat: 40px;
    --fs-h2: 26px;
    --fs-lead: 18px;
  }
  .section { padding-block: var(--s-6); }
  .statement-band { padding-block: var(--s-5); }

  /* Deutsche Komposita sind länger als eine Telefonspalte breit ist —
     „Datenschutzerklärung" allein misst in der Auszeichnungsgröße mehr als
     ein 320-px-Bildschirm hergibt und schob die ganze Seite auf.
     break-word greift ausschließlich bei Wörtern, die sonst überliefen;
     alles, was passt, bricht unverändert an der Wortgrenze. Die Trennstriche
     kommen von hyphens:auto und funktionieren, weil jede Seite ihre Sprache
     im <html lang> mitbringt. */
  h1, h2, h3, h4, p, li, dd, td, th, summary, label,
  .display, .h2, .lead, .prose { overflow-wrap: break-word; }
  /* Trennstriche NUR dort, wo wirklich lange Wörter auf wenig Breite treffen:
     in der Auszeichnungsgröße und im Fließtext der Rechtsseiten. Auf den
     versalen Kartentiteln sah die Trennung falsch aus („MEDIZINI-SCHE"), und
     nötig ist sie dort nicht — break-word oben fängt Ausreißer ohnehin ab. */
  .display, .prose { hyphens: auto; }
  /* Ausnahme: der Werbeclaim auf der Startseite. Dort trennte die Automatik
     „SCHÜTZEN, WAS PRI-VAT IST." — in einem Claim liest sich ein Trennstrich
     wie ein Fehler. Nötig ist sie dort nicht: beide Zeilen passen bei 320 px
     ohne Trennung in die Spalte (nachgemessen 280 von 280 px).
     Die Automatik bleibt für alle anderen Auszeichnungsüberschriften an, weil
     sie dort trägt: „DATENSCHUTZERKLÄRUNG." misst ohne Trennung 430 px in
     derselben 280-px-Spalte. Das Wort steht im Rasterfeld, dessen Mindestbreite
     das ungetrennte Wort einschließt — overflow-wrap greift deshalb nicht, und
     die ganze Seite wird aufgeschoben. */
  .display--claim { hyphens: manual; }
  /* Bühnen-Titel tragen keine Satzzeichen — auch keinen automatischen
     Trennstrich („JE-DEN“). */
  .page-hero .display { hyphens: manual; }

  /* Bis 480 px bleiben die Raster ZWEISPALTIG (die Regeln aus dem
     1024er-Block gelten weiter) — einspaltig hieß hier: halbe Breite leer
     und doppelt so viel Scrollen. Nur die Abstände werden knapper. */
  .stats, .ledger__row, .press-grid { grid-template-columns: 1fr; }
  .ledger__row { gap: var(--s-1); }
  .feature-list { row-gap: var(--s-5); }
  .feature-list.feature-list .feature { padding-inline: var(--s-3); }
  .feature-list--buendig.feature-list--buendig .feature:nth-child(n) { padding-left: var(--s-3); }
  .feature-list--buendig.feature-list--buendig .feature:nth-child(2n + 1) { padding-left: 0; }
  .feature__icon { width: 40px; height: 40px; }
  .feature__icon svg { width: 28px; height: 28px; }
  .feature h3 { font-size: 15px; }
  .feature p { font-size: 15px; }
  .glass-grid, .glass-grid--3, .detail-cards, .detail-cards--3 { row-gap: var(--s-4); }
  .detail-card { padding: var(--s-3); }
  .glass-grid .glass-card { padding: var(--s-2) var(--s-3); }
  .glass-card p { font-size: 15px; }
  .navy-card { padding: var(--s-3); }
  .navy-card h3 { font-size: 16px; }
  .navy-card p { font-size: 15px; }
  .press-grid { gap: var(--s-2); }
  /* Pilot-Leistungen zu zweit, Titel eine Stufe kleiner */
  .feature-list.feature-list--pilot { row-gap: var(--s-4); }
  .feature-list--pilot .feature h3 { font-size: 18px; }
  /* Überschrift → Inhalt: die großen Desktop-Abstände halbieren */
  .section-title { gap: var(--s-2); }
  .section .mt-64 { margin-top: var(--s-4); }
  .section .mt-80, .section .mt-96 { margin-top: var(--s-8); }
  /* Rechtsbündige Blöcke lesen sich auf schmalen Schirmen schlecht */
  .block-rechts { justify-items: start; text-align: left; }
  .closing-cta { padding-block: var(--s-8); }
  .section .mt-40, .section .mt-48 { margin-top: var(--s-3); }
  .zeitplan__balken { min-height: calc(24px * var(--monate)); }

  /* Die Kacheln der Startseite bleiben zu zweit: sechs volle Breiten
     untereinander wären eine sehr lange Rutschbahn. */
  .tile { min-height: 128px; }
  .tile__label { font-size: 14px; }

  /* ---------- Kopfzeile und Bühnen ---------- */
  /* Der Faktor rechnet sich weiter aus der Bildbreite, nur der Abstand von
     oben wird knapper — der Kopfbereich ist hier niedriger. */
  .hero__graphics { inset-block-start: 24px; }
  .hero { min-height: 88vh; }
  /* In den kleinen Ortszenen tritt die Menge auf dem Telefon zurück, damit
     der Erkennungsrahmen trägt. Die gelbe Markierungsfigur bleibt davon
     unberührt: ihre Deckkraft kommt aus einer Keyframe-Animation, und die
     steht in der Kaskade über einer normalen Deklaration. */
  .person { opacity: .2; }
  /* Die Bühne der Startseite ist die Ausnahme — dort ist die Menge nicht
     Beiwerk hinter einem Rahmen, sondern das Bild selbst. Alle Figuren, die
     dort ohnehin ein- und ausgeblendet werden, hängen an Animationen; die
     gehen dieser Rücknahme in der Kaskade vor und bleiben unverändert. */
  .hero__graphics .person { opacity: 1; }
  /* 24 px höher angesetzte Bühne, also auch der Text 24 px höher. */
  .hero__inner { padding-top: calc(126px + 45vw); padding-bottom: var(--s-6); }
  .hero__claim { margin-top: var(--s-8); }
  .hero .badges { margin-top: var(--s-6); gap: var(--s-1); }
  .badge { padding: 10px 16px; font-size: 14px; }
  .page-hero { min-height: 320px; padding-top: 104px; }
  .page-hero .display { font-size: 30px; }
  .page-hero .lead { font-size: 17px; }

  /* Knöpfe: das lange „Jetzt Kontakt aufnehmen" passt sonst nicht */
  .cta { padding: 14px 24px; }
  .cta--blue, .cta--outline, .cta--outline-dark { padding: 14px 24px; }

  /* ---------- Prinzipien 01/02/03 ---------- */
  /* Die freistehenden Ziffern sind auf 1440 px gesetzt und träfen im
     schmalen Strang nicht mehr ihren Textblock. Statt sie fallen zu lassen,
     bekommt jeder Block seine eigene Ziffer über einen Zähler — dieselbe
     Bildsprache, nur an der richtigen Stelle. */
  .principles__num { display: none; }
  .principles__inner { counter-reset: prinzip; }
  .principle {
    counter-increment: prinzip;
    padding-top: var(--s-6);
    text-align: left;
    justify-items: start;
  }
  .principle::before {
    content: counter(prinzip, decimal-leading-zero);
    position: absolute;
    z-index: 0;
    top: -14px; left: -4px;
    font-size: 84px;
    font-weight: 900;
    line-height: 1;
    letter-spacing: 0;
    color: rgba(255, 255, 255, .2);
    pointer-events: none;
    user-select: none;
  }
  .principle h3 { font-size: 26px; white-space: normal; }
  .principle p { font-size: var(--fs-body); }
  .principle--1, .principle--2, .principle--3 { margin-top: var(--s-6); }
  .principle--2 h3 { width: auto; text-align: left; }
  .principles__cta { text-align: left; margin-top: var(--s-5); }

  /* ---------- Fußzeile ---------- */
  .site-footer__spalte--bereiche { grid-column: 1 / span 6; grid-row: 2 / span 2; }
  .site-footer__spalte--unternehmen { grid-column: 7 / span 6; grid-row: 2; }
  .site-footer__spalte--kontakt { grid-column: 7 / span 6; grid-row: 3; }
  .site-footer__leiste { flex-direction: column; align-items: flex-start; }
  .site-footer__rechtlich { flex-wrap: wrap; }

  /* ---------- Formulare ---------- */
  /* Auf breiten Schirmen sitzt die Fehlermeldung neben der Feldbezeichnung
     und verschiebt nichts. Dafür ist hier kein Platz — sie rückt unter das
     Feld und darf umbrechen. */
  .field__error {
    position: static;
    max-width: 100%;
    white-space: normal;
    margin-top: 4px;
  }
  .field--consent .field__error { position: static; }
  .panel { padding: var(--s-3); }

  /* ---------- Einzelteile ---------- */
  .statement-band { padding-block: var(--s-6); }
  .statement-band p { font-size: 19px; }
  .type-row h3 { font-size: 30px; }
  .type-row { padding-block: var(--s-3); }
  .ledger__row h3 { font-size: 22px; }
  /* Die Merkmalsspalte trägt Wörter wie „IMPLEMENTIERUNG". Mit den 22 % der
     großen Fassung blieben davon 119 px, und der Umbruchschutz zerlegte sie
     mitten im Wort („DATENSCHUT / Z"). Auf der Rollfläche kostet mehr Breite
     nichts — die Tabelle rollt ohnehin seitlich. */
  .compare table { min-width: 620px; }
  .compare col.compare-col--label { width: 32%; }
  .compare th, .compare td { padding: var(--s-2) var(--s-1); font-size: 14px; }
    .accordion { padding: var(--s-2) var(--s-3); }
  .accordion summary { gap: var(--s-2); }
  .ki-chat__verlauf { height: 220px; }
  .chat-bubble { max-width: 92%; padding: 10px 16px; }
  .notfound { padding: var(--s-4); }
  .notfound__code { font-size: 96px; }
  .prose h2 { font-size: 24px; }
  .stars-deco { width: 260px; height: 260px; right: -60px; top: 20px; }
    .img-slot { min-height: 200px; }
  .doc-toc a { padding: 10px 12px; }

  /* Der Hinweisbalken stapelt: Text oben, Schaltflächen darunter */
  .cookie { grid-template-columns: 1fr; }
  .cookie .cookie__actions { grid-column: 1; grid-row: auto; margin-top: var(--s-1); }
}

/* ==========================================================================
   480 — kleine Telefone
   ========================================================================== */
@media (max-width: 480px) {
  :root {
    --page-margin: 20px;
    --fs-display: 29px;
    --fs-stat: 34px;
  }
  /* Ab hier ist eine Zeile für lange Beschriftungen zu wenig — Knöpfe
     dürfen umbrechen, statt aus dem Bild zu laufen. */
  .cta { white-space: normal; text-align: center; padding: 14px 20px; }
  .badge { white-space: normal; text-align: center; }
  /* Kacheln bleiben auch hier zu zweit, nur flacher (fünf volle Breiten
     untereinander waren eine lange Rutschbahn) */
  .tile { min-height: 88px; padding: var(--s-2); }
  .tile__label { font-size: 12px; }

  /* Ab hier wird es einspaltig. Die senkrechten Trennlinien ergeben ohne
     Nachbarspalte keinen Sinn — stattdessen trennt eine waagerechte Linie. */
  .glass-grid, .glass-grid--3,
  .detail-cards, .detail-cards--3,
  .feature-list, .navy-grid, .press-grid, .field--row { grid-template-columns: 1fr; }
  .glass-grid--3, .detail-cards--3 { grid-template-columns: 1fr; }
  .feature-list > *, .navy-grid > *, .detail-cards--3 > *, .glass-grid--3 > *,
  .feature-list > :last-child:nth-child(odd),
  .navy-grid > :last-child:nth-child(odd),
  .detail-cards--3 > :last-child:nth-child(odd),
  .glass-grid--3 > :last-child:nth-child(odd) { grid-column: auto; }
  .feature-list.feature-list > .feature:last-child:nth-child(odd):not(:first-child) { padding-inline: 0; }
  .glass-grid.glass-grid .glass-card,
  .detail-cards.detail-cards .detail-card,
  .feature-list.feature-list .feature { border-left: 0; padding: 0; }
  /* Gegenstück zu den Zweispalter-Linien weiter oben (vier Klassen) */
  .glass-grid.glass-grid .glass-card:not(:nth-child(2n + 1)),
  .detail-cards.detail-cards .detail-card:not(:nth-child(2n + 1)),
  .feature-list.feature-list .feature:not(:nth-child(2n + 1)) { border-left: 0; }
  .feature-list--buendig.feature-list--buendig .feature:nth-child(n) { padding-left: 0; }
  .glass-grid--3.glass-grid--3 .glass-card:not(:first-child),
  .feature-list.feature-list .feature:not(:first-child) {
    border-top: 1px solid rgba(255, 255, 255, .35);
    padding-top: var(--s-2);
  }
  .feature-list--light.feature-list--light .feature:not(:first-child) { border-top-color: rgba(12, 28, 62, .12); }
  .detail-cards.detail-cards .detail-card:not(:first-child) {
    border-top: 1px solid rgba(12, 28, 62, .18);
    padding-top: var(--s-2);
  }
  .glass-grid, .glass-grid--3, .detail-cards, .detail-cards--3 { row-gap: var(--s-2); }
  .feature-list, .feature-list.feature-list--pilot { row-gap: var(--s-2); }
  /* Symbol neben den Titel statt darüber — spart pro Position eine Zeile */
  .feature-list .feature { grid-template-columns: 32px 1fr; column-gap: var(--s-2); align-items: center; }
  .feature-list .feature .feature__icon { width: 32px; height: 32px; place-items: center start; }
  .feature-list .feature .feature__icon svg { width: 24px; height: 24px; }
  .feature-list .feature p { grid-column: 1 / -1; }
  .umfang ul { grid-template-columns: 1fr; }
  .page-hero .display { font-size: 26px; }
  /* Ein Titel aus einem einzigen langen Wort („Datenschutzerklärung“ misst
     14,6 em) passt bei 26 px erst ab rund 420 px Breite. Statt ihn mit
     Trennstrich zu brechen, wird er hier gerade so klein, dass er in eine
     Zeile passt. Diese Bühne hat keine Figuren, darf also die volle Breite. */
  .page-hero__inner:has(.display--langwort) { padding-inline: var(--page-margin); }
  .page-hero .display--langwort {
    font-size: min(26px, calc((100vw - 2 * var(--page-margin)) / 14.8));
    white-space: nowrap;
  }
  .notfound__code { font-size: 72px; }
  .site-footer__spalte--bereiche,
  .site-footer__spalte--unternehmen,
  .site-footer__spalte--kontakt { grid-row: auto; }
  .site-footer__spalte--bereiche { grid-column: 1 / span 12; }
  .site-footer__spalte--unternehmen { grid-column: 1 / span 6; }
  .site-footer__spalte--kontakt { grid-column: 7 / span 6; }
  .statement-band .eyebrow::before,
  .statement-band .eyebrow::after { width: 16px; }
}
