/* ============================================================
   icosmedia.de Relaunch v6 — Prototyp
   Zentrale CSS-Datei · Tokens und Regeln nach ICOS Brand & Style Guide v2.0
   (icos-style-guide.html: Farbe, Typografie, Web-UI, Design-Tokens).
   Kernregeln: Open Sans als einzige Schrift · nur die Gewichte 400/600/700 ·
   oranger Vollton mit anthrazitfarbener Schrift · Orange nie als Fließtext.
   ============================================================ */

/* ---------- 0. Schrift (selbst gehostet, kein Google-CDN) ----------
   Variable Font 400–700 in einer Datei je Subset statt drei Schnitten:
   weniger Requests, und der Browser lädt latin-ext nur bei Bedarf.
   Aktualisieren: scripts/fetch-fonts.sh */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 1. Tokens ---------- */
:root {
  --navy:        #1E4975;   /* ICOS Blau — verbindlich */
  --navy-deep:   #1E4975;   /* Der Guide kennt keinen dunkleren Blauton:
                               dunkle Flächen laufen flach im Markenblau. */
  --navy-soft:   #E9EDF1;   /* blue-10: Karten, Marker, Tracks */
  --orange:      #FF940A;   /* ICOS Orange — einziges Brand-Orange */
  --orange-dark: #F0880A;   /* nur Button-Hover-Fläche */
  --orange-text: #B65E00;   /* Orange als Fließtext — nie #FF940A auf Weiß */
  --ink:         #191919;   /* ICOS Anthrazit, 16,9:1 auf Weiß */
  --muted:       #5E5E5E;   /* text-secondary */
  --muted-soft:  #8C8C8C;   /* text-muted */
  --line:        #E6EBEF;   /* Rahmen, Trenner (hairline) */
  --line-strong: #D2DBE3;   /* blue-20: Rahmen bei Hover / betonte Trenner */
  --paper:       #FFFFFF;   /* Seiten-Hintergrund */
  --surface-2:   #F5F7F9;   /* bg-subtle: ruhige Sektionsflächen */
  --success:     #1E8E57;   /* Bestätigungen */
  --error:       #D23B2E;   /* Formular-Fehler */

  /* Getönte Flächen für zwei gleichwertige Alternativen (Abschnitt 11a) und
     für die Kundensystem-Grafik (17a). Das Blau ist NICHT neu, es ist der
     Ton der Trichter- und Kreisflächen im Hero der Startseite; das Orange
     ist derselbe Hell- und Sättigungswert, gedreht auf den Farbwinkel von
     --orange. Nur diese sechs Werte — keinen siebten Zwischenton erfinden. */
  --blau-flaeche:        #D4E2F0;   /* Fläche */
  --blau-flaeche-tief:   #C2D9EF;   /* dieselbe Fläche eine Stufe tiefer (Hover) */
  --blau-flaeche-linie:  #BCD0E6;   /* Kontur/Trenner darin */
  --orange-flaeche:      #FBE8D5;
  --orange-flaeche-tief: #F8DCC0;
  --orange-flaeche-linie: #F0D2AC;

  --logo-blue:   #29446B;   /* Logo-Sonderfall lt. Style Guide */

  --font-sans: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --font-mono: "SFMono-Regular", "JetBrains Mono", Menlo, Consolas, monospace;

  /* Typo-Skala. Die Werte stehen so im Brand & Style Guide v2.0, Abschnitt
     „06 Typografie · 02 Typo-Skala — Web". Vier Überschriften-Rollen, drei
     Textrollen — mehr gibt es nicht. Die Display-Ebene des Guides (700 · 64px
     · LH 1.05, „Markenaussage · Claim") ist hier NICHT abgebildet: keine Seite
     braucht sie, H1 ist die größte Stufe der Website. Erst wenn eine
     Claim-Seite entsteht, kommt sie dazu — nicht vorher. */
  --text-h1:      clamp(min(32px, 8.6vw), 4.2vw, 48px);  /* Guide: 40px, Oberkante hier 48 */
  --text-h2:      clamp(25px, 2.6vw, 30px);              /* Guide: 30px */
  --text-h3:      21px;                                  /* Guide: 21px */
  --text-h4:      17px;                                  /* Guide: 17px, = Label */
  --text-body:    17px;                                  /* Guide: 17px / LH 1.6 */
  --text-lead:    19px;                                  /* Erweiterung: Vorlauftext, ein Verwender (.lead) */
  --text-small:   15px;                                  /* Guide: 15px „Klein / sekundär" */
  --text-eyebrow: 13px;                                  /* Guide: 700 · 13px · +0.08em · UPPER */

  /* Spacing, 4er-Raster — identisch zum Guide (--space-1…10). Neue Regeln
     nehmen ausschließlich diese Werte. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  --radius-card: 14px;   /* Style Guide --radius: Karten UND Buttons */
  --radius-input: 8px;
  --radius-pill: 999px;
  /* Der leise Schatten, der auf getönter Fläche den Rahmen ersetzt. Stand
     zehnmal wörtlich in der Datei, bevor er einen Namen hatte (Guide: --shadow-sm). */
  --shadow-hairline: 0 1px 2px rgba(22, 51, 79, .05);
  --shadow-card: 0 4px 16px rgba(25, 45, 77, .07), 0 1px 3px rgba(25, 45, 77, .05);
  --shadow-float: 0 18px 48px rgba(25, 45, 77, .12), 0 4px 12px rgba(25, 45, 77, .06);

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --fade-y: 14px;        /* Hubhöhe von fade-up; je Verwender überschreibbar */

  /* Container. Drei Maße, drei Aufgaben: Textmaß (Leseweite), Seitenmaß
     (Standard) und randlos. Ein viertes Maß gibt es nicht — .prose lief
     vorher auf 760px, das war dasselbe Bedürfnis mit anderem Wert. */
  --container-content: 720px;
  --container-wide:   1200px;

  /* Sektionsrhythmus, drei Stufen auf dem 4er-Raster. Die Werte werden im
     Mobil-Breakpoint neu gesetzt, nicht in jeder Regel per @media überschrieben:
     ein Verwender schreibt padding: var(--section-md) 0 und ist fertig. */
  --section-sm: 64px;    /* space-8  · gedrängte Bahn */
  --section-md: 96px;    /* space-9  · Standardbahn */
  --section-lg: 128px;   /* space-10 · Hero-Bahn */

  /* Breakpoints. Nur diese drei — Referenz ideenmitholz.de fährt 1024/767,
     die 860 hält den Zwischenschritt 3→2 Spalten, den globale Grid-Klassen
     brauchen. Neue Regeln NIE auf einem vierten Wert aufsetzen.
     CSS erlaubt keine Variablen in @media, die Werte stehen hart im Code. */
  --bp-tablet: 1024px;
  --bp-small:   860px;
  --bp-mobile:  767px;
}

/* Mobil sind es dieselben Rollen mit kleineren Werten — deshalb hier die
   Tokens neu setzen statt in jeder Sektionsregel ein @media zu wiederholen. */
@media (max-width: 767px) {
  :root {
    --section-sm: 48px;   /* space-7 */
    --section-md: 64px;   /* space-8 */
    --section-lg: 72px;
  }
}

/* ---------- 2. Reset & Basis ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--navy); color: #fff; }

h1, h2, h3, h4 {
  color: var(--navy);
  line-height: 1.12;
  margin: 0 0 16px;
  text-wrap: balance;
  font-feature-settings: "ss01" off;
  overflow-wrap: break-word;
}
/* Deutsche Komposita ("Digitalisierungsbegleitung:") sind breiter als die
   350px-Spalte auf dem Handy. Ein 1fr-Track waechst mit dem min-content mit
   und schiebt die ganze Spalte aus dem Viewport — nur Silbentrennung senkt
   den min-content, overflow-wrap allein tut das nicht. Nicht global: auf
   Desktop trennt sie zusammen mit text-wrap:balance ohne Not. */
@media (max-width: 767px) {
  h1, h2, h3, h4, .cb__titel { hyphens: auto; }
}
/* Typo-Skala Web lt. Guide. Bold 700 ist das schwerste Gewicht — kein 800.
   Die Untergrenze ist min(32px, 8.6vw) statt 32px: .swoosh trägt zwingend
   white-space:nowrap (sonst zerreisst der Bogen), und ein Schlüsselwort wie
   „15 Minuten Klarheit" braucht bei 32px 305px — mehr als die 280px, die bei
   einem 320px-Fenster im Container bleiben. Gemessen auf /erstgespraech/.
   8.6vw erreicht 32px bereits bei 373px Fensterbreite, oberhalb davon ändert
   sich also nichts an der Skala; nur die schmalsten Geräte und Browser-Zoom
   ab 125% bekommen kleinere Grade statt einer Seite, die nach rechts ausläuft. */
/* Vier Rollen, an das Element gebunden statt an eine Klasse: wer <h2> schreibt,
   bekommt die Sektionsüberschrift — es gibt keine .h2-Variante daneben.
   h1 = Display der Website (die 64px-Display-Ebene des Guides ist unbenutzt). */
h1 { font-size: var(--text-h1); line-height: 1.1;  letter-spacing: -0.02em; font-weight: 700; }
h2 { font-size: var(--text-h2); line-height: 1.15; letter-spacing: -0.02em; font-weight: 700; }
h3 { font-size: var(--text-h3); line-height: 1.2;  letter-spacing: -0.02em; font-weight: 700; }
h4 { font-size: var(--text-h4); letter-spacing: -0.02em; font-weight: 700; }

p, ul, ol { margin: 0 0 16px; max-width: 66ch; }
p { text-wrap: pretty; }
ul, ol { padding-left: 22px; }
li { margin-bottom: 8px; }

/* Textlink = Markenblau, im Markenblau unterstrichen. Der Unterstrich stand
   vorher auf --line-strong (#D2DBE3) und war damit kaum zu sehen — ein Link
   im Fließtext liest sich dann wie fetter Text. Jetzt trägt er dieselbe Farbe
   wie die Schrift.

   Abgrenzung zum Arrow-Button (Abschnitt 6): der ist 600 fett und trägt einen
   2px-Unterstrich in Orange. Der Textlink bleibt normalgewichtig mit 1px in
   Blau — beim Überfahren wechselt der Strich auf Orange, damit der Hover ein
   sichtbares Ziel hat. Ohne das wäre er unverändert, weil Schrift- und
   Strichfarbe schon gleich sind. */
a { color: var(--navy); text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: var(--navy); transition: color .15s ease, text-decoration-color .15s ease; }
a:hover { color: var(--navy); text-decoration-color: var(--orange); }

/* Auf dunklem Blau kehrt sich das um: Navy auf Navy wäre unlesbar, also
   Schrift und Unterstrich in Weiß. Betrifft die drei dunklen Flächen der
   Seite — .section--navy, .cta-block und die Banner-Bahn .cb--navy.

   :not(.btn):not(.btn-arrow), weil Knöpfe dort ihre eigene Farbgebung haben:
   .btn--primary ist oranger Vollton mit anthrazitem Text, .btn--secondary
   schaltet über die Regel in Abschnitt 6 auf Weiß. Ohne den Ausschluss
   würden beide hier überschrieben.

   Der Footer ist ebenfalls navy, hat aber seit jeher eine eigene Regel
   (Abschnitt 33: #E8F0F7, ohne Unterstrich) und bleibt unangetastet. */
.section--navy a:not(.btn):not(.btn-arrow),
.cta-block a:not(.btn):not(.btn-arrow),
.cb--navy a:not(.btn):not(.btn-arrow) {
  color: #fff;
  text-decoration-color: rgba(255, 255, 255, .55);
}
.section--navy a:not(.btn):not(.btn-arrow):hover,
.cta-block a:not(.btn):not(.btn-arrow):hover,
.cb--navy a:not(.btn):not(.btn-arrow):hover {
  color: #fff;
  text-decoration-color: #fff;
}

img, svg { max-width: 100%; height: auto; }

small, .small { font-size: 14px; }

strong { font-weight: 700; }

hr { border: none; border-top: 1px solid var(--line); margin: 32px 0; }

table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nums; }

input, textarea, select, button { caret-color: var(--orange); }

:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
  border-radius: 4px;
}

@supports (scrollbar-color: red blue) {
  html { scrollbar-color: #B6C6D4 transparent; }
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--navy);
  color: #fff;
  padding: 12px 20px;
  z-index: 200;
  border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; color: #fff; }

/* ---------- 3. Layout ---------- */
/* Drei Container-Rollen, keine vierte:
     wide      = .container, Seitenmaß 1200 inkl. Polster (border-box).
                 Deckt sich mit der Referenz (Elementor 1200 + 10px Polster).
     content   = --container-content (720px). Trägt .section-head und .prose;
                 KEINE eigene .container--content-Klasse, die wäre ein dritter
                 Name für dasselbe Maß.
     full      = randlos. Existiert genau einmal (.uebergabe__platte) und
                 braucht dort eine asymmetrische Geometrie — deshalb
                 Komponenteneigenschaft, keine gemeinsame Klasse für einen
                 einzigen Verwender. Kommt ein zweiter, wird sie eine. */
.container {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: 0 10px;
}
@media (max-width: 767px) {
  .container { padding: 0 20px; }
}

/* Sektionsbahnen: drei Höhen, benannt statt gezählt. Kein @media hier — die
   Tokens selbst werden im Mobil-Breakpoint kleiner (Abschnitt 1). */
.section { padding: var(--section-md) 0; }
.section--soft { background: var(--surface-2); }
.section--navy { background: var(--navy); color: #fff; }
.section--navy h2, .section--navy h3 { color: #fff; }
.section--compact { padding: var(--section-sm) 0; }

/* minmax(0,1fr) statt 1fr: ein 1fr-Track hat min-content als Untergrenze und
   wird von einem breiten Kind aufgeblasen, bis er breiter ist als sein
   eigener Container. Gemessen bei 320px auf /tools/: der .grid-3-Track stand
   auf 324,7px bei 280px Containerbreite — die ganze Seite lief nach rechts
   aus. minmax(0,…) nimmt die Untergrenze weg, das Kind muss schrumpfen. */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; }
/* Engerer Abstand, wenn die beiden Spalten Karten tragen statt Textblöcke. */
.grid-2--tight { gap: 20px; }
/* Spalten oben bündig statt gestreckt: neben einem hohen Formular bleibt der Text am Bild (seit 08.10.2026, /danke/). */
.grid-2--oben { align-items: start; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }
.grid--center { align-items: center; }
/* Zickzack: dreht die Spaltenfolge in jeder zweiten Zeile um, damit Bild und
   Text abwechselnd links stehen. Nur über dem Umbruch — gestapelt muss das
   Bild immer über seinem Text bleiben, sonst steht der Text beim ersten
   Block über, beim zweiten unter dem Bild. */
.grid--flip > :first-child { order: 2; }
@media (max-width: 767px) { .grid--flip > :first-child { order: 0; } }
@media (max-width: 1024px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
}

/* Zwei Spalten mit schmaler Medienspalte: Hochformat-Grafik neben Textblock.
   Bricht früher um als .grid-2, weil die Textspalte sonst zu schmal wird. */
.grid-media { display: grid; grid-template-columns: 360px minmax(0, 1fr); gap: 64px; }
@media (max-width: 860px) {
  .grid-media { grid-template-columns: 1fr; gap: 32px; }
  .grid-media .img-placeholder { max-width: 340px; }
}

.center { text-align: center; }
.center p, .center ul { margin-left: auto; margin-right: auto; }

.section-head { max-width: var(--container-content); margin-bottom: 56px; }
.section-head--center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head p:last-child { margin-bottom: 0; }
@media (max-width: 767px) { .section-head { margin-bottom: 40px; } }

/* ---------- 4. Typo-Hilfsklassen ---------- */
/* Eyebrow = Label-Rolle des Guides: 700 · 13px · +0.08em · Versalien. Steht als
   Kontextzeile über H1 und H2 und ist die einzige Versalien-Auszeichnung der
   Seite — kein zweites Kicker- oder Chip-Textformat daneben. */
.eyebrow {
  display: block;
  font-size: var(--text-eyebrow);
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--muted);
  margin-bottom: 14px;
}
.section--navy .eyebrow { color: #9FB8CE; }

.lead { font-size: var(--text-lead); line-height: 1.6; color: var(--muted); }
.section--navy .lead, .section--navy p { color: #D6E2EE; }

.muted { color: var(--muted); }

/* Utilities (ersetzen Inline-Styles) */
.m-0 { margin: 0 !important; }
.mt-8 { margin-top: 8px !important; }
.mt-16 { margin-top: 16px !important; }
.mt-24 { margin-top: 24px !important; }
.mt-40 { margin-top: 40px !important; }

.mb-16 { margin-bottom: 16px !important; }
.mx-auto { margin-left: auto !important; margin-right: auto !important; }
.max-w-none { max-width: none !important; }
/* Doppelter Kopfabstand einer Bahn — rechnet mit dem Token, damit der Mobil-
   Wert (Abschnitt 1) mitschrumpft. Kein neuer Abstandswert. */
.pt-double { padding-top: calc(var(--section-sm) * 2) !important; }
/* Haelt ein Wort zusammen, das sonst an einem Bindestrich umbrechen wuerde.
   Gebraucht in der Kreislauf-Mitte der App-Seiten: „Buchhaltung und
   E-Rechnung" brach nach dem „E" um und liess einen einzelnen Buchstaben
   am Zeilenende stehen. Der Umbruch gehoert vor das ganze Wort. */
.nowrap { white-space: nowrap; }
.text-15 { font-size: 15px; }
.text-18 { font-size: 18px; }
.text-19 { font-size: 19px; }
/* Nur für Screenreader: Text, der vorgelesen, aber nicht gezeigt wird. Das
   übliche Muster mit clip, die Fläche schrumpft auf einen Pixel und wird
   abgeschnitten (display:none würde auch das Vorlesen abschalten).
   !important wie bei den Utilities oben: Die Klasse sitzt auch in Bausteinen,
   deren eigene Regeln Kinder als Grid- oder Flex-Element setzen (.kanal,
   .btn), und darf dort nie sichtbar werden. Gesetzt von main.js („Links in
   einem neuen Tab“) an jedem Link mit target="_blank" ohne aria-label. */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* ---------- 5. Buttons (C4) ---------- */
/* Ein Button-System, eine Farbe: oranger Vollton mit anthrazitfarbener
   Schrift (8,7:1, AAA). inline-flex, damit min-height die Schrift zentriert.

   Drei Erscheinungsbilder für vier Rollen — mehr braucht die Seite nicht:
     .btn--primary    Vollton. Die eine Haupthandlung je Bahn.
     .btn--secondary  Orange-Outline. Im Guide heißt dieses Bild „ghost";
                      der Guide führt daneben ein .ui-btn--secondary, das
                      byteweise dem Primary gleicht — eine Kopie, kein Muster.
                      Deshalb gibt es hier KEIN .btn--ghost: es wäre ein
                      vierter Name für dieses eine Bild.
     .btn-arrow       Arrow-Button: blaue 600er Schrift, oranger
                      2px-Unterstrich, Pfeil → im Text. Referenz /leistungen/.
                      Jede Handlung, die nicht wie ein Knopf aussehen soll
                      (Hero-Nebenhandlung, Kartenfuß, Glossar).
     .btn--small      Größenvariante, kein eigenes Bild.
   Neue Handlung? Eine dieser Rollen wählen. Kein neuer Button. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: var(--text-small);
  font-weight: 700;
  letter-spacing: -0.006em;
  line-height: 1.2;
  padding: 13px 24px;
  border-radius: var(--radius-card);
  border: 1.5px solid transparent;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  transition: background .2s var(--ease), transform .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
  min-height: 48px;
}
.btn--primary,
.btn--primary:hover { color: #191919; border-color: transparent; }
.btn--primary {
  background: var(--orange);
  box-shadow: 0 4px 14px rgba(255, 148, 10, .30);
}
.btn--primary:hover {
  background: var(--orange-dark);
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(255, 148, 10, .34);
}
/* Leise Nebenaktion: Orange-Outline — keine zweite Buttonfarbe.
   (= „ghost" im Brand & Style Guide, Abschnitt 09 · 01 Buttons.) */
.btn--secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--orange);
}
.btn--secondary:hover { background: #FFF4E7; border-color: var(--orange); color: var(--ink); }
/* Auf dunklem Grund traegt die Grundfarbe des Sekundaerknopfs nicht: --ink auf
   --navy sind 1,9:1. Die drei dunklen Flaechen der Seite sind .section--navy,
   .cta-block und .cb--navy (Banner-Bahn, Abschnitt 16a) — alle drei brauchen
   dieselbe Umschaltung auf Weiss. */
.section--navy .btn--secondary, .cta-block .btn--secondary, .cb--navy .btn--secondary {
  color: #fff;
  border-color: var(--orange);
}
.section--navy .btn--secondary:hover, .cta-block .btn--secondary:hover, .cb--navy .btn--secondary:hover {
  background: rgba(255, 148, 10, .16);
  border-color: var(--orange);
  color: #fff;
}
.btn--block { display: flex; width: 100%; }
/* Header-CTA: zwischen ui-btn--sm (13 px) und Default (15 px), nicht gequetscht. */
.btn--small { padding: 10px 22px; font-size: 14px; min-height: 42px; }

/* Arrow-Button — die dritte und letzte Handlungsform.
   Referenz ist /leistungen/, Karte „Beratung": Anthrazit-Blau, 600, 15px,
   oranger 2px-Unterstrich mit 4px Abstand, Pfeil → im Text. Beim Hover wird
   der Unterstrich blau. Genau dieses Bild, nirgendwo ein zweites.

   Verbindlich:
   · Der Pfeil steht IM Text (…"ansehen →"), nicht als ::after — so wie in der
     Referenz. Ein Arrow-Button ohne Pfeil gibt es nicht.
   · Der Unterstrich ist orange. Ein nur blauer Verweis ist kein Arrow-Button.
   · Als <span> zulässig, wenn die ganze Karte der Link ist (ein <a> im <a>
     wäre ungültig) — die Hover-Regel unten fasst diesen Fall mit.
   Ersetzt: .card__cta, .card__link, .kreislauf__more, .buch-angebot__cta und
   die ungestylten Pfeil-Links. */
.btn-arrow {
  font-weight: 600;
  font-size: var(--text-small);
  color: var(--navy);
  text-decoration-line: underline;
  text-decoration-color: var(--orange);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
  transition: color .15s ease, text-decoration-color .15s ease;
}
.btn-arrow:hover,
a:hover .btn-arrow {
  color: var(--navy-deep);
  text-decoration-color: var(--navy-deep);
}
.btn-arrow:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; border-radius: 3px; }

.microcopy {
  display: block;
  font-size: var(--text-eyebrow);
  color: var(--muted);
  margin-top: 12px;
}
.section--navy .microcopy, .cta-block .microcopy { color: #9FB8CE; }

.cta-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* ---------- 6. Header / Navigation (C1) ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, .86);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .25s var(--ease);
}
.site-header.is-scrolled { box-shadow: 0 8px 24px -16px rgba(22, 51, 79, .25); }

/* Header läuft im selben 1200er-Container wie der Inhalt — kein Sonderfall. */

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 72px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  flex: none;
}
/* Der Zusatz weicht, sobald die Navigation den Platz braucht — siehe den
   Block "Header-Engstelle" weiter unten bei den Navigations-Regeln. */

/* Der Header ist an der Breitengrenze (siehe "Header-Engstelle"): bei 1440px
   bleiben zwischen Marke, Navigation und CTA rund 90px Luft. Die lag vorher
   komplett an den Rändern der Navigation — deshalb wächst sie hier auf die
   volle Restbreite und zentriert ihre Punkte, damit die Luft in die Lücken
   zwischen den Menüpunkten wandert statt links und rechts zu versickern.
   Mehr als 6px Lücke geht nur, wenn Claim oder CTA Platz abgeben. */
.nav { flex: 1 1 auto; }
.nav__list {
  display: flex;
  justify-content: center;
  /* Ohne das greift der 66ch-Deckel für Listen und schneidet die Navigation
     stillschweigend auf 640px zusammen. */
  max-width: none;
  gap: 4px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav__link {
  display: inline-block;
  padding: 10px 11px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border-radius: var(--radius-pill);
  transition: color .15s ease;
}
.nav__item > .nav__link { white-space: nowrap; }
/* Hover nur über die Farbe, keine Fläche: Eine graue Kachel hinter dem Menüpunkt
   konkurriert mit der orangen aria-current-Markierung darunter und lässt die
   Leiste unruhig wirken. Die Dropdown-Links darunter machen es genauso
   (.nav__dropdown a:hover). Tastaturnutzer verlieren dadurch nichts — der
   :focus-visible-Rahmen aus Abschnitt 2 bleibt. */
.nav__link:hover { color: var(--navy); }
.nav__link[aria-current="page"] { color: var(--navy); font-weight: 700; box-shadow: inset 0 -2px 0 var(--orange); border-radius: 0; }

/* KI-Dropdown (Desktop: hover/focus-within) */
.nav__item { position: relative; }
/* Strich-Chevron: dreht sich, wenn das Dropdown offen ist. */
.nav__caret {
  display: inline-block;
  margin-left: 3px;
  vertical-align: -2px;
  opacity: .7;
  transition: transform .16s var(--ease), opacity .16s var(--ease);
}
.nav__item:hover .nav__caret,
.nav__item:focus-within .nav__caret { opacity: 1; transform: rotate(180deg); }
.nav__dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 256px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-float);
  padding: 8px;
  margin: 6px 0 0;
  list-style: none;
  display: none;
  z-index: 120;
}
.nav__item:hover .nav__dropdown,
.nav__item:focus-within .nav__dropdown { display: block; }
/* Unsichtbare Brücke über den 6-px-Spalt: sonst reisst der Hover auf dem Weg
   vom Menüpunkt zum Unterpunkt ab und das Dropdown klappt zu. */
.nav__dropdown::before { content: ""; position: absolute; inset: -8px 0 auto; height: 8px; }
.nav__dropdown li { margin: 0; }
.nav__dropdown a {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}
.nav__dropdown a:hover { color: var(--navy); }
.nav__dropdown a small { display: block; font-size: 12px; font-weight: 400; color: var(--muted); margin-top: 1px; }

/* Breites Dropdown fuer grosse Gruppen. Der Zoho-Bereich fuehrt inzwischen 26
   Unterpunkte; in einer Spalte laeuft das Menue weit unter den unteren
   Bildschirmrand und die hinteren Eintraege sind nicht erreichbar. Ab elf
   Eintraegen setzt sync-nav.py deshalb diese Klasse.
   Mehrspaltensatz (column-count) statt Grid, weil er die Liste SPALTENWEISE
   von oben nach unten fuellt — die alphabetische Reihenfolge bleibt damit
   lesbar. Ein Grid wuerde zeilenweise fuellen und die Sortierung zerreissen.
   Die Breite ist auf den Viewport gedeckelt, das Panel haengt mittig unter dem
   Menuepunkt statt linksbuendig, sonst ragt es rechts heraus. */
.nav__dropdown--breit {
  width: min(760px, calc(100vw - 40px));
  left: 50%;
  transform: translateX(-50%);
  column-count: 3;
  column-gap: 4px;
}
.nav__dropdown--breit li { break-inside: avoid; }

/* Mega-Menü Leistungen (Briefing Leistungsstruktur, 08.10.2026): drei Spalten, sortiert danach, wer die Arbeit
   macht, gelesen von links nach rechts wie der Weg des Kunden: erst klären, dann selbst umsetzen oder umsetzen
   lassen. Leistungen steht ganz links in der Leiste, deshalb hängt das Panel linksbündig unter dem Menüpunkt;
   die Breite ist auf den Viewport gedeckelt. Grid statt Spaltensatz, weil jede Spalte eine eigene Gruppe ist.
   Die Leiste darunter (Förderung, Entscheidungshilfe, Button) ist am 09.10.2026 entfallen (Auftraggeber). */
.nav__dropdown--mega {
  width: min(900px, calc(100vw - 260px));
  padding: 18px 12px 14px;
  column-gap: 8px;
}
.nav__item:hover .nav__dropdown--mega,
.nav__item:focus-within .nav__dropdown--mega { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.nav__mega-spalte { min-width: 0; }
.nav__mega-spalte ul { list-style: none; margin: 0; padding: 0; }
.nav__mega-spalte ul ul { margin: 0 0 4px 12px; padding-left: 8px; border-left: 2px solid var(--line); }
.nav__mega-kopf {
  display: block; padding: 0 12px 10px; margin-bottom: 4px; border-bottom: 1px solid var(--line);
  font-size: 13px; font-weight: 700; color: var(--navy); letter-spacing: .02em;
}
/* Der Kernsatz hat in jeder Spalte Platz für zwei Zeilen (Auftraggeber, 09.10.2026): Links bricht „Wir klären mit
   dir, was passieren soll.“ um, so beginnen die Leistungen trotzdem in allen drei Spalten auf derselben Höhe. */
.nav__mega-kopf small { display: block; font-size: 12px; font-weight: 400; color: var(--muted); letter-spacing: 0; margin-top: 2px; line-height: 1.45; min-height: 2.9em; }
.nav__mega-hinweis { margin: 6px 12px 0; font-size: 12px; color: var(--muted); max-width: none; }

/* Förderhinweis auf jeder Leistungsseite (scripts/leistungsbloecke.py, Block „foerderung“): Icon links, Text und die
   beiden Wege rechts. Ein eigenes kleines Bauteil, weil es auf jeder Leistungsseite gleich steht. */
.foerderhinweis { display: flex; gap: 18px; align-items: flex-start; }
.foerderhinweis__icon { flex: none; margin-top: 2px; }
.foerderhinweis__titel { margin: 0 0 4px; font-weight: 700; color: var(--navy); }
.foerderhinweis__links { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 12px 0 0; max-width: none; }
.ziel__links { display: flex; flex-wrap: wrap; gap: 6px 16px; }
@media (max-width: 767px) { .foerderhinweis { flex-direction: column; gap: 10px; } }
.foerderhinweis-zeile { max-width: 820px; margin: 0 auto; }

/* Wegweiser /leistungen/: die drei Arbeitsweisen als Karten, je Leistung eine Zeile mit Name und Teaser wie im
   Mega-Menü. Haarlinien statt Kästchen, damit drei Karten mit fünf Einträgen nicht nach Formular aussehen. */
.arbeitsweise__liste { list-style: none; margin: 0; padding: 0; max-width: none; border-top: 1px solid var(--line); }
.arbeitsweise__liste li { margin: 0; border-bottom: 1px solid var(--line); }
.arbeitsweise__link { display: block; padding: 12px 0; text-decoration: none; color: inherit; }
.arbeitsweise__name { display: block; font-weight: 700; color: var(--navy); transition: color .2s var(--ease); }
.arbeitsweise__teaser { display: block; font-size: 14px; color: var(--muted); }
.arbeitsweise__link:hover .arbeitsweise__name { color: var(--orange-text); }

/* Checkliste in zwei Spalten, für die Inhalte einer Leistung in einer breiten Karte. ul ist global auf 66ch
   gedeckelt, deshalb max-width: none. */
.check-list--2spaltig { columns: 2; column-gap: 40px; max-width: none; }
.check-list--2spaltig li { break-inside: avoid; }
@media (max-width: 767px) { .check-list--2spaltig { columns: 1; } }

/* Entscheidungshilfe „Welcher Weg passt zu dir?“ (main.js, data-wegweiser): links vier Fragen mit Antworten als
   Chips, rechts der Vorschlag. Alle Ergebnisse stehen im HTML, das Skript blendet nur eins ein. Ohne Kontaktdaten. */
.wegweiser { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; align-items: start; }
.wegweiser__fragen { display: grid; gap: 14px; }
.wegweiser__frage { margin: 0; padding: 16px 18px; min-width: 0; border: 1px solid var(--line); border-radius: var(--radius-card); background: #fff; }
.wegweiser__frage legend { float: left; width: 100%; padding: 0; margin-bottom: 10px; font-size: 16px; font-weight: 700; color: var(--navy); }
.wegweiser__antworten { clear: both; display: flex; flex-wrap: wrap; gap: 8px; }
.wegweiser__antwort { position: relative; cursor: pointer; }
.wegweiser__antwort input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.wegweiser__antwort span {
  display: inline-block; padding: 8px 16px; font-size: 15px;
  border: 1.5px solid var(--line); border-radius: var(--radius-pill); background: #fff;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.wegweiser__antwort:hover span { border-color: var(--orange); }
.wegweiser__antwort input:checked + span { border-color: var(--orange); background: var(--orange); color: var(--ink); font-weight: 600; }
.wegweiser__antwort input:focus-visible + span { outline: 2px solid var(--navy); outline-offset: 2px; }
.wegweiser__ergebnisse { position: sticky; top: 88px; }
.wegweiser__ergebnis[hidden], .wegweiser__hinweis[hidden] { display: none; }
@media (max-width: 860px) {
  .wegweiser { grid-template-columns: minmax(0, 1fr); }
  .wegweiser__ergebnisse { position: static; }
}

/* Mobile-Navigation: die Leistungen in den drei Gruppen des Mega-Menüs. */
.mobile-nav__gruppe { margin: 14px 0 0; padding: 0 0 4px; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #8FA8BF; }
/* zwei Klassen, weil .mobile-nav__sub a das Polster sonst mit !important auf 0 setzt */
.mobile-nav .mobile-nav__einzug a { padding-left: 14px !important; }

/* Wortmarke in der Kreislauf-Mitte. Rueckfall des Zoho-Bauers fuer eine App
   ohne Logo (logo=None): statt eines erfundenen Logos steht dort der
   Produktname als Schrift. Groesse und Gewicht sind so gewaehlt, dass er neben
   den echten Logos (Hoehe 34px) nicht aus der Reihe faellt. Bis 10.10.2026 auf
   Invoice, Office Integrator, DAP und Projects Plus, seitdem tragen auch sie
   das Produktlogo (O15); die Regel bleibt fuer den Rueckfall. */
.kreislauf__wortmarke {
  display: inline-block;
  font-size: 19px;
  font-weight: 700;
  line-height: 34px;
  color: var(--navy);
  letter-spacing: -.01em;
}

/* Mobile-Nav Sub-Liste */
.mobile-nav__sub { list-style: none; margin: 4px 0 0; padding: 0 0 0 16px; }
.mobile-nav__sub a { font-size: 17px !important; font-weight: 600 !important; color: #C9D8E6 !important; padding: 10px 0 !important; border-bottom: 1px solid rgba(255,255,255,.08) !important; }
.mobile-nav__sub a:hover { color: var(--orange) !important; }

.header-cta { flex: none; }

.burger {
  display: none;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-input);
  padding: 10px;
  cursor: pointer;
  min-width: 48px;
  min-height: 48px;
}
.burger__bars { display: block; width: 22px; height: 2px; background: var(--navy); position: relative; margin: 0 auto; border-radius: 2px; }
.burger__bars::before, .burger__bars::after {
  content: ""; position: absolute; left: 0; width: 22px; height: 2px; background: var(--navy); border-radius: 2px;
}
.burger__bars::before { top: -7px; }
.burger__bars::after { top: 7px; }

/* Header-Engstelle. Kein Layout-Breakpoint, sondern die Kante des Containers
   selbst: ab 1200 abwärts ist der 1200er-Container nicht mehr voll
   ausgefahren, der Header wird schmaler als sein Inhalt braucht. Gemessen bei
   voller Breite: Marke 224 + Navigation 642 + CTA 224 + zwei Lücken à 24
   = 1138px gegen 1180px Inhaltsbreite. Bei 1025px Fenster bleiben nur 1005px.
   Claim (−120), engere Menüpunkte (−42) und der kompakte CTA (−36) bringen
   den Bedarf auf 940px. Ab 1024px greift ohnehin der Burger.
   Dieser Block MUSS nach .nav__link stehen — gleiche Spezifität, der spätere
   gewinnt. */
@media (max-width: 1200px) {
  .nav__link { padding-left: 8px; padding-right: 8px; }
  .nav__list { gap: 2px; }
  .header-cta .btn { padding: 10px 18px; font-size: 15px; min-height: 44px; }
  /* Gerechnet bei 1025px, wo die Navigation gerade noch steht (ab 1024 der
     Burger): Inhaltsbreite 1005px gegen Logo 121 + Nav 630 + CTA 228 = 979.
     Mit dem 24px-Gap zweimal dazwischen wären es 1027 — der CTA lief rechts
     hinaus. Gap auf 16 und Logo auf 40px Höhe: 991px, 14px Luft.
     Vorher trug das Logo hier keine Rolle, weil es nur die Wortmarke war. */
  .site-header__inner { gap: 16px; }
  .brand img { height: 40px; width: auto; }
}

@media (max-width: 1024px) {
  .nav { display: none; }
  .burger { display: block; }
}

/* Auf schmalen Telefonen weicht der Header-CTA.
   Gemessen bei 390px: Logo 104 + CTA 228 + Burger 48 plus drei Lücken à 24
   und 2x20 Innenabstand ergeben 492px Bedarf bei 390px Platz. Der Burger
   stand dadurch bei 448px, also ausserhalb des Fensters: das Menü war auf
   jedem Telefon nicht erreichbar. Das ist ein Funktionsfehler, keine
   Kosmetik.
   Der CTA geht dabei nicht verloren, er steht auf Mobil zweimal weiter:
   im Burger-Menü als btn--block und in der Sticky-Leiste (ab 860px sichtbar).
   Ohne CTA braucht der Header 104 + 48 + 48 + 40 = 240px. */
@media (max-width: 767px) {
  .header-cta { display: none; }
}

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: var(--navy-deep);
  color: #fff;
  padding: 24px;
  display: none;
  flex-direction: column;
  overflow-y: auto;
}
.mobile-nav.is-open { display: flex; }
.mobile-nav__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 32px; }
.mobile-nav__close {
  background: none; border: 1px solid rgba(255,255,255,.4); color: #fff;
  border-radius: var(--radius-card); padding: 10px 18px; font-size: 15px; font-weight: 600; cursor: pointer;
  min-height: 48px;
}
/* max-width:none, weil main.css jedes ul auf 66ch deckelt — das Menü stand
   dadurch auch bei 1000px Fenster nur 668px breit, mit 34% leerer Fläche
   rechts daneben. */
.mobile-nav__list { list-style: none; margin: 0 0 32px; padding: 0; max-width: none; }
.mobile-nav__list a {
  display: block; color: #fff; text-decoration: none; font-size: 22px; font-weight: 700; letter-spacing: -0.015em;
  padding: 14px 0; border-bottom: 1px solid rgba(255,255,255,.12);
}
.mobile-nav__list a:hover { color: var(--orange); }
/* Der Burger ersetzt die Navigation schon ab 1024px abwärts (siehe die
   Rechnung an .nav). Als eine Spalte war das Menü dort 2.263px hoch: 36 Links,
   „Kontakt" zweieinhalb Bildschirme tief. Ab 768px ist Platz für zwei Spalten;
   break-inside hält jede Rubrik samt Unterpunkten zusammen. Unter 768px bleibt
   es einspaltig — dort ist die Fläche nicht da. */
@media (min-width: 768px) {
  .mobile-nav__list { columns: 2; column-gap: 48px; }
  .mobile-nav__list > li { break-inside: avoid; }
}

/* ---------- 7. Hero (C2) ---------- */
/* Die Hero-Bahnen laufen auf demselben Rhythmus wie jede andere Sektion — vor
   der Konsolidierung trugen sie fünf eigene Werte (96/104, 124/72, 64/44,
   56/64, 56/48). Jetzt: lg für die tragende Bahn, md für die schlichte,
   sm für den Mini-Hero. */
.hero { padding: var(--section-md) 0; }

/* Split-Hero: verschränkte Achse. Das Medium beginnt oberhalb der Headline
   und endet unterhalb der CTAs, greift also vertikal in den Textblock statt
   parallel danebenzustehen. Die Verschränkung passiert nur auf der Höhen-
   achse, deshalb funktioniert sie mit Foto wie mit Infografik.
   Die obere Luft (section-lg) trägt den Versatz des Mediums. */
.hero--split { padding: var(--section-lg) 0 var(--section-sm); }
.hero--split .hero__grid {
  display: grid;
  grid-template-columns: 54fr 46fr;
  gap: 56px;
  align-items: start;
}
/* Untergrenze als min() aus demselben Grund wie bei der Basis-H1 (Abschnitt 2):
   ein Schlüsselwort im .swoosh darf nicht umbrechen und wird bei fester
   Untergrenze irgendwann breiter als der Container. „dauerhaft halten" passt
   heute mit 245px in die 280px bei 320px Fenster — ein längeres Wort nicht
   mehr. 8vw erreicht 30px bei 375px Fensterbreite, darüber ändert sich nichts. */
.hero--split h1 { font-size: clamp(min(30px, 8vw), 3.5vw, 44px); max-width: 26ch; }
.hero__media { margin-top: -64px; }
/* Echte Fotos im Kopf (figure.hero__media mit <img>): Der Browser gibt <figure>
   seitlich 40px Rand, das Foto stand dadurch eingerückt neben Text und Knöpfen.
   Bündig mit der Spalte und mit den runden Ecken der Karten (10.10.2026). */
figure.hero__media:not(.img-placeholder) { margin-left: 0; margin-right: 0; }
figure.hero__media:not(.img-placeholder) > img { display: block; width: 100%; height: auto; border-radius: var(--radius-card); }
/* Foto-Slots bringen nur die 220px Grundhöhe des Platzhalters mit und würden
   weit oberhalb der CTAs enden. Dann greift nichts ineinander. Infografiken
   bringen ihre Höhe selbst mit und brauchen die Regel nicht. */
.img-placeholder.hero__media { min-height: 460px; }
/* Ab 860px wird der Split einspaltig — deshalb hier feste Stufen der
   Spacing-Skala statt der Rhythmus-Tokens: die wechseln erst bei 767 und
   würden dem Tablet die 128px-Bahn des Desktops lassen. */
@media (max-width: 860px) {
  .hero { padding: var(--space-7) 0 var(--space-8); }
  .hero--split { padding: var(--space-7) 0; }
  .hero--split .hero__grid { grid-template-columns: 1fr; gap: 32px; }
  .hero--split h1 { max-width: none; }
  .hero__media { margin-top: 0; }
  .img-placeholder.hero__media { min-height: 260px; }
}
.hero h1 { margin-bottom: 22px; }
.hero .lead { margin-bottom: var(--space-6); font-size: var(--text-lead); }
.hero__ctas { margin-bottom: var(--space-2); }

/* Mini-Hero (Tool-/Funnel-Seiten) */
.hero--mini { padding: var(--section-sm) 0 var(--space-7); }

/* ---------- 8. Trust-Leiste (C3) ---------- */
.trust-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  align-items: center;
  margin-top: 36px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  list-style: none;
  padding-left: 0;
}
.trust-bar li {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}
.trust-bar li::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--navy);
  opacity: .3;
  flex: none;
}
.section--navy .trust-bar { border-top-color: rgba(255,255,255,.18); }
.section--navy .trust-bar li { color: #9FB8CE; }

/* Belege als Tags an der Haarlinie (C3 im Hero) --------------------------
   Im Hero verankern die Belege die Komposition nach unten: eine Zeile von
   Kante zu Kante, gleich in Split- und Mini-Hero. Die Linie ist die
   Aufhängung, die Belege hängen als Täfelchen daran.

   Fläche ist das blue-10 der Signature-Grafik (--navy-soft), damit Hero-Bild
   und Belegzeile dasselbe Blau teilen; Schrift im Markenblau, 700 — so lesen
   sie sich als Auszeichnung statt als Fußnote.

   padding-top: 0 ist der Kern: nur so berühren die Täfelchen die Linie
   wirklich. Oben bleiben die Ecken eckig — dort sitzt die Aufhängung —,
   unten sind sie gerundet. Kein Schatten, kein Rahmen, kein Verlauf.

   Die Täfelchen ziehen sich über die ganze Containerbreite: erstes links,
   letztes rechts bündig, der Rest gleichmäßig dazwischen. Gleich breite
   Rasterspalten wären hier falsch, weil die Belege sehr unterschiedlich lang
   sind — der Abstand würde ungleich (Rest der Spalte + gap). space-between
   mit flex verteilt den Rest gleichmäßig, also sind die sichtbaren Lücken
   gleich. Das gap ist nur die Untergrenze für den Umbruchfall.

   Kein Punkt-Marker: die Verteilung gliedert hier schon.
   Voraussetzung im Markup: das <ul> steht direkt im .container, nicht in
   einer max-width-Spalte — sonst ist die Zeile nicht randbündig.

   Gilt auf allen 35 Hero-Seiten. Außerhalb des Heros gibt es die Leiste
   nicht; die Basis-Regeln oben (grau, 600, Punkt-Marker) bleiben für den
   Fall, dass eine künftige Sektion sie doch braucht. */
.hero .trust-bar {
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px;
  margin-top: 56px;
  padding-top: 0;
  border-top-color: var(--line-strong);
  max-width: none;   /* main.css deckelt ul auf 66ch */
}
.hero .trust-bar li {
  background: var(--navy-soft);
  color: var(--navy);
  font-weight: 700;
  font-size: var(--text-eyebrow);
  line-height: 1.3;
  padding: 9px 14px 10px;
  border-radius: 0 0 var(--radius-input) var(--radius-input);
}
.hero .trust-bar li::before { display: none; }
@media (max-width: 860px) {
  .hero .trust-bar { margin-top: 36px; }
}
/* Auf dem Handy kippt die Aufhängung um 90°: die Haarlinie steht links, die
   Täfelchen hängen einzeln daran. Grund: „1.700+ Bewertungen (ProvenExpert)"
   braucht allein 256px, vier Belege brechen dort ohnehin zu vier Zeilen um.
   An einer waagerechten Linie berührt dann nur das erste Täfelchen die Linie
   und der Rest hängt in der Luft — an der senkrechten Linie hängen alle vier.
   Entsprechend wandert die eckige Kante von oben nach links: dort sitzt jetzt
   die Aufhängung, rechts sind die Ecken gerundet. */
@media (max-width: 767px) {
  .hero .trust-bar {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 6px;
    border-top: none;
    /* 3px statt 1px: dasselbe optische Gewicht wie die waagerechte Haarlinie.
       Ein 1px-Strich über 154px Höhe, direkt neben der hellblauen Tag-Kante,
       verschwindet — quer über 1180px trägt er. Denselben Schluss zieht der
       senkrechte Balken im FAQ (.faq summary::before, 3px, --line-strong). */
    border-left: 3px solid var(--line-strong);
    padding-top: 0;
  }
  .hero .trust-bar li {
    padding: 8px 12px 9px;
    border-radius: 0 var(--radius-input) var(--radius-input) 0;
  }
}

.trust-inline { font-size: 14px; color: var(--muted); }
/* Zentriert steht die Zeile immer als Nachsatz unter einem Block (Funnel-Box,
   CTA-Reihe). Der Abstand gehoert deshalb an die Klasse, nicht an die
   Einbaustelle — vorher standen dort 20, 24 und 28px nebeneinander. */
.center.trust-inline { margin-top: 24px; }
.trust-inline strong { color: var(--navy); }

/* ---------- 8a. Belegleiste mit Icons (Zoho-App-Seiten) ----------
   Gleiche ROLLE wie .trust-bar (Belege unter dem Hero), reichere Form: Icon,
   grosser Wert, Beschriftung. Warum eine Variante und keine Aenderung an
   .trust-bar: die schlichte Form steht auf 44 Seiten und soll dort bleiben —
   dort sind es Stichworte, hier sind es Zahlen, die getragen werden muessen.

   ACHTUNG Icons: docs/design-system.md schliesst ein Icon-Set aus („neue
   Gestaltungsarbeit ohne Anlass"). Der Anlass ist da, die Ausnahme gilt aber
   NUR fuer diese Leiste. Die Icons liegen als <img> in assets/img/icons/ und
   tragen ihre Farben selbst (Navy-Kontur, oranger Akzent) — sie sind deshalb
   nicht ueber CSS einfaerbbar, was hier gewollt ist: zwei Toene, fix.

   Die Selektoren nennen BEIDE Klassen (.trust-bar.trust-bar--belege). Das ist
   kein Schmuck: .hero .trust-bar li traegt zwei Klassen und schlaegt eine
   einklassige Regel unabhaengig von der Reihenfolge. Mit zwei Klassen steht es
   gleich, und der spaetere Block — dieser — gewinnt. So faellt das
   Taefelchen-Bild des Heros weg (Flaeche, Rundung, Fettung): hier gliedern
   Trennlinien, keine Kacheln. */
.trust-bar.trust-bar--belege {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 20px 0;
  align-items: stretch;
  justify-content: initial;
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  border-left: 0;
  max-width: none;
}
.trust-bar.trust-bar--belege li {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Rechts 10 statt 16px: „Weiterempfehlung" (13px, 114px breit) muss ab
     1180px Viewport in die Textspalte passen, sonst wird Feld 4 dreizeilig.
     Links bleiben 16px, damit die Icons an ihrer Stelle stehen. Die Regeln
     für 1024px und 767px setzen ihre Abstände selbst und bleiben, wie sie sind. */
  padding: 2px 10px 2px 16px;
  border-left: 1px solid var(--line);
  border-radius: 0;
  background: none;
  font-size: inherit;
  font-weight: 400;
  line-height: 1.3;
  color: var(--ink);
}
/* Der Punkt der Basis-Variante entfaellt — hier traegt das Icon. */
.trust-bar.trust-bar--belege li::before { content: none; display: none; }
/* Trennlinie entfaellt in der ersten Spalte. Weil die Spaltenzahl je
   Breakpoint wechselt, steht die Ausnahme dreimal da — einmal je Raster. */
.trust-bar.trust-bar--belege li:nth-child(6n + 1) { border-left: 0; padding-left: 0; }

.beleg__icon { width: 40px; height: 40px; flex: none; }
.beleg__text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* 19px statt --text-h3: der Wert soll auffallen, aber neben dem 40px-Icon
   keine zweite Ueberschrift werden. */
.beleg__wert {
  font-size: var(--text-lead);
  font-weight: 700;
  color: var(--navy);
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.beleg__label { font-size: var(--text-eyebrow); color: var(--muted); line-height: 1.3; }
/* Der erste Beleg ist ein Link (seit 04.10.2026): „Premium“ auf die
   Partnerseite, „ISO 9001“ auf die Zertifikate. Der Link uebernimmt das
   Flex-Layout des Listenpunkts, damit Icon und Text an ihrer Stelle bleiben.
   Unterstrichen wird erst bei Hover und Fokus, die Leiste soll ruhig bleiben. */
.beleg__link { display: flex; align-items: center; gap: 12px; min-width: 0; color: inherit; text-decoration: none; }
.beleg__link:hover .beleg__wert,
.beleg__link:focus-visible .beleg__wert { text-decoration: underline; text-underline-offset: 3px; }

.section--navy .trust-bar.trust-bar--belege li { border-left-color: rgba(255, 255, 255, .18); }
.section--navy .beleg__wert { color: #fff; }
.section--navy .beleg__label { color: #9FB8CE; }

@media (max-width: 1024px) {
  .trust-bar.trust-bar--belege { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .trust-bar.trust-bar--belege li:nth-child(6n + 1) { border-left: 1px solid var(--line); padding-left: 16px; }
  .trust-bar.trust-bar--belege li:nth-child(3n + 1) { border-left: 0; padding-left: 0; }
}
@media (max-width: 767px) {
  /* Der Hero stellt seine Belegleiste hier auf eine senkrechte Linie um
     (Abschnitt 8). Fuer diese Variante gilt das nicht — sie bleibt ein
     Raster an der waagerechten Linie. */
  .trust-bar.trust-bar--belege {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px 0;
    border-top: 1px solid var(--line);
    border-left: 0;
    padding-top: 22px;
    margin-top: 36px;
  }
  .trust-bar.trust-bar--belege li:nth-child(3n + 1) { border-left: 1px solid var(--line); padding-left: 14px; }
  .trust-bar.trust-bar--belege li:nth-child(2n + 1) { border-left: 0; padding-left: 0; }
  .trust-bar.trust-bar--belege li { padding: 2px 10px 2px 14px; gap: 10px; }
  .beleg__icon { width: 34px; height: 34px; }
  /* 17px: bei zwei Spalten steht „1.738 Bewertungen" sonst auf drei Zeilen. */
  .beleg__wert { font-size: 17px; }
  /* hyphens: manual (Standardwert, hier nur zur Klarstellung): Getrennt wird
     ausschliesslich an den &shy;-Stellen im Markup — Weiter·emp·fehlung,
     Proven·Expert, Förder·fähig. Vorher stand hier hyphens: auto gegen das
     inzwischen entfallene „Zoho-Zertifizierungen"; der Browser setzte damit
     eigene Trennstellen und brach „empfeh·lung" statt „emp·fehlung".
     overflow-wrap bleibt als Notnagel: Es greift nur, wenn ein Wort sonst
     ueberlaufen wuerde. */
  .beleg__wert, .beleg__label { overflow-wrap: break-word; hyphens: manual; }
}

/* ---------- 9. Karten ---------- */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 28px;
}
a.card, .card--link { display: block; text-decoration: none; color: inherit; }

/* Hover für weiße Karten mit Haarrahmen -----------------------------------
   Ein Verhalten für alle Karten-Bausteine mit weißem Grund und dünner Linie,
   statt einer Zusatzklasse (.card--interactive), die auf der Hälfte der Seiten
   vergessen wurde — auf ueber-uns hoben dieselben Karten nicht ab wie auf
   leads-qualifizieren. Neuer Karten-Baustein mit weißem Grund: hier in die
   Liste eintragen, keine eigene Hover-Regel schreiben.
   Ausgenommen ist .card--soft (getönt, rahmenlos) und das Tabpanel des
   KI-Flows: das ist keine anfassbare Karte, sondern der Inhalt der Umschaltung. */
.card:not(.card--soft),
.news-card,
.stufe-card {
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.card:not(.card--soft):hover,
.news-card:hover,
.stufe-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card);
  border-color: var(--line-strong);
}
.ki-flow__detail .card:hover { transform: none; box-shadow: none; border-color: var(--line); }
/* Auf getönter Fläche trägt die Karte ohne Rahmen (siehe Regel weiter unten) —
   beim Hover darf dort keine Linie auftauchen. Muss nach der KI-Flow-Ausnahme
   stehen, sonst holt die sich auf getöntem Grund die Linie zurück. */
.section--soft .card:hover,
.section--soft .news-card:hover,
.section--soft .stufe-card:hover { border-color: transparent; }
.card h3 { margin-bottom: 10px; }
/* Chip als Auszeichnung über der Kartenüberschrift: inline-block erzeugt von
   sich aus keinen Abstand nach unten, die Pille klebt sonst an der Headline. */
.card > .chip { margin-bottom: 12px; }
.card p:last-child { margin-bottom: 0; }

.card--soft { background: var(--navy-soft); border-color: transparent; box-shadow: none; }

/* Auf getönter Fläche trägt die weiße Karte selbst — der Rahmen entfällt, ein
   Haarschatten hält die Kante. Eine Regel für alle Flächen-Bausteine statt
   zehn wörtlich gleicher Blöcke an zehn Stellen der Datei. Neuer Baustein
   auf getönter Fläche: hier in die Liste, keine elfte Regel. */
.section--soft .card,
.section--soft .stufe-card,
.section--soft .weiche__card,
.section--soft .tool-teaser,
.section--soft .faq details,
.section--soft .faq-aside,
.section--soft .news-card {
  border-color: transparent;
  box-shadow: var(--shadow-hairline);
}

/* Karte mit Link am Fuß ---------------------------------------------------
   Für Kartenraster, deren Texte unterschiedlich lang sind. Vorher hing der
   Link direkt unter dem Text und saß dadurch je Karte auf einer anderen
   Höhe (auf leistungen.html 31 bis 101px über dem Kartenboden). Jetzt ist
   die Karte ein Flex-Container und der Link schiebt sich per
   margin-top:auto an den Boden. Rasterzellen einer Zeile sind gleich hoch,
   also liegen die Links auf einer Grundlinie, egal wie lang der Text ist.

   Zweite Voraussetzung ist Breite: der Link "Anfrage im Erstgespräch →"
   ist 194px breit und brach in den 202px Inhaltsbreite eines 4-Spalten-
   Rasters immer um. Solche Karten gehören darum in .grid-2, nicht .grid-4. */
.card--cta { display: flex; flex-direction: column; }
/* Die Karten-Geometrie sitzt am Ort, nicht am Button: der Arrow-Button steht
   auch außerhalb von Karten (Hero, Glossar, freie Absätze) und darf dort keine
   18px Kopfpolster mitbringen.
   Muss blockartig sein, sonst wirkt padding-top an einem Inline-Element nicht
   auf die Zeilenhöhe und der Link überlappt den Text darüber. In .card--cta
   blockifiziert der Flex-Container ihn ohnehin, in einer Karte ohne Flex nicht. */
.card .btn-arrow,
.stufe-card .btn-arrow,
.glossar__panel .btn-arrow {
  display: inline-block;
  align-self: flex-start;
  margin-top: auto;
  padding-top: 18px;
}

/* ---------- 10. Stufen-Kette (C5) ---------- */
.stufen-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Alle Zeilen so hoch wie die höchste Karte, statt jede Zeile für sich.
     Damit sind alle neun Karten gleich hoch — ohne feste Pixelhöhe, die
     beim ersten längeren Text wieder überläuft. */
  grid-auto-rows: 1fr;
  gap: 16px;
  counter-reset: stufe;
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
}
/* Drei Spalten hielten bisher bis 767px. Gemessen bei 820px: 256px Karte
   minus 32px Badge und 14px Lücke = 168px Textspalte — jeder Stufentitel
   zweizeilig, jede Unterzeile drei­zeilig. Das ist der Kern-Baustein der
   Startseite, er darf nicht als Textwand lesen. Zwei Spalten geben ab 1024px
   wieder 300–440px pro Karte; Stufe 9 steht allein in der letzten Zeile,
   was bei einer numerierten Kette als Abschluss und nicht als Lücke liest. */
@media (max-width: 1024px) { .stufen-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px)  { .stufen-grid { grid-template-columns: minmax(0, 1fr); } }
.stufe-card {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  /* Die Zelle wird vom Raster gestreckt, der Link darin nicht von allein. */
  height: 100%;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 20px;
  text-decoration: none;
  color: inherit;
  /* Hover: gemeinsame Regel in Abschnitt 9 (Karten) */
  margin: 0;
}
.stufe-card__num {
  flex: none;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--navy-soft);
  color: var(--navy);
  font-weight: 700;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s ease, color .2s ease;
}
.section--soft .stufe-card__num { background: #fff; box-shadow: inset 0 0 0 1px var(--line); }
/* Ziffer auf Orange anthrazit wie beim .btn--primary — Weiss auf #FF940A
   liegt bei 2,1:1. Gilt gleichlautend für .steps li::before. */
.stufe-card:hover .stufe-card__num { background: var(--orange); color: var(--ink); box-shadow: none; }
.stufe-card__title { font-weight: 600; color: var(--navy); display: block; letter-spacing: -0.01em; }
.stufe-card__text { font-size: 14px; color: var(--muted); display: block; margin-top: 2px; }

/* ---------- 11. Reifegrad-Weiche (C6) / Weg-Weiche ---------- */
.weiche { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
/* Die Weiche ist eine Entscheidung zwischen gleichwertigen Wegen — 2+1 würde
   einen davon zum Nachzügler machen. Deshalb kein Zwischenschritt, sondern
   der Umbruch eine Stufe früher: bei 900px standen die drei Spalten auf 262px
   (sieben Zeilen à 25 Zeichen), bei 1024px sind es noch 319px. Ab 1024px
   also gestapelt, drei Wege untereinander, jeder mit voller Breite. */
@media (max-width: 1024px) { .weiche { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 860px) { .weiche { grid-template-columns: minmax(0, 1fr); } }
.weiche__card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 32px 28px;
  display: flex;
  flex-direction: column;
}
.weiche__card .btn { margin-top: auto; align-self: flex-start; }

/* ---------- 11a. Wege-Paar (.weiche--paar) ----------
   Genau ZWEI gleichwertige Alternativen als Kontrastpaar: eine Karte in der
   hellen Blaufläche, die andere im dazugehörigen Orange. Für drei Wege nicht
   verwenden — drei Tönungen wären ein Farbcode, den niemand mitliest, und der
   Baustein hat nur zwei Farben.

   Die Zuordnung ist über ALLE Seiten dieselbe und darf nicht seitenweise
   kippen, sonst bedeutet die Farbe nichts mehr:
     blau   = der Weg, den du selbst gehst / das Laufende / das Kleinere
     orange = der Weg, bei dem wir umsetzen / das Zusätzliche / das Größere
   Ziffer 1/2 in der weißen Kachel statt Piktogramm: die Nummer sagt sofort
   „zwei Möglichkeiten", ein Icon müsste erst gedeutet werden.

   Bahn: am stärksten auf .section--navy (dort leuchten die Karten heraus).
   Steht die Section direkt vor dem .cta-block, bleibt die Bahn hell — zwei
   dunkle Bänder hintereinander mauern das Seitenende zu; nirgends sonst auf
   der Seite folgt navy auf navy. Auf heller Bahn stimmen die Textfarben von
   selbst, auf dunkler holen die .section--navy-Regeln unten sie zurück. */
.weiche--paar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Eigene Media-Query statt der Liste oben: die Regel darüber steht NACH
   jener Query und würde sie sonst überschreiben (gleiche Spezifität). */
@media (max-width: 860px) { .weiche--paar { grid-template-columns: minmax(0, 1fr); } }
.weiche--paar .weiche__card {
  position: relative; overflow: hidden;
  border: 0; padding: 32px 28px 28px;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), background-color .35s var(--ease);
}
.weiche__card--blau   { background: var(--blau-flaeche); }
.weiche__card--orange { background: var(--orange-flaeche); }
/* Stapelkontext für den Inhalt — der Schleier bleibt ausgenommen, ein
   position: relative nähme ihm sonst das absolute Layout. */
.weiche--paar .weiche__card > *:not(.weiche__schleier) { position: relative; }

/* Farbschleier oben rechts: nimmt der großen Tönung die Flachheit und atmet
   beim Hover. Radiengradient statt Bild, damit nichts nachgeladen wird. */
.weiche__schleier {
  position: absolute; top: -90px; right: -90px;
  width: 260px; height: 260px; border-radius: 50%;
  pointer-events: none;
  transition: transform .5s var(--ease);
}
.weiche__card--blau .weiche__schleier   { background: radial-gradient(circle, rgba(30, 73, 117, .20) 0%, rgba(30, 73, 117, 0) 70%); }
.weiche__card--orange .weiche__schleier { background: radial-gradient(circle, rgba(255, 148, 10, .30) 0%, rgba(255, 148, 10, 0) 70%); }

.weiche__nr {
  width: 48px; height: 48px; border-radius: var(--radius-card);
  display: grid; place-items: center;
  background: var(--paper);
  font-size: 21px; font-weight: 700; line-height: 1;
  margin-bottom: 18px;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.weiche__card--blau .weiche__nr   { color: var(--navy); }
.weiche__card--orange .weiche__nr { color: var(--orange); }

/* Feinabdruck am Fuß der Karte, durch eine Kontur in Kartenfarbe abgesetzt. */
.weiche__fein {
  margin: 0 0 22px; padding-top: 16px;
  border-top: 1px solid;
  font-size: var(--text-small); color: var(--muted); max-width: none;
}
.weiche__card--blau .weiche__fein   { border-top-color: var(--blau-flaeche-linie); }
.weiche__card--orange .weiche__fein { border-top-color: var(--orange-flaeche-linie); }

/* Haken in Kartenfarbe. Drei Klassen, damit die Regel die Orange-Haken aus
   Abschnitt 26 (.section--navy .check-list) schlägt — die steht später. */
.weiche--paar .weiche__card--blau .check-list li::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%231E4975' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.weiche--paar .weiche__card--orange .check-list li::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%23B65E00' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Textfarben in den hellen Karten auf dunkler Bahn zurückholen. */
.section--navy .weiche--paar h3 { color: var(--navy); }
.section--navy .weiche--paar p,
.section--navy .weiche--paar li { color: var(--ink); }
.section--navy .weiche--paar .eyebrow,
.section--navy .weiche--paar .weiche__fein { color: var(--muted); }
.section--navy .weiche--paar .btn--secondary { color: var(--ink); }

.weiche--paar .weiche__card:hover { transform: translateY(-5px); box-shadow: var(--shadow-float); }
.weiche__card--blau:hover   { background: var(--blau-flaeche-tief); }
.weiche__card--orange:hover { background: var(--orange-flaeche-tief); }
.weiche--paar .weiche__card:hover .weiche__schleier { transform: scale(1.25); }
.weiche--paar .weiche__card:hover .weiche__nr { transform: translateY(-2px); box-shadow: var(--shadow-hairline); }
.weiche--paar .weiche__card:hover .btn--secondary { background: var(--orange); color: var(--ink); }
@media (max-width: 767px) {
  .weiche--paar .weiche__card { padding: 26px 20px 24px; }
  .weiche--paar .weiche__card .btn { width: 100%; text-align: center; }
}

/* ---------- 13. Tool-/Funnel-Teaser (C8) ---------- */
.tool-teaser {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 28px;
  display: flex;
  flex-direction: column;
}
/* wrap, weil „PROZESSKOSTENRECHNER" mit Versalabstand 175px braucht und der
   Minuten-Chip weitere 87px: bei 320px Fenster bleiben im Karteninneren 224px,
   der Chip stand dadurch über der Kartenkante. Umbruch statt Überstand. */
.tool-teaser__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px 12px; margin-bottom: 14px; }
.tool-teaser__name { font-size: 12px; font-weight: 600; letter-spacing: .01em; color: var(--muted); }
/* Steht die Karte direkt unter der H1, ohne Abschnittsüberschrift darüber, ist
   ihr Titel eine H2 (/sbr/, seit 10.10.2026), sonst stünde eine H3 ohne H2.
   Er sieht trotzdem aus wie der H3-Titel auf /tools/: Die Karte bestimmt die
   Größe, nicht die Gliederungsebene. */
.tool-teaser h2 { font-size: var(--text-h3); line-height: 1.2; }
.tool-teaser h2, .tool-teaser h3 { margin-bottom: 8px; }
.tool-teaser .btn { align-self: flex-start; margin-top: auto; }
/* Die fünfte Karte auf /tools/ (Fördermittel-Check, seit 09.10.2026) läuft über die volle Breite, statt allein in der
   letzten Reihe zu stehen. Einspaltig ist sie ohnehin so breit wie die anderen. */
.tool-teaser--breit { grid-column: 1 / -1; }

.chip {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 3px 12px;
  background: var(--navy-soft);
  color: var(--navy);
  white-space: nowrap;
}

.chip--outline { background: transparent; border: 1px solid var(--line-strong); color: var(--muted); }
.chip--success { background: #E7F4EC; color: var(--success); }

/* ---------- 14. FAQ-Akkordeon (C9) ----------
   Zweispaltig: Fragen links in Lesebreite, rechts die Anschlusshandlung.
   Vorher war .faq ein 720px-Block in einem 1160px-Container, die rechten
   440px hatten keine Aufgabe und die Section wirkte dadurch leer.
   Beide Marker laufen über Pseudo-Elemente, das Markup im <summary> bleibt
   also unangetastet: Frage rein, fertig. */
.faq-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 64px;
  align-items: start;
}

.faq details {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  margin-bottom: 8px;
  transition: box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.faq details:hover { border-color: var(--line-strong); }
.faq details[open] { box-shadow: var(--shadow-card); }

/* Ruhiges Auf- und Zuschieben statt hartem Umspringen: die Höhe wandert
   über ::details-content, `interpolate-size` macht das Schlüsselwort `auto`
   dafür überhaupt erst interpolierbar (lokal auf .faq gesetzt, nicht global).
   Kein JS: Browser ohne ::details-content klappen wie bisher hart um.
   .45s ist die Leitgeschwindigkeit des Akkordeons — Balken und Plus laufen
   unten mit derselben Dauer, sonst steht das Zeichen vor der Antwort still. */
.faq { interpolate-size: allow-keywords; }
.faq details::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size .45s var(--ease), content-visibility .45s allow-discrete;
}
.faq details[open]::details-content { block-size: auto; }
/* Der globale Reduced-Motion-Reset trifft nur *, ::before und ::after —
   ::details-content muss hier einzeln ruhiggestellt werden. */
@media (prefers-reduced-motion: reduce) {
  .faq details::details-content { transition: none; }
}
/* Auf getönter Fläche trägt die weiße Karte selbst, der Rahmen entfällt.
   Gleiche Konvention wie bei .card in Abschnitt 12. */
.section--soft .faq details:hover { border-color: transparent; }
.section--soft .faq details[open] { box-shadow: var(--shadow-card); }

.faq summary {
  list-style: none;
  cursor: pointer;
  font-weight: 600;
  font-size: 17px;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--navy);
  padding: 20px 52px 20px 42px;
  position: relative;
  transition: color .15s ease;
}
.faq summary:hover { color: var(--navy-deep); }
.faq summary::-webkit-details-marker { display: none; }
/* Die Frage ist seit 06.10.2026 eine H3 (O68): für Google und KI-Systeme eine
   Unterüberschrift der FAQ, fürs Auge dieselbe Zeile wie vorher. */
.faq summary .faq__frage {
  font: inherit; letter-spacing: inherit; color: inherit; margin: 0; display: inline;
  text-wrap: inherit; font-feature-settings: inherit; overflow-wrap: inherit;
}
.faq summary:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; border-radius: var(--radius-card); }

/* Balken links: wächst beim Öffnen nach unten, also in die Richtung, in die
   sich die Antwort öffnet. Gestaucht über scaleY, nicht über height, damit
   die Zeile beim Umschalten kein Layout neu rechnet. */
.faq summary::before {
  content: "";
  position: absolute;
  left: 22px; top: 22px;
  width: 3px; height: 26px;
  border-radius: 2px;
  background: var(--line-strong);
  transform: scaleY(.69);
  transform-origin: top center;
  transition: background .2s var(--ease), transform .45s var(--ease);
}
.faq summary:hover::before { background: var(--navy); }
.faq details[open] summary::before { background: var(--orange); transform: scaleY(1); }

/* Plus dreht zum Kreuz. */
.faq summary::after {
  content: "";
  position: absolute;
  right: 22px; top: 50%;
  width: 14px; height: 14px;
  transform: translateY(-50%);
  background:
    linear-gradient(currentColor, currentColor) center / 14px 1.5px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1.5px 14px no-repeat;
  color: var(--muted);
  transition: transform .45s var(--ease), color .15s ease;
}
.faq summary:hover::after { color: var(--navy); }
.faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); color: var(--orange); }

.faq .faq__answer { padding: 0 24px 22px 42px; color: var(--ink); }
.faq .faq__answer p:last-child { margin-bottom: 0; }

/* Rechte Spalte: exakt so hoch wie ihr Inhalt. Kein sticky und kein
   align-self: stretch, die Section ist kürzer als ein Fenster, die Leere
   wäre damit nur von links nach rechts gewandert. */
.faq-aside {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 26px 28px;
}

/* Die Kanäle, die der CTA-Block darunter nicht anbietet, als Textlinks —
   der Button am Kartenfuß führt bewusst woanders hin (Kontaktseite), nicht
   noch einmal ins Erstgespräch. */
.faq-aside__contact { list-style: none; padding: 0; margin: 0; }
.faq-aside__contact li { margin: 0; border-top: 1px solid var(--line); }
.faq-aside__contact a {
  display: block;
  padding: 11px 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--navy);
  text-decoration: none;
}
.faq-aside__contact a:hover { color: var(--orange-text, #B65E00); }
.faq-aside__contact a:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* Variante mit Überschrift in der linken Spalte (alle FAQ-Seiten) ---------
   Die Fragen tragen die linke Spalte allein, rechts stehen H2, Einordnung
   und die Ansprechpartner-Karte untereinander. Bewusst drei Grid-Kinder
   statt zwei Spalten-Wrappern: nur so fällt die Karte auf dem Handy hinter
   die Fragen — mit einem gemeinsamen Wrapper stünde sie über ihnen. */
.faq-layout--split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  /* Zeilenabstand = 48px Kugel-Überstand + 24px Luft, sonst schöben sich die
     Kugeln in die letzte Zeile des Einordnungstextes. */
  gap: 72px 56px;
}
.faq-layout--split > .faq       { grid-column: 2; grid-row: 1 / span 2; }
.faq-layout--split > .faq-head  { grid-column: 1; grid-row: 1; }
.faq-layout--split > .faq-aside { grid-column: 1; grid-row: 2; }
.faq-head h2 { margin-bottom: 14px; }
.faq-head p:last-child { margin-bottom: 0; }

/* Ansprechpartner-Karte: die beiden Kugeln sitzen zur Hälfte über der
   Kartenkante (96px Avatar, also -48px). Der 5px-Ring ist die Sektionsfläche
   selbst, sonst schnitte die Kartenkante durch die Kugeln. */
.faq-aside--team { text-align: center; padding-top: 0; }
.faq-aside__people { display: flex; justify-content: center; margin: -48px 0 12px; }
/* Der Ring ist die Fläche, auf der die Karte liegt — weiß auf .section,
   getönt auf .section--soft. Gleiche Fallunterscheidung wie bei den Karten
   in Abschnitt 12; mit nur einem Wert schnitte auf der jeweils anderen
   Fläche ein Kreisrand durch die Kugeln. */
.faq-aside__people .img-placeholder--avatar { box-shadow: 0 0 0 5px var(--paper); }
.section--soft .faq-aside__people .img-placeholder--avatar { box-shadow: 0 0 0 5px var(--surface-2); }
.faq-aside__people .img-placeholder--avatar + .img-placeholder--avatar { margin-left: -18px; }
/* Fünf Gesichter fürs Erstgespräch (Julia, Manuela, Mirlinda, Florian und Thomas, Auftraggeber
   06.10.2026): mit 96px wären das 408px, breiter als die Karte zwischen 861 und 1200px und auf dem
   Handy. Die Kugel folgt deshalb der Kartenbreite (fünf Kugeln mit 20 % Überlappung brauchen 4,2
   Kugelbreiten, 4,4 lassen Luft für den Ring), höchstens 96px; der Überstand bleibt die halbe Kugel. */
.faq-aside__people--fuenf { --kugel: min(96px, calc(100% / 4.4)); margin-top: calc(var(--kugel) / -2); }
.faq-aside__people--fuenf .img-placeholder--avatar { flex: none; width: var(--kugel); height: auto; aspect-ratio: 1; }
.faq-aside__people--fuenf .img-placeholder--avatar + .img-placeholder--avatar { margin-left: calc(var(--kugel) * -0.2); }
.faq-aside--team .team-card__role { display: block; margin-bottom: 18px; }
/* Der Button trägt den Fuß der Karte: volle Kartenbreite, damit er nicht als
   dritter Kontaktkanal zwischen den Textlinks steht. */
.faq-aside--team .btn { display: block; margin-top: 18px; }
/* /kontakt/ Abschnitt 3: dieselbe Karte rechts neben dem Formular, darunter
   die Anschrift. Die Kugeln ragen 48px über die Karte; dieselbe Luft darüber
   setzt ihre Oberkante auf die Oberkante des Formulars. */
.kontakt-spalte > .faq-aside--team { margin-top: 48px; }
.kontakt-spalte > * + * { margin-top: 24px; }

@media (max-width: 860px) {
  .faq-layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  /* Einspaltig übernimmt wieder die DOM-Reihenfolge: H2, Fragen, Karte.
     Je Kind einzeln aufgehoben, weil `> *` eine Klasse weniger wiegt als
     `> .faq` und die Platzierung sonst stehen bliebe. */
  .faq-layout--split > .faq,
  .faq-layout--split > .faq-head,
  .faq-layout--split > .faq-aside { grid-column: auto; grid-row: auto; }
  .faq-layout--split { gap: 28px; }
  /* Der Kugel-Überstand braucht auch gestapelt seine 48px, sonst sitzt er
     auf der letzten Frage. Als Marge nur an der Karte statt als Zeilen-Gap,
     damit der Abstand H2 → Fragen bei 28px bleibt. */
  .faq-aside--team { margin-top: 44px; }
  /* Links Platz für den Marker, rechts für das Plus. Zusammen waren das 84px,
     die nicht mitschrumpfen: bei 320px Fenster blieben 196px für die Frage,
     und „EU-AI-Act-konform" schob die Box auf 328px. 66px lassen genug Luft
     für beide Zeichen, hyphens bricht das Kompositum statt den Kasten. */
  .faq summary { padding: 18px 38px 18px 28px; hyphens: auto; }
  .faq summary::before { left: 14px; top: 20px; }
  .faq summary::after { right: 14px; }
  .faq .faq__answer { padding: 0 16px 20px 28px; }
}

/* ---------- 15. Zitatfragment (/erstgespraech/) ----------
   Rest der früheren Case-Karte (C10), die übrigen Teile sind am 09.10.2026 entfallen. */
.case-card__quote { font-size: 16px; margin: 0; font-style: normal; }
.case-card__source { font-size: 13px; color: var(--muted); }

/* ---------- 16. CTA-Schluss-Block (C11) ---------- */
.cta-block {
  background: var(--navy);
  color: #fff;
  border-radius: 0;
  padding: var(--section-md) 0;
}
.cta-block h2 { color: #fff; }
.cta-block p { color: #D6E2EE; }
.cta-block__alt { margin-top: 28px; font-size: var(--text-small); }
/* Inline-Verweis im Satz auf dunkler Fläche — kein Arrow-Button, weil er
   mitten in einem Satz steht. */
.cta-block__alt a { color: #fff; font-weight: 600; text-decoration-color: rgba(255,255,255,.4); }
.cta-block__alt a:hover { color: #fff; text-decoration-color: #fff; }

/* ---------- 16a. CTA-Banner B1, C1 und D4-c (C11) ----------
   Die freigegebenen Bauformen aus
   _nicht-deployen/cta-banner-varianten.html (dort stehen alle Entwürfe,
   gesetzt sind A1, C1 und D4-c). Sie bedienen dieselbe Rolle wie der
   CTA-Schluss direkt darüber, stehen aber MITTEN in der Seite, wo ein Argument
   gerade fertig erzählt ist:
     A1    randlose Navy-Bahn mit Porträt, entfallen am 05.10.2026 (unten).
     C1    weisse Karte mit Geisterzahl   — wo eine Zahl oder Dauer sie trägt.
     D4-c  Navy-Karte, Bild über der Kante — wo Bild, Zitat UND Kennzahlen
           zusammen auftreten, also bei der Kundenstimme mit Beweiszahl.
   Der Abbinder .cta-block am Seitenende bleibt davon unberührt: er ist der
   Abschluss, kein Banner. Alle bewegen sich nur über .reveal, damit
   prefers-reduced-motion global mitgreift und keine Extraregel braucht.

   Ein Banner ist immer Fläche + Aussage + Handlung; die Bauformen unterscheiden
   sich nur darin, WAS die Aussage trägt. Deshalb die gemeinsame Basis: */
.cb { position: relative; overflow: hidden; }
.cb__inner { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; padding: 0 20px; }
.cb h2, .cb h3 { letter-spacing: -0.02em; }
/* Zwischen-Aufrufe tragen seit 06.10.2026 keine H2 mehr (O68, Auftraggeber):
   Google und KI-Systeme lasen jeden Aufruf als eigenes Kapitel. .cb__titel ist
   ein Absatz, der genau wie die H2 vorher aussieht; die Varianten unten
   (.cb--navy, .cb-b1, .cb-c1) nennen ihn neben h2. Das Schluss-Band
   (.cta-block) und „Zoho One, die Klammer“ auf /zoho-pakete/ behalten ihre H2. */
.cb__titel {
  color: var(--navy); font-size: var(--text-h2); line-height: 1.15; font-weight: 700;
  letter-spacing: -0.02em; margin: 0 0 16px; text-wrap: balance;
  font-feature-settings: "ss01" off; overflow-wrap: break-word;
}
.cb p { max-width: none; }         /* Abschnitt 2 deckelt p auf 66ch */
.cb .microcopy { margin-top: 12px; }
/* 56px statt var(--section-md): ein Banner sitzt innerhalb einer Seite und ist
   deshalb gedrängter als eine eigene Bahn — mit 96px liest er sich als Sektion. */
.cb--navy { background: var(--navy); color: #fff; padding: 56px 0; }
.cb--navy h2, .cb--navy h3, .cb--navy .cb__titel { color: #fff; }
.cb--navy p { color: #D6E2EE; }
.cb--navy .eyebrow { color: #9FB8CE; }
.cb--navy .microcopy { color: #9FB8CE; }
/* Karte — sitzt in einer normalen Sektion, nicht randlos. */
.cb--card { background: var(--paper); border-radius: var(--radius-card); box-shadow: var(--shadow-card); }
@media (max-width: 767px) { .cb--navy { padding: 40px 0; } }

/* .cb__bogen ist am 25.09.2026 entfallen — auf Wunsch des Auftraggebers und
   grundsaetzlich, nicht nur auf einer Seite. Es waren zwei quer durchs Banner
   laufende Kurven (orange 2,5px bei 32 % Deckkraft, weiss 1,5px bei 10 %).
   Die Deko-Ebene stand in 15 Seiten als <span class="cb__bogen"> im Markup und
   ist dort ebenfalls entfernt. Dieselben zwei Kurven lagen als
   .cta-block::before unter jedem Schluss-CTA — auch die sind weg, sonst waere
   die Geste auf derselben Seite einmal verworfen und einmal behalten worden.
   Wer sie zurueckholt, braucht beide Stellen. */
/* A1, die Navy-Bahn mit Porträt, ist am 05.10.2026 entfallen, ebenfalls auf
   Wunsch des Auftraggebers. Sie stand nur auf /kontakt/ („Wer antwortet“) und
   trug den orangen Logo-Bogen vor und hinter dem runden Foto, dazu einen
   Lichtkegel (.cb__glow) und einen pulsierenden Punkt (cb-puls). Der Bogen war
   die letzte Schmuckform dieser Art um ein Foto, alle übrigen Porträts sind
   schlichte runde Avatare. Wer ihn zurückholt, findet ihn im Git-Stand vor dem
   05.10.2026. */

/* Handlungsspalte: Knopf plus Microcopy untereinander, in C1 die zweite
   Rasterspalte. Ohne Familien-Präfix, weil sie mehreren Bauformen diente. */
.cb__tat { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }

/* --- B1 · Aussage: ein Satz, ein Knopf, Marker hinter dem Schlüsselwort ---
   Der Zwischen-CTA (Slot 6) aller Leistungsdetailseiten, siehe
   docs/leistungsseiten-struktur.md. Bewusst zentriert und ohne Bild: er sitzt
   auf der Seitenmitte zwischen Nutzen und Abgrenzung und darf dort nichts
   erklären, sondern nur abfangen.

   Der Marker ist der einzige Farbakzent und liegt HINTER der Schrift
   (z-index: -1 gegen .cb__inner mit isolation), nicht darauf: als Textfarbe
   wären #FF940A auf Navy 3,1:1 und damit unzulässig. Als Fläche unter weisser
   Schrift trägt Orange dagegen 8,4:1.

   Er läuft beim Einblenden von links auf — dieselbe Geste wie der
   Eyebrow-Strich, die Belege-Linie und der Swoosh unter der H1. Ausgelöst
   wird sie von .reveal.is-visible am Banner selbst, nicht von einem eigenen
   Beobachter. */
/* Mehr Luft als die 56px von .cb--navy: der Banner läuft über die volle
   Fensterbreite und ist der einzige Halt auf der Seitenmitte — mit
   Sektionspolsterung nimmt er den Raum ein, der zu dieser Rolle gehört.
   var(--section-md) statt eines eigenen Werts, weil die Tokens im
   767px-Breakpoint mitschalten: 96px am Desktop, 64px mobil, ohne zweites
   @media. Die Regel steht NACH .cb--navy und dessen 767px-Override, deshalb
   gewinnt sie bei gleicher Spezifität auf allen Breiten.
   Bewusst nur .cb-b1, nicht .cb--navy: Bis 05.10.2026 trug auch A1 auf
   /kontakt/ die Navy-Bahn, mit Porträt im Dreispalter und anderem
   Höhenbedarf. Heute ist B1 ihr einziger Verwender. */
.cb-b1 { text-align: center; padding: var(--section-md) 0; }
/* Der Stapelkontext stammt aus der Zeit des alten Markers (z-index: -1 hinter
   der Schrift). Er bleibt stehen, weil .cb__inner ohnehin ueber der Bahn
   liegen muss; schaden kann er nicht. */
.cb-b1 .cb__inner { isolation: isolate; }
/* 26ch, nicht 20ch: bei 20ch war der Überschriftenblock deutlich schmaler als
   der Absatz darunter (62ch auf 17px ≈ 527px; 20ch auf 40px ≈ 400px), die
   beiden Blöcke standen unterschiedlich breit übereinander. 26ch auf 40px
   trifft die Absatzbreite. Weil die Schrift per clamp mitschrumpft, wird der
   Deckel auf kleinen Breiten von allein enger — kein zweites @media.
   Wirkt auf alle Verwender: die längeren der neun Leistungs-Headlines
   (42–58 Zeichen) laufen damit auf zwei statt drei Zeilen. */
.cb-b1 h2, .cb-b1 .cb__titel { font-size: clamp(26px, 3.4vw, 40px); line-height: 1.18; max-width: 26ch; margin: 0 auto 14px; }
.cb-b1 p { max-width: 62ch; margin: 0 auto 24px; }
/* Das Schluesselwort trug bis 25.09.2026 einen eigenen Marker: einen orangen
   Vollton-Balken hinter der Schrift (.cb-b1__marker). Er ist gegen den
   .swoosh getauscht, der auf jeder Seite unter dem Schluesselwort der H1
   steht — damit gibt es im ganzen Projekt nur noch EINE Auszeichnung fuer
   Schluesselwoerter statt zweier, die sich aehnlich sehen.
   Der Kontrastgrund des alten Markers faellt damit weg und darf nicht
   zurueckkehren: Orange als Schriftfarbe auf Navy waere 3,1:1 und
   unzulaessig. Der Swoosh ist ein Strich UNTER dem Wort, keine Schriftfarbe —
   die Schrift bleibt weiss. */
.cb-b1__zeile { display: flex; flex-wrap: wrap; gap: 12px 16px; justify-content: center; align-items: center; }
@media (max-width: 767px) {
  /* Nebeneinander bleiben unter 767px zwei Knöpfe von je ~150px übrig — die
     Beschriftungen brechen dann mitten im Wort. Gestapelt volle Breite. */
  .cb-b1__zeile .btn { width: 100%; }
}

/* --- C1 · Geisterzahl im Hintergrund --- */
.cb-c1 { padding: 44px 40px; }
.cb-c1 .cb__inner { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 32px; align-items: center; padding: 0; }
/* Die Zahl ist Deko, keine Information — sie steht als Kontur hinter dem Text
   und ist aria-hidden. Die lesbare Zahl steht im Satz. */
.cb-c1__geist {
  position: absolute; right: -10px; top: 50%; transform: translateY(-50%);
  /* 150px statt 300px, und derselbe Wert für JEDEN Geist: bei 300px war die
     Kontur höher als die Karte und breiter als der freie Platz rechts, also
     oben, unten und links beschnitten — man sah Bruchstücke statt eines Werts.
     Bei 150px steht „−65 %", „100 %" oder „3 Min" vollständig da und bleibt
     trotzdem Hintergrund. Einheitlich, damit die Banner untereinander
     konsistent bleiben; die Werte sind unterschiedlich lang, die Schrift nicht.
     Auf Wunsch des Auftraggebers. */
  font-size: clamp(120px, 17vw, 220px); font-weight: 700; line-height: .8; letter-spacing: -0.05em;
  color: transparent; -webkit-text-stroke: 2px var(--line-strong);
  pointer-events: none; user-select: none;
  /* Sanft an beiden Enden: der Wert soll nicht mit einer harten Kontur anfangen
     und aufhören, sondern aus der Fläche kommen und wieder darin verschwinden.
     Kurze Zonen, sonst frisst der Verlauf die erste und letzte Ziffer — genau
     daran lag es, dass der Wert vorher (52 % Anlauf) unlesbar war.
     Asymmetrisch, weil die Enden es auch sind: links steht das Zeichen frei,
     da darf der Anlauf mit 20 % lang sein. Rechts läuft der Wert ohnehin über
     die Kartenkante hinaus, die Karte schneidet also mitten in die Zone — 10 %
     lassen an der Kante noch etwa 60 % Deckkraft übrig, damit dort ein weiches
     Ende steht und nicht der Rest verschwindet. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 20%, #000 90%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 20%, #000 90%, transparent 100%);
}
/* Wort-Geist („2 Min", „3 Min") statt reiner Zahl: Größe kommt unverändert von
   .cb-c1__geist, nur der Anschnitt rechts ist eigen. Bei „100 %" darf das
   Prozentzeichen an der Kartenkante auslaufen, das liest sich als Absicht. Ein
   Wort dagegen muss lesbar bleiben: −0,15em schneidet das „n" nach dem Bogen
   an, sodass der Ansatz des zweiten Beins noch steht — „Min" ist damit klar,
   der Anschnitt bleibt aber sichtbar Absicht. In em, damit das Verhältnis über
   die ganze clamp-Spanne stimmt (bei 150px sind das 22px, bei 96px 14px). */
.cb-c1__geist--wort { right: -0.15em; }
/* 30ch statt 22: die Aussage soll auf drei Zeilen laufen, nicht auf vier —
   der Platz dafür kommt von rechts, die Geisterzahl weicht per Maske aus.
   h2 mit, weil der Banner auf manchen Seiten die einzige Überschrift der
   Sektion trägt und dort keine Ebene übersprungen werden darf. */
.cb-c1 h2, .cb-c1 h3, .cb-c1 .cb__titel { font-size: clamp(22px, 2.6vw, 30px); line-height: 1.25; margin-bottom: 10px; max-width: 30ch; }
.cb-c1 .cb__titel { color: var(--navy); }   /* sonst gewönne .cb-c1 p mit --muted */
.cb-c1 .cb__titel + p { margin-top: 0; }
/* Vollton-Orange statt --orange-text: die Karte ist weiss, die Zeile ist 30px
   und 700 — das ist keine Fliesstext-Lage. Auf Wunsch des Auftraggebers. */
.cb-c1 h2 em, .cb-c1 h3 em, .cb-c1 .cb__titel em { font-style: normal; color: var(--orange); }
.cb-c1 p { color: var(--muted); max-width: 56ch; margin: 0; }
.cb-c1 p + p { margin-top: 10px; }
@media (max-width: 860px) {
  .cb-c1 { padding: 28px 24px; }
  .cb-c1 .cb__inner { grid-template-columns: minmax(0, 1fr); }
  /* Einspaltig liegt der Geist unter dem Text, nicht daneben — dort deckt er
     sich mit Microcopy und Knopf. Deshalb hier die längere Anlaufzone links
     (38 % statt 12 %) und die geringere Deckkraft; das Ausblenden rechts bleibt
     wie in der Grundregel. */
  .cb-c1__geist { right: -20px; top: auto; bottom: -30px; transform: none; opacity: .6;
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 42%, #000 90%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0%, #000 42%, #000 90%, transparent 100%); }
  .cb-c1 .btn { width: 100%; }
}

/* C1 mit Grafik rechts (seit 11.10.2026, Kasten „So verkauft man heute“ auf den Stufenseiten, Auftraggeber: „unser
   Kundensystem rechts daneben … als Verstärker“): Der Knopf steht unter dem Text, rechts die Kundensystem-Grafik
   (.ks, §17a) als stille Ergänzung, ohne Links und ohne Hover, für Screenreader ausgeblendet. 220 px breit, damit der
   Kasten nicht höher wird als nötig; einspaltig steht sie mittig unter dem Text. */
.cb-c1__grafik { width: 220px; }
.cb-c1__grafik .ks { max-width: 220px; pointer-events: none; }
.cb-c1__text .cb__tat { margin-top: 20px; }
@media (max-width: 860px) {
  .cb-c1__grafik { width: 100%; max-width: 200px; margin: 4px auto 0; }
}

/* --- D4-c · Navy-Karte, Bild ragt über die linke Kante ---
   Ersetzt die vier .case-card--big-Vorkommen (Startseite, /business-ki/,
   /zoho/, /best-practice-loesungen/zoho-crm-einfuehrung/). Die alte Bauform
   legte Bild und Zitat nebeneinander in eine weisse Karte und liess die
   Kennzahlen ohne Handlung enden; hier trägt die Navy-Fläche das Zitat, die
   Kennzahlen stehen als Fuss unter einer Haarlinie, und das Bild ragt links
   über die Kante auf die Sektionsfläche.

   Der Überstand ist die ganze Variante, und daran hängen drei Dinge:
   1. overflow: visible hebt die Maske von .cb auf — sonst schneidet die Karte
      genau das ab, was herausragen soll.
   2. margin-left am Banner trägt den Überstand, damit das Bild aus dem BANNER
      ragt und nicht aus der Sektion.
   3. Der Ring ums Bild ist --surface-2, nicht weiss: das Bild liegt zur Hälfte
      auf der Sektionsfläche (alle vier Einbaulagen sind .section--soft, und
      --soft IST --surface-2). In Weiss wäre die äussere Ringhälfte unsichtbar
      und die innere bräche an der Bannerkante mitten ab.
   Eine Vollton-Fläche, kein Verlauf: nur mit sichtbarer Kante liest sich der
   Überstand als Überstand. Auf Vollton trägt weisse Schrift ausserdem überall
   (9,3:1), es gibt also keine Zone, in der Text nicht stehen darf. */
.cb-d4c {
  overflow: visible;                      /* siehe 1. */
  margin-left: 48px;                      /* siehe 2. */
  background: var(--navy);
  border-radius: var(--radius-card);
  display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 34px; align-items: center;
  padding: 30px 34px 30px 0;
}
/* justify-self: start ist hier Bedingung, nicht Kosmetik. Rasterfelder werden
   in der Inline-Achse gestreckt; ein negativer Rand VERBREITERT das Feld dann,
   statt es zu verschieben — gemessen war das Bild 248px statt 200 und damit
   331px hoch, was den Banner auf 391px trieb, obwohl der Inhalt nur 218–244px
   braucht. Mit start sitzt die Breite fest und der Rand schiebt wirklich. */
.cb-d4c__bild { justify-self: start; width: 100%; margin-left: -48px; }
.cb-d4c__bild .img-placeholder {
  aspect-ratio: 3 / 4; min-height: 0;
  border-radius: var(--radius-card);
  box-shadow: 0 0 0 5px var(--surface-2), var(--shadow-card);   /* siehe 3. */
}
/* Echtes Foto im Bild-Slot statt des Platzhalters. Gleiche Fallunterscheidung
   wie bei .img-placeholder--avatar (Abschnitt 25) und aus demselben Grund:
   Seitenverhaeltnis, Rundung und der weisse Ring stecken in der
   Platzhalter-Regel darueber. Ohne Klasse saesse das Bild ungerundet und in
   Originalhoehe im Banner und triebe ihn auf die dreifache Hoehe.
   :not(.img-placeholder) trifft genau diesen Fall; die Platzhalter der
   uebrigen Seiten bleiben unberuehrt.
   object-position wird je Bild inline gesetzt: die Standbilder tragen den
   Kopf nicht mittig, und ein 3:4-Ausschnitt aus 16:9 wirft sonst genau das
   Gesicht heraus. Achtung beim Einstellen: der Prozentwert ist NICHT die
   Bildstelle, die in der Mitte landet. Das Fenster ist hier 42 % der
   skalierten Bildbreite, die sichtbare Mitte liegt also bei
   p x 0,58 + 0,21 — fuer einen Kopf bei 79 % braucht es p = 100 %. */
.cb-d4c__bild > figure:not(.img-placeholder) {
  margin: 0; overflow: hidden;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-card);
  box-shadow: 0 0 0 5px var(--surface-2), var(--shadow-card);
}
.cb-d4c__bild > figure:not(.img-placeholder) > img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Schrift auf Navy — dieselben Werte wie .cb--navy, nur der Kicker in Weiss. */
.cb-d4c .eyebrow { color: #fff; }
.cb-d4c__zitat { color: #fff; font-size: clamp(19px, 2.2vw, 26px); line-height: 1.38;
  max-width: 32ch; margin: 10px 0 8px; }
.cb-d4c__quelle { display: block; font-size: var(--text-small); color: #D6E2EE; }
/* Kennzahlen und Handlung teilen sich den Fuss. flex-wrap statt fester Spalten:
   die Zahl der Kennzahlen schwankt je Seite zwischen einer und dreien. */
.cb-d4c__leiste { display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  border-top: 1px solid rgba(255,255,255,.22); margin-top: 22px; padding-top: 18px; }

/* Die Startseite trägt im Fuss ihren vorhandenen Textlink statt eines Knopfes.
   .btn-arrow ist navy auf navy — hier also Weiss, Unterstreichung bleibt orange. */
.cb-d4c .btn-arrow { color: #fff; }
.cb-d4c .btn-arrow:hover { color: #fff; }
@media (max-width: 860px) {
  /* Einspaltig steht der Banner selbst an der Sektionskante — das Bild würde
     also aus der SEKTION laufen statt aus dem Banner. Der Überstand ist
     deshalb ein Desktop-Merkmal; gestapelt sitzt das Bild oben links drin und
     wird quer, weil ein Hochformat über der vollen Breite zu hoch baut. */
  .cb-d4c { grid-template-columns: minmax(0, 1fr); margin-left: 0; padding: 24px 20px 26px; gap: 0; }
  .cb-d4c__bild { width: 150px; margin: 0 0 20px; }
  .cb-d4c__bild .img-placeholder { aspect-ratio: 4 / 3; }
  /* Echte Fotos behalten hier bewusst 3:4. Der Platzhalter wird quer, weil er
     ueber die volle Breite zu hoch baut — das Foto steht aber in einem 150px
     schmalen Kasten, 3:4 sind darin 200px. Dazu kommt der Ausschnitt: quer
     zeigt das Fenster 75 % der Bildbreite, und in den Standbildern steht
     links die eingebrannte Schlagzeile, die damit wieder im Bild waere. */
}
@media (max-width: 767px) { .cb-d4c__leiste .btn { width: 100%; } }

/* ---------- 17. Hub-and-Spoke (C12): App-Kranz ----------
   Zoho CRM in der Mitte, die Zoho-Apps als Kranz drumherum. Löst am
   26.09.2026 die Bilddatei zoho-hub.svg ab (drei Ringe aus gefüllten Kreisen
   mit Text darin, dazu Bestandssysteme und KI). Der Kranz zeigt bewusst NUR
   Zoho: KI bekommt später einen eigenen Ort. Steht auf / (Abschnitt 4) und
   im Hero von /zoho/ mit identischem Markup — beim Tausch einer App beide
   Seiten anfassen. Gebaut nach docs/grafiksprache.md, Idiom B (Kreis),
   Abweichungen dort unter „App-Kranz".

   Alle Maße hängen an der Breite des Kranzes (cqw), nicht am Viewport. Der
   Kranz sitzt mal in der Hero-Spalte (508px bei 1280, 352px bei 861 — dort
   ist der Split noch zweispaltig), mal einspaltig bis 520px, mal bei 280px
   (320er Fenster). Mit festen Pixeln bräuchte jede dieser Breiten eigene
   Werte; so skaliert der Kranz als Ganzes und die Geometrie bleibt gleich.

   Die Icons sind KEINE eigenen Dateien. Jede App zeigt ihre Logodatei aus
   assets/img/zoho/ durch ein quadratisches viewBox-Fenster, das nur das
   Icon links im Lockup freigibt:
     <svg viewBox="-18 0 296 296"><image href="…/desk.svg" width="684" height="296"/></svg>
   Nichts nachgezeichnet, nichts umgefärbt, und es bleibt bei einer Datei
   je Marke. Die Fensterwerte sind je Logo gemessen, weil die Icons
   unterschiedlich weit eingerückt sind — Tabelle in docs/grafiksprache.md. */
.app-kranz {
  --kranz-radius: 37cqw;    /* Mitte -> Kachelmitte */
  --kranz-kachel: 13.5cqw;  /* Kantenlänge einer App-Kachel */
  --kranz-mitte: 42cqw;     /* Durchmesser der CRM-Scheibe */
  position: relative;
  width: 100%;
  max-width: 520px;
  aspect-ratio: 1;
  margin: 0 auto;
  container-type: inline-size;
}
/* Die Bahn liegt genau auf den Kachelmitten: 50 % minus Radius. */
.app-kranz__bahn {
  position: absolute; inset: calc(50% - var(--kranz-radius));
  border: 1px dashed var(--line-strong);
  border-radius: 50%;
}
.app-kranz__apps { list-style: none; margin: 0; padding: 0; max-width: none; }
/* Das <li> ist ein Punkt ohne Ausdehnung, gesetzt über den Winkel --a.
   sin/cos statt der Doppel-Rotation des Kreislaufs (§38): die rechnet in
   translateY, und Prozent dort beziehen sich auf das Element selbst, nicht
   auf den Kranz. */
.app-kranz__app {
  position: absolute; margin: 0;
  left: calc(50% + var(--kranz-radius) * sin(var(--a)));
  top: calc(50% - var(--kranz-radius) * cos(var(--a)));
}
/* Speiche: vom Punkt zur Mitte, bis an den Rand der CRM-Scheibe. Die Linie
   zeigt ungedreht nach unten; um --a gedreht, zeigt sie genau zur Mitte.
   --line-strong statt des --line, das die Grafiksprache für
   Verbindungslinien nennt: auf --surface-2 (Startseite) liegt --line bei
   einem Kontrast von 1,1 : 1 und ist praktisch weg. */
.app-kranz__app::before {
  content: ""; position: absolute; left: -.5px; top: 0;
  width: 1px; height: calc(var(--kranz-radius) - var(--kranz-mitte) / 2);
  background: var(--line-strong);
  transform-origin: 50% 0;
  transform: rotate(var(--a));
}
.app-kranz__link {
  position: absolute; left: 0; top: 0;
  width: var(--kranz-kachel); height: var(--kranz-kachel);
  margin: calc(var(--kranz-kachel) / -2) 0 0 calc(var(--kranz-kachel) / -2);
  display: grid; place-items: center;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  text-decoration: none;
  transition: border-color .2s var(--ease);
}
.app-kranz__link:hover { border-color: var(--navy); }
.app-kranz__link:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
.app-kranz__icon { display: block; width: 64%; height: 64%; }
/* Der Name hängt absolut unter der Kachel, damit die Kachelmitte auf dem
   Punkt bleibt, egal wie lang der Name ist. Der Grund in Flächenfarbe deckt
   Bahn und Speiche ab, wo sie hinter dem Namen durchlaufen.
   12px Untergrenze, gemessen bei 280px Kranzbreite (320er Fenster): die
   beiden oberen Namen stehen 64px auseinander, Mitte zu Mitte; „Campaigns"
   (62px) und „Analytics" (49px) lassen dazwischen 8px Luft. Mehr als 12px
   trägt der Kranz dort nicht. max-width 26cqw: „Campaigns" samt Polster
   braucht bei 280px 70px, 24cqw wären 67px. */
.app-kranz__name {
  position: absolute; left: 50%; top: calc(100% + 8px);
  transform: translateX(-50%);
  width: max-content; max-width: 26cqw;
  padding: 0 .35em;
  font-size: clamp(12px, 2.7cqw, 14px); line-height: 1.25;
  color: var(--muted); text-align: center;
  background: var(--paper);
  transition: color .2s var(--ease);
}
.section--soft .app-kranz__name { background: var(--surface-2); }
.app-kranz__link:hover .app-kranz__name { color: var(--navy); }
/* Die vier Apps der oberen Hälfte tragen den Namen über der Kachel, also
   nach außen. Darunter stünde er zwischen Kachel und Mitte.
   Dazu gehört die Drehung um eine halbe Teilung: zehn Apps im 36°-Raster,
   beginnend bei 18° statt bei 0°. So liegen je eine App genau auf der
   Waagerechten (90°/270°) und je zwei symmetrisch oben und unten. Beim
   Raster ab 0° standen die seitlichen Apps schräg übereinander, und bei
   354px Kranzbreite (861er Fenster) ragten „Bookings" und „WorkDrive" 6
   bzw. 10px in die Kachel darunter. */
.app-kranz__app--oben .app-kranz__name { top: auto; bottom: calc(100% + 8px); }
.app-kranz__mitte {
  position: absolute; left: 50%; top: 50%; z-index: 1;
  width: var(--kranz-mitte); aspect-ratio: 1;
  transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2.4cqw;
  background: var(--paper);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--line-strong);
  text-decoration: none;
  transition: box-shadow .2s var(--ease);
}
.app-kranz__mitte:hover { box-shadow: inset 0 0 0 1px var(--navy); }
.app-kranz__mitte:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
.app-kranz__crm { display: block; width: 28cqw; height: auto; max-width: none; }

/* ---------- 17a. Kundensystem-Grafik (.ks) ----------
   Der ICOS-Kunden-Kreislauf auf / und /kundensystem/: ein Trichter, dessen
   Spitze „Mit System verkaufen" zugleich das obere Segment des Kreislaufs
   ist, fünf weitere Segmente im Uhrzeigersinn, „Kunden" in der Mitte, sechs
   feste orange Pfeile außen.

   Seit 27.09.2026 exakt die Form aus dem Foliensatz des Teilnehmer-Materials
   (vorlage/build.py, svg_kreislauf) — auf Wunsch des Auftraggebers das
   Original. Alle Maße stammen von dort: Mitte 230/430, Ring 185, Mittelkreis
   52, Trichter-Öffnung 2 × 28°, Stufenlinien 68/133/202/272, Pfeile auf
   Radius 190. Im HTML sind die Koordinaten um (−30, −48) verschoben, damit
   die viewBox bei 0 0 beginnt und der Leerraum der Folie wegfällt.
   transform-origin in px bezieht sich auf den Ursprung der viewBox, deshalb
   verschoben statt beschnitten.

   Zwei Abweichungen von der Folie, beide bewusst:
   – Die Fugen sind Geometrie, keine Kontur. Die Folie malt eine 6er-Kontur
     in Hintergrundfarbe, hier ist jede Fläche um 3 eingerückt. Optisch
     dasselbe, aber die Kontur bleibt frei für den Hover-Rand, und die Fuge
     hängt nicht an der Hintergrundfarbe.
   – Farben aus den Tokens statt der Folienwerte (Fläche #DCE8F5, Schrift
     #3D5573, Orange #F79817). Die Stufen-Chips und „Kunden" stehen wie die
     Pfeile im Vollton --orange, siehe unten.

   Bis 26.09.2026 stand hier die Geometrie der früheren Bilddatei
   kundensystem-funnel.svg: Trichter über einem eigenen Kreis mit sechs
   gleichen Segmenten, dazu EIN umlaufender Pfeil mit „Tour"-Hervorhebung.
   Beides ist entfallen, der Pfeil samt ks-lauf/ks-puls/ks-tour ebenso.

   Schriftgrade wie auf der Folie in viewBox-Einheiten (15/15/16). Bei der
   Höchstbreite von 440px sind das 16,5px am Schirm, bei 280px (320er
   Fenster) 10,5px — die alte Grafik stand dort bei 8,4px. */
.ks { width: 100%; max-width: 440px; height: auto; display: block; margin: 0 auto; overflow: visible; }
.ks text { font-family: var(--font-sans); font-weight: 700; }

/* Eine Stufe = ein <a> mit Fläche und Beschriftung. transform-origin steht
   inline pro Stufe (Schwerpunkt in viewBox-Einheiten), weil transform-box:
   fill-box auf <a>-Gruppen nicht überall trägt. Die Reihenfolge der neun <a>
   ist die der Stufen-Kette: Die Infokarte am Zeiger (main.js) ordnet über
   den Index zu. */
.ks__stufe { cursor: pointer; transition: transform .3s var(--ease); }
/* Kontur im Ruhezustand transparent statt none — none lässt sich beim Hover
   nicht überblenden. */
.ks__flaeche { fill: var(--blau-flaeche); stroke: transparent; stroke-width: 2;
  transition: fill .25s var(--ease), stroke .25s var(--ease); }
.ks__label { fill: var(--navy); font-size: 15px; }
.ks__stufe:focus { outline: none; }
/* 1,03 statt der früheren 1,05, gerechnet: Die Fugen sind hier 6 statt 10
   Einheiten breit. Mit 1,05 blieben an der engsten Stelle (Leads
   qualifizieren zu Kunden aktivieren) samt Rand noch 0,8 Einheiten Fuge,
   mit 1,03 sind es 2,5. Kein Umsortieren beim Hover (SVG kennt kein
   z-index), die gewachsene Stufe überdeckt nichts. */
.ks__stufe:hover, .ks__stufe:focus-visible { transform: scale(1.03); }
.ks__stufe:hover .ks__flaeche, .ks__stufe:focus-visible .ks__flaeche {
  fill: var(--blau-flaeche-tief); stroke: var(--orange); }

/* Deko — Mitte, Stufen-Chips, Pfeile: nie im Weg des Zeigers. */
.ks__deko { pointer-events: none; }
.ks__mitte, .ks__chip { fill: var(--paper); stroke: var(--line-strong); stroke-width: 1; }
/* Chips und „Kunden" im Vollton --orange wie die Pfeile, auf Wunsch des
   Auftraggebers am 27.09.2026 — nicht im --orange-text, das die Markenregel
   für Schrift vorsieht. Bekannt und in Kauf genommen: #FF940A auf Weiß hat
   2,2 : 1 Kontrast. WCAG AA verlangt für fette Schrift unter 18,7px 4,5 : 1,
   hier sind es am Schirm höchstens 16,5 bzw. 17,6px (--orange-text hätte
   4,6 : 1). Die Chips sind Deko (aria-hidden), ihre Aussage steht im
   aria-label der Grafik. Bis 26.09.2026 standen sie ebenso im Vollton. */
.ks__mitte-text { fill: var(--orange); font-size: 16px; }
.ks__chip-text { fill: var(--orange); font-size: 15px; }
/* Die Pfeile tragen die Richtung des Kreislaufs, wie die Achse in Idiom A
   der Grafiksprache. */
.ks__pfeil { fill: none; stroke: var(--orange); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- 17a-2. Variante „Aufbau" (data-ks-aufbau) ----------
   Die statische Grafik oben ist der Standard. Mit data-ks-aufbau="<ms>" am
   <svg> baut sie sich beim ersten Sichtbarwerden Element für Element auf und
   läuft danach als Kreislauf weiter — auf / und /kundensystem/, freigegeben
   am 27.09.2026. Das Skript steht in main.js („Kundensystem-Grafik, Variante
   Aufbau"), das Markup erzeugt scripts/kundensystem-grafik.py.

   Aufbau (einmal): Element für Element in der Reihenfolge --auf (0–19):
   Zielkunden, Zielkunden ansprechen, Besucher, Leads generieren, Leads,
   Leads qualifizieren, Interessenten, Mit System verkaufen, Kunden, der Ring
   im Uhrzeigersinn, zuletzt die sechs Pfeile. Was gerade erscheint, trägt
   die orange Umrandung (is-lauf), bei einem Pfeil die Stufe, auf die er
   zeigt. So läuft der Aufbau ohne Bruch in den Kreislauf über, der dieselbe
   Markierung benutzt: reihum pulsiert ein Pfeil, seine Zielstufe leuchtet.

   Verborgen wird NUR unter ks--baut, und die Klasse setzt allein das
   Skript — nie bei prefers-reduced-motion. Ohne Skript oder mit reduzierter
   Bewegung steht also sofort das fertige Bild. Nach dem Aufbau nimmt das
   Skript ks--baut wieder weg; ab da ist das Bild pixelgleich mit der
   statischen Variante (gemessen). Die Strichelung zum Zeichnen der Pfeile
   gilt deshalb nur während des Aufbaus: Bleibt sie stehen, weicht das Ende
   eines Bogens um gut hundert Bildpunkte ab. */
.ks--baut :is(.ks__stufe, .ks__chip-gruppe, .ks__mitte-gruppe, .ks__pfeil-gruppe):not(.ist-da) { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .ks--baut :is(.ks__stufe, .ks__chip-gruppe, .ks__mitte-gruppe).ist-da { animation: ks-fallen .7s var(--ease); }
  /* Der Ring und die Mitte wachsen aus ihrem Schwerpunkt, der Trichter fällt. */
  .ks--baut :is(.ks__stufe--ring, .ks__mitte-gruppe).ist-da { animation-name: ks-wachsen; }
  .ks--baut .ks__pfeil-gruppe.ist-da .ks__pfeil-bogen { stroke-dasharray: 1; animation: ks-zeichnen .6s var(--ease); }
  .ks--baut .ks__pfeil-gruppe.ist-da .ks__pfeil-spitze { animation: ks-einblenden .25s var(--ease) .5s backwards; }
}
@keyframes ks-fallen { from { opacity: 0; transform: translateY(-10px); } }
@keyframes ks-wachsen { from { opacity: 0; transform: scale(.9); } }
@keyframes ks-zeichnen { from { stroke-dashoffset: 1; } }
@keyframes ks-einblenden { from { opacity: 0; } }

/* Die Markierung — im Aufbau, im Kreislauf und auf den Stufenseiten
   dieselbe: Stufen wie beim Hover, nur ohne Zoom; Chips und Mitte bekommen
   den orangen Rand. Auf einer Stufenseite (statische Variante) trägt der
   Link zur eigenen Seite aria-current="page" und bleibt so dauerhaft
   markiert: „hier bist du". */
.ks__stufe.is-lauf .ks__flaeche,
.ks__stufe[aria-current="page"] .ks__flaeche { fill: var(--blau-flaeche-tief); stroke: var(--orange); }
.ks__chip, .ks__mitte { transition: stroke .25s var(--ease), stroke-width .25s var(--ease); }
.ks__chip-gruppe.is-lauf .ks__chip, .ks__mitte-gruppe.is-lauf .ks__mitte { stroke: var(--orange); stroke-width: 2; }
.ks__pfeil-gruppe.is-lauf .ks__pfeil { animation: ks-pfeil-puls .9s var(--ease); }
@keyframes ks-pfeil-puls { 35% { stroke-width: 4.6; } }

/* Infokarte am Zeiger: ein Klon der .stufe-card aus der Stufen-Kette weiter
   unten auf derselben Seite (Abschnitt 10) — deshalb exakt dieselbe Optik,
   und Titel und Text können nie auseinanderlaufen. Drei Dinge weichen ab:
   die Karte hängt am Cursor, sie ist nicht anfassbar, und ihre Zahl steht
   sofort im Hover-Zustand — die Karte selbst kann ja nicht gehovert werden. */
.ks-tip {
  position: fixed; top: 0; left: 0; z-index: 210;
  width: max-content; max-width: 320px;
  pointer-events: none;
  visibility: hidden; opacity: 0;
  transition: opacity .15s var(--ease);
}
.ks-tip.is-visible { visibility: visible; opacity: 1; }
/* height: 100% käme aus der Rasterzelle — hier ist der Container der
   Viewport, die Karte wäre bildschirmhoch. */
.ks-tip .stufe-card { height: auto; box-shadow: var(--shadow-card); }
.ks-tip .stufe-card__num { background: var(--orange); color: var(--ink); box-shadow: none; }

/* Legende neben dem App-Kranz (Startseite). Die Punkte wiederholen die
   Bauteile der Grafik: Orange steht für den Kern-Chip der Mitte, die weiße
   Kachel für eine App. Bis 26.09.2026 bildeten sie die Kreise von
   zoho-hub.svg nach (Navy-Scheibe, hellblauer Ring, gestrichelter Ring);
   der dritte Punkt „Außen" ist mit der Grafik entfallen. */
.legend { display: grid; gap: 18px; margin: 0 0 24px; max-width: none; list-style: none; padding: 0; }
.legend__item { display: flex; gap: 14px; align-items: flex-start; margin: 0; }
.legend__dot { flex: none; width: 14px; height: 14px; border-radius: 50%; margin-top: 5px; }
.legend__dot--core { background: var(--orange); }
.legend__dot--inner { background: var(--paper); border: 1px solid var(--line-strong); border-radius: 4px; }

/* ---------- 17b. CRM-Haus (.crm-haus) ----------
   Was eine Zoho-CRM-Einführung aufbaut, als Haus: das Setup ist das
   Fundament, darauf die Daten (Leads, Kontakte, Firmen, Verkaufs-Chancen),
   darüber die Aktivitäten, als Dach Kennzahlen, Dashboards und Berichte.
   Nachgebaut am 27.09.2026 nach der Grafik des Auftraggebers, bis 08.10.2026
   im Hero von /zoho-crm-einfuehrung/. Seit 09.10.2026 steht es auf /zoho-crm/
   im Abschnitt Einführung als Empfehlung „Fundament“ (.fundament, unten).
   Idiom C der Grafiksprache (docs/grafiksprache.md): hellblaue Flächen mit
   navy Beschriftung darin, getrennt durch weiße Fugen statt durch die grauen
   Konturen der Vorlage. Das Markup erzeugt scripts/crm-haus-grafik.py.

   Die Icons sind für diese Grafik gezeichnet (48er-Raster, zweifarbig wie
   die Icons der Belegleiste). Ihre Farben kommen über Klassen aus den Tokens:
   k-navy / k-orange = Kontur, f-orange = gefüllte Punkte und Sterne,
   f-grund = Fläche in der Kachelfarbe, die verdeckt, was hinter einer Figur
   liegt. Deshalb hängt die Kachelfarbe an --haus-grund: Wechselt sie bei der
   Markierung, wechseln die Deckflächen mit.

   Zwei Anordnungen, umgeschaltet über die Breite des Hauses selbst. Das ist
   eine Container-Abfrage, kein vierter Breakpoint: Das Haus steht in einer
   Spalte, und deren Breite verrät der Viewport nicht (gemessen damals in der
   Hero-Spalte: 436px bei 1024, 361px bei 861, 840px bei 860 Fensterbreite). Ab 430px vier Kacheln je
   Etage, das Icon über dem Namen; jeder Name hat zwei Zeilen reserviert,
   damit alle Kacheln gleich hoch sind und die Icons auf einer Linie stehen.
   Darunter zwei Kacheln je Etage, das Icon neben dem Namen, die Etagen durch
   eine breitere Fuge getrennt. Die Grenze gibt „Firmenspezi-/fisches Setup“
   vor (85,5px bei 13px): Vierspaltig passt es bis 430px in zwei Zeilen.
   Bei 280px (320er Fenster) bricht es dreizeilig; sonst läuft nichts über
   (gemessen von 280 bis 540px). */
.crm-haus {
  --haus-fuge: 8px;
  --haus-grund: var(--blau-flaeche);
  --haus-icon: clamp(34px, 9cqw, 46px);
  container: crm-haus / inline-size;
  display: grid;
  gap: var(--haus-fuge);
  width: 100%;
  max-width: 540px;
  margin: 0 auto;
}
/* Das Dach ist ein gestrecktes Dreieck hinter Tacho und Namen. Die Höhe
   hängt an der Hausbreite, die Kontur (nur bei der Markierung sichtbar)
   bleibt dank non-scaling-stroke überall 2px. */
.crm-haus__dach {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  height: clamp(108px, 30cqw, 152px);
  padding-bottom: clamp(10px, 3cqw, 16px);
  text-align: center;
}
.crm-haus__dachform {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.crm-haus__dachform path {
  fill: var(--haus-grund);
  stroke: transparent;
  stroke-width: 2;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  transition: fill .25s var(--ease), stroke .25s var(--ease);
}
.crm-haus__etage {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--haus-fuge);
  max-width: none;
  margin: 0;
  padding: 0;
  list-style: none;
}
.crm-haus__kachel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 16px 6px 14px;
  background: var(--haus-grund);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 2px transparent;
  text-align: center;
  transition: background-color .25s var(--ease), box-shadow .25s var(--ease);
}
.crm-haus__icon {
  display: block;
  flex: none;
  width: var(--haus-icon);
  height: var(--haus-icon);
  overflow: visible;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.crm-haus__icon--tacho { width: calc(var(--haus-icon) * 1.15); height: calc(var(--haus-icon) * 1.15 * 28 / 48); }
.crm-haus__icon .k-navy { stroke: var(--navy); }
.crm-haus__icon .k-orange { stroke: var(--orange); }
.crm-haus__icon .f-orange { fill: var(--orange); }
.crm-haus__icon .f-grund { fill: var(--haus-grund); transition: fill .25s var(--ease); }
.crm-haus__name {
  max-width: none;
  margin: 0;
  color: var(--navy);
  font-size: clamp(13px, 3cqw, 14px);
  font-weight: 700;
  line-height: 1.25;
  hyphens: manual;
}
.crm-haus__kachel .crm-haus__name { display: flex; align-items: center; justify-content: center; min-height: 2.5em; }
/* Der Zeiger ist senkrecht gezeichnet und steht gedreht rechts oben. */
.crm-haus__zeiger { transform-box: view-box; transform-origin: 24px 25px; transform: rotate(38deg); }

@container crm-haus (max-width: 429px) {
  .crm-haus__etage { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .crm-haus__etage + .crm-haus__etage { margin-top: 6px; }
  .crm-haus__kachel { flex-direction: row; gap: 8px; min-height: 53px; padding: 10px; text-align: left; }
  .crm-haus__kachel .crm-haus__icon { width: 28px; height: 28px; }
  .crm-haus__kachel .crm-haus__name { display: block; min-height: 0; }
  .crm-haus__name { font-size: 13px; }
}

/* Aufbau (data-haus-aufbau, Skript in main.js „CRM-Haus“): einmal beim
   ersten Sichtbarwerden, von unten nach oben — Basis-Setup zuerst, das Dach
   zuletzt (Reihenfolge data-auf). Dieselbe Mechanik wie bei der
   Kundensystem-Grafik (§17a-2), auch dieselben Keyframes ks-fallen:
   Verborgen wird NUR unter crm-haus--baut, und die Klasse setzt allein das
   Skript. Ohne Skript oder mit reduzierter Bewegung steht also sofort das
   fertige Haus. Was gerade erscheint, trägt die orange Umrandung (is-lauf).
   Mit dem Dach schlägt der Zeiger im Tacho von links nach rechts oben aus
   und federt nach. Die Dauern liegen wie beim Aufbau der Kundensystem-Grafik
   bewusst über der 0,6s-Grenze aus docs/DESIGN.md: Ein Aufbau soll gesehen
   werden, nicht vorbeihuschen. */
.crm-haus--baut :is(.crm-haus__dach, .crm-haus__kachel):not(.ist-da) { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .crm-haus--baut :is(.crm-haus__dach, .crm-haus__kachel).ist-da { animation: ks-fallen .7s var(--ease); }
  .crm-haus--baut .crm-haus__dach.ist-da .crm-haus__zeiger { animation: crm-haus-zeiger .9s cubic-bezier(.34, 1.45, .64, 1) .35s backwards; }
}
@keyframes crm-haus-zeiger { from { transform: rotate(-78deg); } }
.crm-haus__kachel.is-lauf { --haus-grund: var(--blau-flaeche-tief); box-shadow: inset 0 0 0 2px var(--orange); }
.crm-haus__dach.is-lauf { --haus-grund: var(--blau-flaeche-tief); }
.crm-haus__dach.is-lauf .crm-haus__dachform path { stroke: var(--orange); }
/* Empfehlung „Fundament“ auf /zoho-crm/ (seit 09.10.2026): Text links, Haus
   rechts, unter den Schritten der Einführung. Der Abstand trennt die beiden
   Teile des Abschnitts deutlicher als der der Schritte untereinander. */
.fundament { margin-top: 72px; }
.fundament h3 { font-size: clamp(22px, 2.4vw, 28px); }
@media (max-width: 767px) { .fundament { margin-top: 56px; } }

/* ---------- 18. News-Karte (C13) ---------- */
.news-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-decoration: none;
  color: inherit;
  /* Hover: gemeinsame Regel in Abschnitt 9 (Karten) */
}
.news-card__meta,
.news-card__date { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Das Datum schließt die Karte ab. margin-top:auto, damit es bei
   unterschiedlich langen Anrissen trotzdem auf einer Linie sitzt. */
.news-card__date { margin-top: auto; }
.news-card h3 { font-size: 17px; margin: 0; }
.news-card p { font-size: 15px; margin: 0; color: var(--ink); }
.news-card__label { font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 7px; }
.news-card__label::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.news-card__label--sofort { color: var(--success); }

/* ---------- 19. Quick-Answer-Block (C14) ----------
   Die Kernantwort nach der H1. Erst eine graue Box mit Grundschriftgröße —
   niemand fand darin einen Einstieg. Dann mittig und groß gesetzt ohne
   Kasten — der Block war damit das einzige zentrierte Element der Seite und
   brach aus dem System aus, und der breite Filzstiftstrich biss sich mit den
   dünnen orangen Linien ringsum (Swoosh unter der H1, Eyebrow-Strich).

   Jetzt: linksbündig auf derselben Achse wie Hero, H2 und Fließtext, auf
   einer eigenen ruhigen Fläche. Die Fläche macht den Block zu einem eigenen
   Abschnitt — er kann nicht mehr am Nachbarinhalt kleben. Dafür braucht die
   Section .section--compact.section--soft, und der Section DARUNTER wird
   .section--soft weggenommen: sonst stoßen zwei graue Flächen aneinander und
   die Fläche verliert ihre Kante.

   Die tragenden Stellen stehen in <mark> und bekommen eine 2px-Unterlänge in
   Orange — dieselbe Strichstärke wie Swoosh (3,2px) und Eyebrow-Strich (3px).
   Der Block tritt damit in die Linienfamilie der Seite ein, statt gegen sie
   zu stehen. Drei bis fünf Stellen pro Block, mehr wird zum Leuchtstift.
   Gezogen wird beim Sichtbarwerden; dafür genügt .reveal auf .quick-answer,
   den Rest macht der Reveal-Observer in main.js. Bei prefers-reduced-motion
   sind die Striche sofort da.

   Wichtig: In diesem Block wird nie Text hinter eine Interaktion gelegt.
   Er ist die Antwort, die generative Suchmaschinen zitieren, und muss
   immer vollständig und sichtbar im DOM stehen. Für Kästen mit anderem
   Zweck (Redaktionshinweise, „Was ist neu?“) ist .card--soft da. */
.quick-answer { max-width: none; margin: 0; text-align: left; }
.quick-answer .eyebrow { color: var(--muted); margin-bottom: 16px; }
/* Die Frage über der Antwort (O72, 10.10.2026): Zwischen der kleinen Zeile und
   dem Absatz steht die Frage, auf die der Block antwortet, als <h2>. So lesen
   Suchmaschinen und KI-Assistenten Frage und Antwort als Paar. Sie ist eine
   echte Überschrift, aber eine Stufe kleiner als die H2 der Bahnen: --text-h3
   wie der Kartentitel (Vorbild .tool-teaser h2, §13). In voller H2-Größe
   stünde über der Antwort eine zweite Bahnüberschrift, und der Block verlöre
   seine Ruhe. Abstand oben gibt die kleine Zeile vor (16px), unten 12px bis
   zur Antwort: Frage und Antwort gehören zusammen, mehr Luft trennte sie. */
.quick-answer__frage { font-size: var(--text-h3); line-height: 1.25; margin: 0 0 12px; }
.quick-answer p {
  font-size: clamp(18px, 1.7vw, 20px);
  line-height: 1.62;
  margin: 0;
  max-width: 62ch;
}
.quick-answer p + p { margin-top: 15px; }
.quick-answer mark {
  /* Das Browser-Gelb von <mark> muss weg, sonst liegt der Strich darauf. */
  background-color: transparent;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  color: inherit;
  font-weight: 600;
  padding-bottom: 3px;
  transition: background-size .45s var(--ease);
}
.quick-answer.is-visible mark { background-size: 100% 2px; }
.quick-answer p mark:nth-of-type(2) { transition-delay: .09s; }
.quick-answer p mark:nth-of-type(3) { transition-delay: .18s; }
.quick-answer p mark:nth-of-type(4) { transition-delay: .27s; }
.quick-answer p mark:nth-of-type(5) { transition-delay: .36s; }
/* ki.html und leistungen.html setzen <mark><strong> für die Aufzählung der
   drei Wege. Das doppelte Gewicht bleibt, ohne dass die Stelle doppelt so
   laut wird — 600 aus .quick-answer mark wird hier auf 700 gehoben. */
.quick-answer mark strong { font-weight: 700; }
/* Ohne JavaScript und ohne Bewegung sofort in Endstellung. */
@media (prefers-reduced-motion: reduce) {
  .quick-answer mark { background-size: 100% 2px; }
}

/* Antwort links, schmale Beiwerk-Spalte rechts (kundensystem.html: die
   Buch-Karte). Bricht bei 900px um, nicht erst bei 640px wie .grid-2 —
   darunter wird die Textspalte für 20px-Satz zu schmal. Muss eine Klasse
   sein und kein Inline-Style: der schlägt sonst den Umbruch. */
.quick-answer-row { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 40px; align-items: start; }
@media (max-width: 860px) {
  .quick-answer-row { grid-template-columns: 1fr; gap: 28px; }
  /* Gestapelt darf das Beiwerk nicht auf Sektionsbreite laufen. */
  .quick-answer-row > :last-child { max-width: 420px; }
}

/* ---------- 19a. Beiwerk-Grafik zur Antwort (alle Quick-Answer-Seiten außer /kundensystem/) ----------
   Vorher füllte der Block nur die linke Hälfte des Bandes, rechts blieb auf
   19 Seiten leere Fläche — und auf /kundensystem/ stand dort das Buch. Die
   Grafik schließt beides: dieselbe Spalte, dieselbe Aufteilung, überall.
   /kundensystem/ behält das Buch, das ist die einzige Ausnahme.

   Die Grafik ist rein dekorativ (aria-hidden): Frage-Blase, Antwort-Blase,
   Häkchen — sie zeigt, was der Block leistet, ohne einen Inhalt zu tragen,
   der den zitierfähigen Absatz daneben doppeln würde. Deshalb steht sie als
   Inline-SVG und nicht als Datei: der orange Strich wird von .reveal
   ausgelöst, und ein <img> hört von außen kein .is-visible.

   align-self: center statt des start aus .quick-answer-row — die Antworten
   sind zwischen 4 und 9 Zeilen lang. Oben angeschlagen bliebe darunter ein
   sichtbares Loch; mittig liest sich der Rest als Rand. */
.qa-figur { display: block; width: 100%; height: auto; align-self: center; overflow: visible; }
.qa-figur text { font-family: var(--font-sans); }
@media (max-width: 860px) {
  /* Gestapelt bleibt die Grafik ein Objekt und läuft nicht auf Bandbreite
     (der 420px-Deckel aus .quick-answer-row wäre dafür noch zu viel). */
  .qa-figur { max-width: 280px; align-self: start; }
}
/* Derselbe Strich wie im <mark> daneben, dieselbe Dauer, dieselbe Kurve —
   eine Bewegung, zwei Orte. transform-box: fill-box, weil transform-origin
   in SVG sonst am viewBox-Ursprung hängt und der Strich aus dem Bild läuft. */
.qa-strich { transform: scaleX(0); transform-box: fill-box; transform-origin: left center;
  transition: transform .5s var(--ease) .18s; }
.reveal.is-visible .qa-strich { transform: scaleX(1); }
/* Das Häkchen kommt nach, mit demselben kleinen Hub wie .reveal selbst. */
.qa-akzent { opacity: 0; transform: translateY(6px); transform-box: fill-box;
  transition: opacity .4s var(--ease) .3s, transform .4s var(--ease) .3s; }
.reveal.is-visible .qa-akzent { opacity: 1; transform: none; }
/* Ohne Bewegung sofort in Endstellung — sonst bliebe der Strich bei 0. */
@media (prefers-reduced-motion: reduce) {
  .qa-strich { transform: scaleX(1); }
  .qa-akzent { opacity: 1; transform: none; }
}

/* ---------- 19b. Buch-Angebot (kundensystem.html) ----------
   Steht in der schmalen Spalte neben der Antwort. Vorher eine Karte in
   --navy-soft, darin ein 16:9-Platzhalter in --navy-soft mit Schraffur und
   gestrichelter Kante — drei gestapelte Grautöne im ohnehin grauen Band, für
   ein Buch, das hochkant ist. Das Angebot beanspruchte mehr Fläche als die
   Antwort daneben.

   Jetzt kein Kasten mehr: das Objekt trägt die Fläche, der Text steht
   darunter. Ein Lead-Magnet verkauft sich über das Ding. */
.buch-angebot { display: grid; gap: 20px; justify-items: start; }
.buch-angebot__titel { font-size: 18px; line-height: 1.25; margin: 0 0 6px; }
.buch-angebot__text { font-size: 14.5px; line-height: 1.55; color: var(--muted); margin: 0; max-width: 40ch; }
/* Textlink statt Button: „Buch anfordern" ist ein Nebenangebot und darf
   optisch nicht mit „Erstgespräch vereinbaren" in der Navigation
   konkurrieren. Der orange Unterstrich ist dieselbe 2px-Geste wie im
   Quick-Answer-Block darüber. */
/* wie oben: Abstand am Ort, nicht am Button */
.buch-angebot .btn-arrow { display: inline-block; margin-top: 16px; }
.buch-angebot__micro { display: block; font-size: 12.5px; color: var(--muted-soft); margin-top: 10px; }

/* Das Buch: seit 27.09.2026 das Mockup von der alten Startseite (Buch,
   Tablet, Smartphone, roter Aufkleber „+ 50 bewährte Kunden-Systeme"), auf
   Wunsch des Auftraggebers statt des vorher per CSS gezeichneten Deckels
   (Rücken, Schnittkante, Titel als Spans). Die Datei liegt nur in 600 × 600px
   vor — mehr hat auch die Altsite nicht —, der transparente Rand ist
   abgeschnitten (585 × 520). Bei 320px Spaltenbreite sind das knapp 2
   Bildpunkte je Pixel, also auch auf Retina-Schirmen scharf; breiter als die
   Spalte wird es nie. Verlustfreies WebP: Verlustbehaftet kam es bei der
   farbigen Kleinschrift auch mit Qualität 100 nicht über 31 dB. */
.buch { display: block; width: 100%; max-width: 320px; text-decoration: none; transition: translate .3s var(--ease); }
.buch img { display: block; width: 100%; height: auto; }
/* Aus dem Regal gezogen — derselbe kleine Hub wie bei Karten. translate statt
   transform, weil .reveal.is-visible transform zurücksetzt (DESIGN.md). */
.buch:hover, .buch:focus-visible { translate: 0 -3px; }
.buch:focus-visible { outline: 2px solid var(--navy); outline-offset: 6px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) {
  .buch:hover, .buch:focus-visible { translate: none; }
}

/* ---------- 19c. Einordnung + Antwort, verschränkt (ki-eigene-ki-aufbauen) ----------
   Auf dieser Seite stand vor der Antwort noch ein zweiter Textblock: der
   Positionierungs-Satz („Was diese Leistung von den anderen unterscheidet")
   in einer .card--soft. Zwei Abschnitte, beide grau, beide reiner Fließtext
   ohne Überschrift, beide negativ definiert — und die getönte Karte nahm dem
   --surface-2-Band darunter die Kante, also genau das, was §19 für die
   Section DARUNTER verbietet. Dazu saß der Kartentext wegen der 28px
   Innenabstand neben der Seitenachse von H1, Lead und Antwort.

   Jetzt ein Abschnitt: die Einordnung ist Vorspann der Antwort, nicht ihr
   Vorgänger. Eine Fuge, die es nicht gibt, kann nicht klemmen. Die
   Einordnung sitzt auf einer weißen Platte, die rechts anschlägt und über
   die Oberkante des grauen Bandes tritt — zwei Flächen können nicht
   aneinanderstoßen, wenn sie sich überlappen. Dasselbe Prinzip trägt den
   Hero (.hero--split: das Medium greift vertikal in den Textblock).

   Die Antwort selbst ist unverändert: vollständig und sichtbar im DOM, nichts
   hinter einer Interaktion (§19, „Wichtig"). Interaktion gibt es hier keine —
   die Bewegung ist Reveal-gesteuert und hört nach einmal auf.

   Die 64px Luft nach oben gehören der Section, nicht dem Hero: die Platte
   holt sich davon 56px für die Überlappung zurück, sichtbar bleiben 64px
   plus die 72px Hero-Polsterung. Sonst müsste jede Seite, die den Block
   einbaut, ihre Hero-Polsterung anfassen.

   display:flow-root ist der Grund, warum die Überlappung überhaupt sichtbar
   wird: ohne eigenen Block-Formatierungskontext kollabiert der negative
   margin-top der Platte AUS der Section heraus und zieht die Bandkante mit
   nach oben. overflow-x:clip fängt die halbe Pixelbreite ab, die 50vw bei
   sichtbarer Scrollbar zu viel ist, sonst wackelt die Seite horizontal.

   Die Section DARUNTER darf kein .section--soft sein — dieselbe Regel wie
   bei §19, sonst verliert das Band seine untere Kante. */
.uebergabe-band {
  background: var(--surface-2);
  margin-top: 64px;
  padding: 0 0 64px;
  display: flow-root;
  overflow-x: clip;
}
.uebergabe { position: relative; }

/* Die Platte schlägt RECHTS an und läuft dort aus dem Satzspiegel bis zum
   Fensterrand heraus, gerundet nur links. Daraus entsteht der Versatz: die
   Einordnung sitzt rechts oben, die Antwort darunter links auf der
   Seitenachse. Zwei Achsen statt eines linksbündigen Textklotzes.
   Unterschied zum alten Fehler: 28px neben der Achse liest als
   Ungenauigkeit, ein Versatz von ~580px liest als Absicht. Die Achse selbst
   bleibt der Antwort, sie ist die Hauptsache.

   Die Breite ist so gerechnet, dass der Innenraum (520px) genau an der
   rechten Rasterkante endet — dieselbe Linie, an der die Trust-Bar und jeder
   andere Satzspiegel der Seite schließen. Die Fläche läuft darüber hinaus
   bis zum Fensterrand, der Text nicht: Satz am Raster, Fläche frei.
   padding-right trägt deshalb exakt die Bleed-Strecke ohne Zugabe.
   Die stille Fläche links unter der Platte ist die Gegenkraft zum rechten
   Anschlag. Wer sie füllt, hebt den Versatz wieder auf. */
.uebergabe__platte {
  position: relative;
  margin-top: -56px;
  margin-left: auto;
  margin-right: calc(50% - 50vw);
  width: calc(50vw - 50% + 560px);   /* 40px Innenabstand links + 520px Satz */
  padding: 30px calc(50vw - 50%) 28px 40px;
  background: var(--paper);
  border-radius: var(--radius-card) 0 0 var(--radius-card);
  box-shadow: var(--shadow-card);
}
.uebergabe__platte p { margin: 0; font-size: 17.5px; line-height: 1.55; max-width: none; }
.uebergabe__platte strong { color: var(--navy); }

/* Die drei Grundlagen sind der Kern des Satzes und gehen im Fließtext unter.
   Als eigene Zeile setzen sie versetzt ein. */
.uebergabe__grundlagen { display: flex; flex-wrap: wrap; gap: 8px 10px; list-style: none; margin: 18px 0 0; padding: 0; max-width: none; }
.uebergabe__grundlagen li {
  margin: 0; font-size: 13.5px; font-weight: 600; color: var(--navy);
  background: var(--navy-soft); border-radius: var(--radius-pill); padding: 5px 13px;
  opacity: 0; transform: translateY(5px);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.uebergabe.is-visible .uebergabe__grundlagen li { opacity: 1; transform: none; }
.uebergabe.is-visible .uebergabe__grundlagen li:nth-child(2) { transition-delay: .1s; }
.uebergabe.is-visible .uebergabe__grundlagen li:nth-child(3) { transition-delay: .2s; }

/* Die Übergabe: ein 3px-Strich auf der Seitenachse zwischen Platte und
   Antwort — dieselbe Marke wie am Eyebrow, nur senkrecht. Eine durchgehende
   Schiene neben dem Antworttext wäre lauter, würde ihn aber um ihre Breite
   von der Seitenachse schieben — genau der Fehler, den dieser Umbau behebt. */
.uebergabe__strich {
  width: 3px; height: 26px; margin: 34px 0 15px; border-radius: 2px;
  background: var(--orange);
  transform: scaleY(0); transform-origin: top;
  transition: transform .5s var(--ease) .25s;
}
.uebergabe.is-visible .uebergabe__strich { transform: scaleY(1); }

/* Unter 900px ist für einen Versatz kein Platz — die Platte würde die
   Textspalte auf Streichholzbreite drücken. Sie bleedet dann nach BEIDEN
   Seiten aus und wird zur weißen Stufe über die volle Fensterbreite: gleiche
   Idee (die Platte tritt über die Bandkante), nur ohne Versatz, und der Text
   sitzt wieder auf der Seitenachse. */
@media (max-width: 900px) {
  .uebergabe__platte {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: auto;
    padding-left: calc(50vw - 50%);
    padding-right: calc(50vw - 50%);
    border-radius: 0;
  }
  /* Ohne Versatz ist der Innenraum so breit wie die Section — für
     17,5px-Satz zu breit, also wieder deckeln. */
  .uebergabe__platte p { max-width: 62ch; }
}
@media (max-width: 700px) {
  .uebergabe-band { margin-top: 44px; padding-bottom: 44px; }
  .uebergabe__platte { margin-top: -40px; padding-top: 24px; padding-bottom: 22px; }
  .uebergabe__platte p { font-size: 16.5px; }
  .uebergabe__strich { margin: 24px 0 20px; height: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .uebergabe__strich { transform: scaleY(1); }
  .uebergabe__grundlagen li { opacity: 1; transform: none; }
}

/* ---------- 20. Funnel (C15) ---------- */
.funnel-section { scroll-margin-top: 90px; }
.funnel-box {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 36px;
  max-width: 720px;
  margin: 0 auto;
}
.section--soft .funnel-box { border-color: transparent; }
@media (max-width: 767px) { .funnel-box { padding: 24px 18px; } }

.funnel__progress { margin-bottom: 26px; }
.funnel__progress-label { font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 8px; display: flex; justify-content: space-between; font-variant-numeric: tabular-nums; }
.funnel__progress-track { height: 6px; background: var(--navy-soft); border-radius: var(--radius-pill); overflow: hidden; }
/* Die runden Enden kommen vom Track (overflow: hidden), damit der Fill
   skaliert werden kann, ohne dass der Radius mitgestaucht wird. */
.funnel__progress-fill { height: 100%; width: 100%; background: var(--orange); transform: scaleX(0); transform-origin: left; transition: transform .35s var(--ease); }

.funnel__question { font-size: clamp(20px, 2.4vw, 25px); font-weight: 700; letter-spacing: -0.018em; color: var(--navy); margin: 0 0 6px; line-height: 1.25; text-wrap: balance; }
.funnel__hint { font-size: 14px; color: var(--muted); margin: 0 0 22px; }

.funnel__tiles { display: grid; gap: 12px; margin: 0 0 8px; }
.funnel-tile {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 56px;
  text-align: left;
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-input);
  padding: 16px 18px;
  cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease), box-shadow .2s var(--ease);
}
.funnel-tile:hover { border-color: var(--navy); }
.funnel-tile.is-selected {
  border-color: var(--orange);
  background: #FFF4E7;
  box-shadow: 0 0 0 1px var(--orange) inset;
}
.funnel-tile__check {
  flex: none;
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px;
  color: transparent;
  transition: all .2s var(--ease);
}
.funnel-tile.is-selected .funnel-tile__check { background: var(--orange); border-color: var(--orange); color: #fff; }
.funnel-tile--multi .funnel-tile__check { border-radius: 7px; }

/* Eine Leiste, eine Höhe: "Zurück" links, Primär-Button rechts.
   flex-end + margin-right:auto, damit der Primär-Button auch rechts
   steht, wenn es (Screen 1) kein "Zurück" gibt.
   margin-top > Abstand der Formfelder untereinander (12–16px). */
.funnel__nav { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 16px; margin-top: 32px; }
/* Screen 1: nur der Weiter-Button, und der taucht erst mit der Auswahl auf.
   Die ganze Leiste wird ausgeblendet, damit auch ihr margin-top verschwindet. */
.funnel__nav--first:has(.btn[disabled]) { display: none; }
.funnel__back {
  margin-right: auto;
  background: none; border: none;
  font-family: var(--font-sans);
  font-size: 15px; font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  padding: 12px 8px;
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 48px;
}
.funnel__back:hover { color: var(--navy); }

/* Kontakt-Screen */
/* Ohne Hinweis unter der Frage standen die ersten Felder direkt an ihr
   (Anfrage-Formular, 09.10.2026): derselbe Abstand wie nach einem Hinweis. */
.funnel__question + .funnel__form, .funnel__question + .funnel__textfeld { margin-top: 22px; }
.funnel__fields { display: grid; gap: 16px; margin-bottom: 20px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 14px; font-weight: 600; color: var(--navy); }
.field input[type="text"], .field input[type="email"], .field input[type="tel"], .field input[type="search"], .field textarea, .field select {
  font-family: var(--font-sans);
  font-size: 16px;
  color: var(--ink);
  padding: 13px 14px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-input);
  background: var(--paper);
  width: 100%;
  min-height: 48px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
/* Nativer Pfeil klebt am Feldrand — deshalb eigener Chevron mit Innenabstand
   (gleiche Form wie .nav__caret) */
.field select {
  appearance: none; -webkit-appearance: none;
  padding-right: 44px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='m3 4.5 3 3 3-3' fill='none' stroke='%231E4975' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  cursor: pointer;
}
.field select:hover { border-color: var(--line-strong); }

.field input::placeholder, .field textarea::placeholder { color: #8A99A8; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(255, 148, 10, .22);
}
/* Auswahl und Textfeld mit: Die Anrede bekam bis 05.10.2026 keinen roten
   Rahmen, und seit das Anliegen auf /kontakt/ Pflicht ist, das Textfeld auch
   nicht. Beide zeigten den Fehler nur als Zeile darunter. */
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: var(--error); }
.field__error { font-size: 13px; color: var(--error); font-weight: 600; display: none; }
.field.has-error .field__error { display: block; }
.field__optional { font-weight: 400; color: var(--muted); }
/* Pflichtfelder: roter Stern direkt hinter der Beschriftung, Wunsch des
   Auftraggebers vom 05.10.2026 für alle Formulare (funnel.js, Newsletter).
   --error hat 4,9:1 auf Weiß. */
.field__pflicht { color: var(--error); font-weight: 700; margin-left: 2px; }
/* Hinweis unter einem Feld (feldAngaben.hinweis in funnel.js), etwa wofür
   die Mobilnummer gebraucht wird. Klein und gedämpft, damit er nicht wie ein
   Fehler aussieht. */
.field__hinweis { font-size: 13px; color: var(--muted); margin: 0; }

.checkbox-row { display: flex; gap: 12px; align-items: flex-start; font-size: 14px; }
.checkbox-row input[type="checkbox"] { width: 20px; height: 20px; flex: none; margin-top: 2px; accent-color: var(--orange); }
.checkbox-row.has-error label { color: var(--error); }
.privacy-note { font-size: 13px; color: var(--muted); margin: 14px 0 0; }

/* Danke-Screen */
.funnel__danke { text-align: center; padding: 24px 0; }

.funnel__danke h3 { font-size: 23px; }
.funnel__danke p { margin-left: auto; margin-right: auto; }

/* Freitext-Bildschirm (typ: 'text', seit 09.10.2026 im Anfrage-Formular):
   „Überspringen“ steht als stiller Textknopf links neben „Weiter“, damit
   der Primärknopf der einzige orange bleibt. Der Zähler erscheint erst kurz
   vor der Höchstlänge (funnel.js). */
.funnel__textfeld textarea { min-height: 148px; resize: vertical; }
.funnel__zaehler { text-align: right; min-height: 1.4em; }
.funnel__skip {
  background: none; border: none;
  font-family: var(--font-sans);
  font-size: 15px; font-weight: 600;
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  padding: 12px 8px;
  min-height: 48px;
}
.funnel__skip:hover { color: var(--orange-text); }
/* Zwei Knöpfe in der Fehlermeldung des Anfrage-Formulars: Kalender und Mail. */
.funnel__knoepfe { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }

/* ---------- 20a. Standard-Anfrageformular (Block „anfrage“, seit 09.10.2026) ----------
   Das Standard-Anfrageformular, universell und mit Terminvereinbarung (Spezifikation
   P1.1, Auftraggeber: „Das wird das Standardformular“). Ein Block über die
   volle Breite des Containers, abgesetzt als Fläche in --navy-soft, damit er
   sich auf weißen wie auf weichen Sections vom Rest der Seite abhebt: links
   Überschrift, Unterzeile und die fünf Gesichter fürs Erstgespräch, rechts
   die Strecke im gewohnten weißen Kasten (.funnel-box). Markup schreibt
   scripts/leistungsbloecke.py, auf jeder Seite gleich. Unter 1024px steht
   der Text über dem Formular. */
.anfrage {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 56px;
  align-items: start;
  background: var(--navy-soft);
  border-radius: var(--radius-card);
  padding: 56px;
}
.anfrage__intro h2 { margin-bottom: 16px; }
.anfrage__intro .lead { margin-bottom: 0; }
.anfrage__team { display: flex; align-items: center; gap: 16px; margin-top: 32px; }
.anfrage__gesichter { display: flex; flex: none; }
.anfrage__gesichter .img-placeholder--avatar { width: 52px; height: 52px; box-shadow: 0 0 0 3px var(--navy-soft); }
.anfrage__gesichter .img-placeholder--avatar + .img-placeholder--avatar { margin-left: -12px; }
.anfrage__namen { font-size: 14px; line-height: 1.5; color: var(--muted); margin: 0; }
.anfrage__namen strong { display: block; color: var(--navy); }
.anfrage__belege { margin: 24px 0 0; }
/* Dieselbe Reihe Gesichter mittig unter den Schritten der Terminseiten. */
.anfrage__team--mitte { justify-content: center; margin-top: 48px; }
.anfrage__team--mitte .anfrage__gesichter .img-placeholder--avatar { box-shadow: 0 0 0 3px var(--surface-2); }
.anfrage .funnel-box { max-width: none; margin: 0; border-color: transparent; }
@media (max-width: 1024px) {
  .anfrage { grid-template-columns: minmax(0, 1fr); gap: 32px; padding: 40px; }
}
/* Schmal: Fläche, Kasten und Kachel tragen je eigene Ränder. Bei 320px blieben
   für den Kacheltext sonst nur rund 170px, „Kunden systematischer gewinnen
   und betreuen“ brach vierzeilig. Mit den engeren Abständen sind es rund 200px. */
@media (max-width: 767px) {
  .anfrage { padding: 28px 8px 8px; gap: 24px; }
  .anfrage__intro { padding: 0 10px; }
  .anfrage__team { align-items: flex-start; flex-direction: column; gap: 10px; margin-top: 24px; }
  .anfrage__team--mitte { align-items: center; text-align: center; margin-top: 40px; }
  .anfrage .funnel-box { padding: 20px 12px; }
  .anfrage .funnel-tile { padding: 14px 12px; gap: 10px; }
}

/* Terminseiten (/termin/geschaeftsfuehrung/, /termin/vertrieb/): Gruß mit
   dem Vornamen aus dem Anfrage-Formular, erst sichtbar, wenn main.js ihn
   gefunden hat (data-termin-gruss). */
.termin-gruss { font-size: var(--text-lead); font-weight: 600; color: var(--navy); margin: 0 0 8px; }

/* ---------- 21. Sticky-Mobile-CTA (C16) ---------- */
.sticky-cta {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -12px 32px -16px rgba(22, 51, 79, .25);
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  display: none;
  align-items: center;
  gap: 10px;
  transform: translateY(110%);
  transition: transform .35s var(--ease);
}
.sticky-cta.is-visible { transform: translateY(0); }
.sticky-cta .btn { flex: 1; padding: 12px 16px; font-size: 16px; }
.sticky-cta__close {
  flex: none;
  background: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  width: 44px; height: 44px;
  font-size: 17px;
  color: var(--muted);
  cursor: pointer;
}
@media (max-width: 860px) { .sticky-cta { display: flex; } }

/* ---------- 22. Footer (C17) ---------- */
.site-footer {
  background: var(--navy-deep);
  color: #C9D8E6;
  padding: 72px 0 36px;
  font-size: 15px;
}
.site-footer a, .footer-legal__knopf { color: #E8F0F7; text-decoration: none; }
.site-footer a:hover, .footer-legal__knopf:hover { color: var(--orange); text-decoration: underline; }
.site-footer h3 { color: #fff; font-size: 12px; letter-spacing: .01em; margin-bottom: 18px; }
/* Spaltenbreiten folgen der Länge der Überschriften — sonst bricht
   „Wissen & Unternehmen" um und die Links stehen nicht mehr auf einer Linie. */
.footer-grid { display: grid; grid-template-columns: 1.4fr .95fr .95fr 1fr 1.2fr; gap: 40px; margin-bottom: 48px; }
@media (max-width: 1024px) { .footer-grid { grid-template-columns: repeat(3, 1fr); gap: 32px 40px; } }
@media (max-width: 860px) { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 767px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer ul { list-style: none; padding: 0; margin: 0; max-width: none; }
.site-footer li { margin-bottom: 10px; }
/* 27 Footer-Links pro Seite standen mobil 20px hoch bei 34px Raster. Das
   erfüllt WCAG 2.2 nur über die Spacing-Ausnahme und trifft sich mit dem
   Daumen schlecht. Als Block mit Polster wird die Zeile selbst zum Ziel:
   36px Höhe, das Raster bleibt durch das kleinere li-margin gleich. */
@media (max-width: 767px) {
  .footer-grid li { margin-bottom: 2px; }
  .footer-grid li a { display: block; padding: 8px 0; }
}
/* Die Herkunft gehört zum Absender, nicht ins Copyright. Stand vorher als
   Anhang in der Rechtszeile — zusammen mit dem Trust-Streifen war das die
   dritte Trust-Dosis in einem Footer. */
.footer-origin { margin-top: 10px; font-size: 14px; color: #9FB8CE; }
/* Zwei Adressen unter der Herkunft (Auftraggeber, 08.10.2026): Büro und Besucheradresse,
   Firmensitz. Gleiche Farben wie der übrige Fußtext, <address> ohne Kursiv. */
.footer-adressen { margin-top: 18px; font-style: normal; font-size: 14px; line-height: 1.55; color: #D6E2EE; }
.footer-adressen p { margin: 0 0 12px; max-width: none; }
.footer-adressen p:last-child { margin-bottom: 0; }
.footer-adressen strong { color: #fff; }
.footer-adressen__hinweis { display: block; color: #9FB8CE; }

/* Belege stehen bei den nachprüfbaren Angaben, nicht in einem eigenen Block.
   Vorher: sieben gleich gewichtete Belege zwischen zwei Haarlinien — davon
   stand das meiste auf 17 von 20 Seiten schon oben in der .trust-bar, und
   Wiederholung ohne neue Information liest sich als Behauptung, nicht als
   Beleg. Geblieben ist das institutionell Nachprüfbare: Partnerstatus, Norm,
   Trägerzulassung, Datenhaltung. Von den zwei Haarlinien bleibt eine. */
.footer-legal { display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: space-between; align-items: flex-start; border-top: 1px solid rgba(255,255,255,.12); padding-top: 22px; font-size: 13px; color: #8FA8BF; }
.footer-legal ul { display: flex; flex-wrap: wrap; gap: 16px; }
.footer-legal li { margin: 0; }
/* „Cookie-Einstellungen“ als letzter Eintrag der Rechtszeile (seit 10.10.2026, O3): eine Schaltfläche, kein Link, weil
   sie das Banner von Cookiebot öffnet und nirgendwohin führt (ein href="#" wäre ein Fehler). Farben wie die Rechtslinks
   (oben bei .site-footer a), Unterstrich-Abstand und Übergang wie bei jedem Link (Abschnitt 2); vom Knopf bleibt nichts:
   kein Rahmen, kein Hintergrund, Schrift und Zeilenhöhe der Zeile. Bis Cookiebot geladen ist, tragen sie und ihr
   Listeneintrag hidden (main.js); deshalb hier kein display. */
.footer-legal__knopf {
  margin: 0; padding: 0; border: 0; background: none; font: inherit; cursor: pointer;
  text-underline-offset: 3px; transition: color .15s ease, text-decoration-color .15s ease;
}
/* Copyright und Belege in einer Zeile, mit Abstand dazwischen (Auftraggeber, 08.10.2026: „unten etwas
   aufgeräumter“). Reicht der Platz nicht, rutschen die Belege in die nächste Zeile. */
.footer-legal__left { display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px 32px; flex: 1 1 auto; min-width: 0; }
/* max-width: none ist Pflicht — main.css deckelt <p> auf Lesebreite, sonst
   bricht die Zeile schon bei 491px um statt bei den verfügbaren 773px. */
.footer-proof { display: flex; flex-wrap: wrap; gap: 4px 10px; margin: 0; max-width: none; color: #A8C0D6; }
.footer-proof span::after { content: "·"; margin-left: 10px; color: rgba(255,255,255,.28); }
.footer-proof span:last-child::after { content: none; }
.footer-proof a { color: #A8C0D6; text-decoration: underline; text-decoration-color: rgba(255,255,255,.22); text-underline-offset: 3px; }
/* Gemessen: die Zeile bricht ab 624px Viewport um (bis 767px hilft noch der
   Umbruch der Rechtslinks in eine eigene Zeile). Ab da lieber eine Liste ohne
   Trennzeichen — ein „·", das am Zeilenende allein stehen bleibt, ist
   schlechter als gar keins. */
@media (max-width: 767px) {
  .footer-legal__left { display: grid; gap: 7px; }
  .footer-proof { display: grid; gap: 6px; }
  .footer-proof span::after { content: none; }
}

/* ---------- 23. Bild-Platzhalter (C18) ----------
   Der Platzhalter ist ein echtes <figure> mit einem echten <img> darin, damit
   Parser, Screenreader und das CMS sehen, dass hier ein Bild hingehört — inkl.
   Alt-Text und Seitenverhältnis. Das <img> zeigt ein transparentes SVG und
   liegt unter der Beschriftung. Kommt das echte Asset: src tauschen,
   <figcaption> löschen, fertig. */
.img-placeholder {
  position: relative;
  overflow: hidden;
  margin: 0;
  /* Fünf Platzhalter tragen eine Inline-Breite (flex:none;width:280px), damit
     das Medium in .case-card--big neben dem Zitat nicht mitwächst. Gestapelt
     auf dem Handy ist diese Breite ein harter Boden: bei 320px Fenster bleiben
     im Karteninneren 224px, die Figur stand auf 280px und schob die Seite nach
     rechts. max-width deckelt die Inline-Breite, ohne sie zu ersetzen. */
  max-width: 100%;
  background:
    repeating-linear-gradient(-45deg, transparent 0 10px, rgba(30, 73, 117, .035) 10px 20px),
    var(--navy-soft);
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--radius-card);
  color: var(--muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 24px;
  min-height: 220px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .02em;
}
.img-placeholder--portrait { min-height: 300px; }

.img-placeholder--34 { aspect-ratio: 3 / 4; min-height: 0; }
.img-placeholder--43 { aspect-ratio: 4 / 3; min-height: 0; }

.img-placeholder--video { aspect-ratio: 16 / 9; min-height: 0; position: relative; }
.img-placeholder--video::before {
  content: "";
  /* über dem <img>, damit der Play-Button auch auf einem echten Poster liegt */
  position: relative; z-index: 1;
  width: 60px; height: 60px;
  border-radius: 50%;
  background: var(--navy) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6 4.5v7L12 8z' fill='%23fff'/%3E%3C/svg%3E") center / 22px no-repeat;
}
.img-placeholder--avatar {
  border-radius: 50%;
  width: 96px; height: 96px;
  min-height: 0;
  padding: 8px;
  font-size: 10px;
}
/* Echtes Foto im Avatar-Slot statt des Platzhalters. Beschnitt, Polster und
   margin kommen sonst von .img-placeholder — fehlt die Klasse, saesse das Bild
   eckig im runden Rahmen und mit 8px Polster darin.
   :not(.img-placeholder) trifft genau diesen Fall; die Platzhalter-Avatare auf
   den uebrigen Seiten bleiben unberuehrt. */
.img-placeholder--avatar:not(.img-placeholder) {
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.img-placeholder--avatar:not(.img-placeholder) > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.img-placeholder > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.img-placeholder__label {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.img-placeholder__format { font-size: 11px; color: #8A99A8; font-weight: 400; }
/* Livebau (build-netlify.py --live, T8): Der Platzhalter verliert seinen
   Arbeitshinweis und zeigt bis zum echten Bild (T20) eine ruhige Fläche statt
   Strichrahmen und Streifen; ein Video-Platzhalter ohne Video zeigt keinen
   Play-Knopf. In der Testfassung kommt die Klasse nicht vor. */
.img-placeholder--ruhig { background: var(--navy-soft); border-color: transparent; }
.img-placeholder--ruhig::before { display: none; }

/* ---------- 24. Score-Ergebnis (C19) ---------- */
.score-result { text-align: center; }
.gauge { width: 240px; margin: 0 auto 8px; display: block; }
.gauge__value { font-size: 44px; font-weight: 700; fill: var(--navy); font-variant-numeric: tabular-nums; }
.gauge__label { font-size: 13px; fill: var(--muted); }

.stufen-bars { display: grid; gap: 12px; max-width: 560px; margin: 32px auto; text-align: left; }
.stufen-bar { display: grid; grid-template-columns: 180px 1fr 40px; gap: 12px; align-items: center; font-size: 14px; }
@media (max-width: 767px) { .stufen-bar { grid-template-columns: 120px 1fr 36px; font-size: 13px; } }
.stufen-bar__label { font-weight: 600; color: var(--ink); }
.stufen-bar__track { height: 8px; background: var(--navy-soft); border-radius: var(--radius-pill); overflow: hidden; }
.stufen-bar__fill { height: 100%; background: var(--navy); border-radius: var(--radius-pill); }
.stufen-bar--hebel .stufen-bar__fill { background: var(--orange); }
.stufen-bar__val { font-weight: 700; color: var(--navy); text-align: right; font-variant-numeric: tabular-nums; }

.hebel-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 24px 0 32px; text-align: left; }
@media (max-width: 860px) { .hebel-cards { grid-template-columns: 1fr; } }
.hebel-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 24px;
  background: var(--paper);
}
.hebel-card h4 { margin-bottom: 6px; }
.hebel-card p { font-size: 14px; color: var(--muted); margin-bottom: 10px; }
.hebel-card a { font-size: 14px; font-weight: 600; }

.score-offer { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 32px; text-align: left; }
@media (max-width: 767px) { .score-offer { grid-template-columns: 1fr; } }
.score-offer .card h3 { font-size: 18px; }
.score-offer form { display: flex; gap: 10px; flex-wrap: wrap; }
.score-offer form input[type="email"] {
  flex: 1; min-width: 200px;
  font-family: var(--font-sans); font-size: 16px;
  padding: 12px 14px; border: 1.5px solid var(--line); border-radius: var(--radius-input);
  min-height: 48px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.score-offer form input[type="email"]:focus { outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px rgba(255, 148, 10, .22); }

/* ---------- 24b. KI-Ablauf einer Stufe (Zeitachse mit Auswahl) ----------
   Ersetzt auf den Stufen-Seiten das grid-3-Kartenraster der Section
   "KI in dieser Stufe". Grund: die Section davor ist auf denselben Seiten
   ebenfalls ein grid-3 mit .card, zwei gleiche Raster direkt
   untereinander lassen die Seite boxig wirken. Die KI-Funktionen greifen
   ausserdem nacheinander in den Lead-Weg ein, das ist eine Reihenfolge und
   keine Sammlung gleichwertiger Kacheln.

   Anzahl der Stationen über --stations, damit die Linie ohne neue Regel
   auch bei vier oder fünf Stationen an den äusseren Markern endet.
   Die Auswahl läuft über echte Radios (Pfeiltasten funktionieren) und
   :has(), ohne JavaScript und ohne seitenspezifische IDs in dieser Datei. */
.ki-flow { --stations: 3; }

.ki-flow__axis {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--stations), 1fr);
  max-width: 940px;
  margin: 0 auto;
  text-align: center;
}
.ki-flow__axis input {
  position: absolute;
  width: 1px; height: 1px; margin: -1px;
  clip: rect(0 0 0 0);
  overflow: hidden;
}
/* Schiene wie .steps--center::before auf /kundensystem/: 3px oranger Vollton
   mit durchlaufendem Puls, damit die beiden Ablauf-Bausteine gleich aussehen.
   Sie läuft von der Mitte des ersten bis zur Mitte des letzten Markers: bei n
   gleichen Spalten ohne gap sind das 50%/n von jeder Seite. Über die letzte
   Station hinaus läse sich die Linie wie ein Ablauf, der noch weitergeht.
   Läuft beim Sichtbarwerden in Leserichtung auf und zeigt damit die Richtung
   des Ablaufs. Braucht .reveal auf .ki-flow, den Rest macht main.js. */
.ki-flow__axis::after {
  content: "";
  position: absolute;
  left: calc(50% / var(--stations));
  right: calc(50% / var(--stations));
  top: 9.5px;                       /* Marker 20px hoch, Schiene 3px → mittig */
  height: 3px;
  border-radius: var(--radius-pill);
  background:
    linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.75) 50%, rgba(255,255,255,0) 100%) no-repeat,
    var(--orange);
  background-size: 34% 100%, auto;
  animation: steps-rail 3.2s var(--ease) infinite;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1s var(--ease) .15s;
}
.ki-flow.is-visible .ki-flow__axis::after { transform: scaleX(1); }

/* z-index, damit die Marker über der Schiene liegen. Ohne das gewinnt
   ::after der Achse (kommt in der Malreihenfolge nach den Labels) und die
   Linie ragt sichtbar in die Kreise. */
.ki-flow__station {
  position: relative;
  z-index: 1;
  cursor: pointer;
  padding: 40px 18px 0;
  /* Schriftstile wie .steps h3 / .steps p auf /kundensystem/. */
  font-weight: 700;
  font-size: 18px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--muted);
  transition: color .2s var(--ease);
}
.ki-flow__station:hover { color: var(--navy); }
.ki-flow input:checked + .ki-flow__station { color: var(--navy); }
.ki-flow input:focus-visible + .ki-flow__station { outline: 2px solid var(--orange); outline-offset: 4px; }

/* Marker auf der Linie: zeigt die Position im Ablauf. 20px, damit der Punkt
   ein ausreichendes Klickziel ist. Füllung wie .steps li::before — grau als
   Grundzustand, auf --soft-Flächen weiss mit Haarlinie, weil grau auf grau
   verschwindet. Deckt die Schiene ab, deshalb deckende Farbe, kein Ring. */
.ki-flow__station::before {
  content: "";
  position: absolute;
  left: 50%; top: 1px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--navy-soft);
  transform: translateX(-50%);
  transition: box-shadow .25s var(--ease), transform .25s var(--ease), background .25s var(--ease);
}
.section--soft .ki-flow__station::before { background: var(--navy-soft); box-shadow: inset 0 0 0 1px var(--line-strong); }
/* Hover nur als Ring — Orange ist hier für „ausgewählt" reserviert, anders als
   bei .steps, wo es keinen aktiven Zustand gibt. */
.ki-flow__station:hover::before { box-shadow: inset 0 0 0 2px var(--line-strong); }
.ki-flow input:checked + .ki-flow__station::before {
  background: var(--orange);
  box-shadow: none;
  /* translateX muss mit, sonst springt der Marker aus der Spaltenmitte. */
  transform: translateX(-50%) scale(1.15);
}
.ki-flow__moment { display: block; font-weight: 400; font-size: 15px; line-height: 1.6; letter-spacing: normal; color: var(--muted); margin-top: 6px; }

/* Erklärkarte folgt der gewählten Station: erste Station → links am Raster,
   letzte → rechts, alles dazwischen mittig. Damit zeigt die Karte selbst,
   wo im Ablauf man steht, statt die Zuordnung nur über die Farbe zu tragen.
   Alle Karten liegen in derselben Rasterzelle und werden über Sichtbarkeit
   getauscht, nicht über display. Damit ist die Höhe automatisch die der
   längsten Karte und der Wechsel kann nicht springen, egal wie lang die
   Texte je Stufen-Seite ausfallen. visibility:hidden nimmt die inaktiven
   Karten auch aus Screenreader und Tab-Reihenfolge. */
.ki-flow__detail { display: grid; margin: 52px auto 0; max-width: 620px; }
.ki-flow:has(input:nth-of-type(1):checked) .ki-flow__detail { margin-left: 0; }
.ki-flow:has(input:last-of-type:checked) .ki-flow__detail { margin-right: 0; }
.ki-flow__detail > .card {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transition: opacity .25s var(--ease);
}
.ki-flow:has(input:nth-of-type(1):checked) .ki-flow__detail > .card:nth-child(1),
.ki-flow:has(input:nth-of-type(2):checked) .ki-flow__detail > .card:nth-child(2),
.ki-flow:has(input:nth-of-type(3):checked) .ki-flow__detail > .card:nth-child(3),
.ki-flow:has(input:nth-of-type(4):checked) .ki-flow__detail > .card:nth-child(4) {
  visibility: visible;
  opacity: 1;
}
.ki-flow__detail .card h3 { font-size: 18px; margin-bottom: 10px; }
.ki-flow__detail .card p { font-size: 17px; margin-bottom: 0; }
.ki-flow__detail .card .btn-arrow { margin-top: 0; }

@media (max-width: 767px) {
  /* Aus der mittigen waagerechten Achse wird eine linke senkrechte: drei
     zentrierte Stationen auf 350px funktionieren nicht. */
  .ki-flow__axis { grid-template-columns: 1fr; max-width: none; padding-left: 34px; text-align: left; }
  /* Senkrecht kann eine durchlaufende Schiene nicht an der Mitte des letzten
     Markers enden: deren Abstand zum unteren Rand hängt an der Textlänge der
     letzten Station. Deshalb zeichnet hier jede Station ihr eigenes Segment
     bis zum nächsten Marker, die letzte keins. Der Puls läuft über
     background-position waagerecht und bringt auf 3px Breite nichts, deshalb
     nur der Vollton. */
  .ki-flow__axis::after { display: none; }
  .ki-flow__station::after {
    content: "";
    position: absolute;
    left: -25.5px;            /* Marker: -34px + 20px/2 → Mitte -24px, minus 1,5px */
    top: 11px;                /* Mitte des eigenen Markers */
    bottom: -11px;            /* Mitte des nächsten Markers (Zeilen liegen ohne gap aneinander) */
    width: 3px;
    border-radius: var(--radius-pill);
    background: var(--orange);
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform .5s var(--ease) .15s;
  }
  .ki-flow__station:last-of-type::after { display: none; }
  .ki-flow.is-visible .ki-flow__station::after { transform: scaleY(1); }
  .ki-flow__station { padding: 0 0 24px 0; }
  .ki-flow__station::before { left: -34px; top: 1px; transform: none; }
  .ki-flow input:checked + .ki-flow__station::before { transform: scale(1.15); }
  /* Einspaltig: die Karte steht immer voll unter der Achse, die
     Links/Mitte/Rechts-Zuordnung greift nur bei waagerechter Achse. */
  .ki-flow__detail { margin: 24px 0 0; max-width: none; }
}

/* ---------- 25. Prozess-Schritte ---------- */
/* --cols hält die Spaltenzahl als Zahl fest, weil grid-template-columns nicht
   rückrechenbar ist: .steps--center::before braucht sie, um die Schiene auf die
   Kreismitten zu setzen. Gleiches Muster wie --stations bei .ki-flow. */
.steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px; counter-reset: step; list-style: none; padding: 0; max-width: none; --cols: 4; }
.steps--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); --cols: 3; }
/* Vier Spalten standen bis 860px. Gemessen bei 900px: 199px pro Schritt, also
   fünf Zeilen à 25 Zeichen — und sobald ein Titel zweizeilig wird, verlieren
   die Nummern ihre gemeinsame Grundlinie. Als 2x2 bleibt die Reihenfolge
   lesbar (links→rechts, dann Zeile zwei) und jeder Schritt bekommt 360–490px.
   .steps--3 hält seine drei Spalten bis 860: dort sind es bei 900px noch
   277px, und ein Dreischritt zerfällt in 2+1 statt in 2x2.

   Bleibt: zwischen 1025 und 1150px stehen weiter vier Spalten, bei 1100px mit
   249px. Das ist die schmalste Stelle, die dieser Baustein noch hat — sie
   trifft nur Laptops mit verkleinertem Fenster, alle üblichen Breiten
   (1280/1366/1440/1512/1920) liegen bei 274px und mehr. Ein vierter Umbruch
   bei 1200px würde das schliessen, dafür aber das Drei-Werte-System des
   Guides aufbrechen; auto-fit würde beim Vierschritt 3+1 erzeugen und die
   Reihenfolge unleserlich machen. Deshalb hier die Grenze und kein Wert mehr. */
/* :not(.steps--3), weil `.steps` hier sonst die drei Spalten von oben
   überschreibt — gleiche Spezifität, aber später in der Datei. Ohne das
   zerfiel der Dreischritt entgegen dem Absatz oben schon ab 1024px in 2+1. */
@media (max-width: 1024px) { .steps:not(.steps--3) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Erster Selektor mit demselben :not() wie oben, sonst schlaegt die
   1024er-Regel (0,2,0) diese hier (0,1,0) und der Vierschritt bliebe bis 320px
   zweispaltig — bei 320px waeren das 126px je Schritt. */
@media (max-width: 860px) { .steps:not(.steps--3), .steps--3 { grid-template-columns: minmax(0, 1fr); max-width: 767px; } }
.steps li { counter-increment: step; position: relative; padding-top: 54px; margin: 0; }
.steps li::before {
  content: counter(step);
  position: absolute; top: 0; left: 0;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--navy-soft);
  color: var(--navy);
  font-weight: 700;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s ease, color .2s ease;
}
.section--soft .steps li::before { background: #fff; box-shadow: inset 0 0 0 1px var(--line); }
/* Gleiches Hover-Verhalten wie .stufe-card__num: Zahlkreise sehen überall
   gleich aus. Ziffer auf Orange ist anthrazit, nicht weiss — wie beim
   .btn--primary; Weiss auf #FF940A liegt bei 2,1:1 und fällt durch. */
.steps li:hover::before { background: var(--orange); color: var(--ink); box-shadow: none; }
.steps h3 { font-size: 18px; margin-bottom: 8px; }
.steps p { font-size: 15px; margin: 0; }

/* Zentrierte Variante mit durchlaufender Linie (/kundensystem/).
   Nummer über dem Text statt daneben, Linie auf Höhe der Kreismitte. */
.steps--center { position: relative; }
.steps--center li { padding-top: 0; text-align: center; }
.steps--center li::before {
  position: relative; z-index: 1;   /* liegt über der Linie und deckt sie ab */
  top: auto; left: auto;
  margin: 0 auto 16px;
}
.steps--center p { margin-inline: auto; }
/* Die Linie beginnt in der Mitte des ersten und endet in der Mitte des
   letzten Kreises. Bei n gleichen Spalten mit gap g liegt diese Mitte bei
   50%/n − (n−1)·g / (2n) — deshalb die krummen Werte, nicht glatt 100%/2n.
   Aufgelöst: n = 3 → 16,67% − 9,33px, n = 4 → 12,5% − 10,5px. */
.steps--center::before {
  content: "";
  position: absolute;
  top: 18px;                        /* Kreis 38px hoch, Linie 3px → mittig */
  left: calc(50% / var(--cols) - 14px * (var(--cols) - 1) / var(--cols));
  right: calc(50% / var(--cols) - 14px * (var(--cols) - 1) / var(--cols));
  height: 3px;
  border-radius: var(--radius-pill);
  background:
    linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.75) 50%, rgba(255,255,255,0) 100%) no-repeat,
    var(--orange);
  background-size: 34% 100%, auto;
  animation: steps-rail 3.2s var(--ease) infinite;
}
/* Puls läuft links → rechts; ausserhalb -50%/150% ist er unsichtbar. */
@keyframes steps-rail {
  from { background-position: -50% 0; }
  to   { background-position: 150% 0; }
}
/* Der Vierschritt bricht ab 1024px auf 2x2 um, der Dreischritt erst ab 860px
   auf eine Spalte. Sobald der Ablauf mehr als eine Zeile hat, verbände die
   waagerechte Schiene nur noch die erste Zeile — dann weg damit. */
@media (max-width: 1024px) { .steps--center:not(.steps--3)::before { display: none; } }
@media (max-width: 860px) { .steps--center::before { display: none; } }

/* ---------- 26. Checkliste ---------- */
.check-list { list-style: none; padding: 0; }
.check-list li { padding-left: 34px; position: relative; margin-bottom: 13px; }
.check-list li::before {
  content: "";
  position: absolute; left: 0; top: 3px;
  width: 20px; height: 20px;
  background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%231E4975' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 17px no-repeat;
}
.section--navy .check-list li::before, .cta-block .check-list li::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%23FF940A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Aufzählung als Zeilen mit Haarlinien: mehr Luft, wenn die Liste die
   tragende Aussage eines Textblocks ist und nicht nur eine Ergänzung. */
.check-list--rows { margin: 24px 0 28px; }
.check-list--rows li { padding: 14px 0 14px 34px; margin: 0; border-top: 1px solid var(--line); }
.check-list--rows li::before { top: 17px; }
.check-list--rows li:last-child { border-bottom: 1px solid var(--line); }
/* Haken im Kreis, Maße und Hover-Verhalten wie die Zahlkreise der
   Prozess-Schritte (Abschnitt 25): 38px, in .section--soft weiß mit Haarlinie,
   beim Hover der ganzen Zeile Orange. Der Haken ist im Ruhezustand orange und
   wird auf der orangen Fläche anthrazit — zwei Data-URIs, weil var() darin
   nicht ausgewertet wird (siehe --x/--ok).
   Nur mit .check-list--rows sinnvoll: die Zeilenhöhe trägt den Kreis. */
/* Trenner einen Ton dunkler als die --rows-Haarlinie: neben den 38px-Kreisen
   verschwand --line optisch. --line-strong ist genau dafür da. */
.check-list--circles li { padding-left: 52px; border-color: var(--line-strong); }
.check-list--circles li::before {
  top: 8px;
  width: 38px; height: 38px;
  border-radius: 50%;
  background-color: var(--navy-soft);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%23FF940A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 18px;
  transition: background-color .2s ease, box-shadow .2s ease;
}
.section--soft .check-list--circles li::before { background-color: #fff; box-shadow: inset 0 0 0 1px var(--line); }
.check-list--circles li:hover::before {
  background-color: var(--orange);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%23191919' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  box-shadow: none;
}

/* Status-Paar für „passt / passt nicht“-Aufzählungen. Die Farben sind die
   Tokens --success (#1E8E57) und --error (#D23B2E) aus Abschnitt 1 — hier hart
   notiert, weil in einer Data-URI kein var() ausgewertet wird. Beim Ändern
   eines Tokens diese beiden Hex-Werte mitziehen.

   Das Kreuz ist über .is-negative fest an das negative Listenelement gebunden,
   der grüne Haken braucht dagegen den Modifier --ok: der blanke .check-list-
   Haken steht überall auf der Seite (Hero, CTA, Navy) und bleibt navy. */
.check-list--x li.is-negative::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' fill='none' stroke='%23D23B2E' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
/* Höhere Spezifität hat die --x-Regel oben, ein Kreuz in einer --ok-Liste
   bleibt also rot — gemischte Listen (Erstgespräch) funktionieren so. */
.check-list--ok li::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 4.5' fill='none' stroke='%231E8E57' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* ---------- 26b. Kriterien-Zeilen („Für wen das der richtige Weg ist") ----------
   Textblock und Aufzählung nebeneinander, die Aufzählung als vier große Zeilen
   mit Ziffer. Zwei Dinge sind hier Absicht und dürfen nicht wegoptimiert werden:

   1. min-height auf der Zeile. Die Sätze sind unterschiedlich lang; ohne die
      Mindesthöhe ist eine Zeile 44px hoch und die nächste 66px, und die
      Aufzählung wirkt kaputt statt gesetzt. Der Wert deckt genau zwei Zeilen
      Fließtext auf 19px ab — ab drei Zeilen wächst sie wieder mit.
   2. Beim Hover wandert nur der INHALT nach rechts (transform auf den Kindern),
      nicht das <li>. Verschiebt man das li, ragt es über den Spaltenrand und
      die Trennlinien wackeln mit.

   Die Textspalte bleibt beim Scrollen stehen (top: 96px wie Lese-Rail und
   Zeitstrahl) und löst sich ab 860px auf, wo alles einspaltig läuft. */
.kriterien-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 64px; align-items: start; }
.kriterien-grid__text { position: sticky; top: 96px; }

.kriterien { list-style: none; margin: 0; padding: 0; max-width: none; }
.kriterien li {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 88px;
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
  border-top: 1px solid var(--line);
  transition: background .25s var(--ease);
}
.kriterien li:last-child { border-bottom: 1px solid var(--line); }
/* Versetztes Einblenden wie bei .quick-answer und .uebergabe: im CSS über
   nth-child, damit im HTML keine Zähl-Klassen mitgepflegt werden müssen. */
.kriterien li.reveal:nth-child(2) { transition-delay: .08s; }
.kriterien li.reveal:nth-child(3) { transition-delay: .16s; }
.kriterien li.reveal:nth-child(4) { transition-delay: .24s; }
.kriterien li > * { transition: transform .25s var(--ease), background .25s var(--ease), color .25s var(--ease); }
.kriterien li:hover { background: var(--surface-2); }
.kriterien li:hover > * { transform: translateX(var(--space-3)); }
.kriterien li p { margin: 0; max-width: none; font-size: var(--text-lead); line-height: 1.45; }
.kriterien__nr {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  background: var(--navy-soft); color: var(--navy);
  font-weight: 700; font-size: var(--text-h4); font-variant-numeric: tabular-nums;
}
.kriterien li:hover .kriterien__nr { background: var(--orange); color: var(--ink); }
/* Auf getönter Bahn hebt --surface-2 nicht ab; dort ist Weiß die Hervorhebung. */
.section--soft .kriterien li:hover { background: var(--paper); }

@media (max-width: 1024px) { .kriterien-grid { gap: 40px; } }
@media (max-width: 860px) {
  .kriterien-grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
  .kriterien-grid__text { position: static; }
  .kriterien li { min-height: 0; }
}
@media (max-width: 767px) {
  .kriterien li { gap: var(--space-4); }
  .kriterien li p { font-size: var(--text-body); }
  .kriterien__nr { width: 36px; height: 36px; font-size: var(--text-small); }
}

/* ---------- 28. Zitat-Block ----------
   Statement-Auftritt: der Satz steht auf der H1-Stufe, weil er die einzige
   Aussage seiner Section ist — keine eigene Display-Groesse dafuer (siehe
   Abschnitt 1). Die Auszeichnung im Satz macht der .swoosh, nicht ein zweiter
   Farbton; darunter schliesst ein kurzer Strich den Block ab. */
.quote-block { max-width: 760px; margin: 0 auto; text-align: center; }
.quote-block blockquote {
  font-size: var(--text-h1);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--navy);
  line-height: 1.2;
  margin: 0 0 24px;
  position: relative;
  text-wrap: balance;
}
/* Beide Zeichen kommen aus dem CSS, damit sie sicher gleich aussehen.
   Schriftgröße wie der Text und keine vertikale Verschiebung: das 1.4em große
   Zeichen mit vertical-align sass sonst schief im ersten Wort. */
.quote-block blockquote::before,
.quote-block blockquote::after { color: var(--orange); }
.quote-block blockquote::before { content: "„"; margin-right: .1em; }
.quote-block blockquote::after  { content: "“"; margin-left: .1em; }
.quote-block cite { display: block; font-style: normal; font-size: var(--text-small); color: var(--muted); }
.quote-block cite strong { color: var(--ink); }
/* Abschlussstrich statt einer weiteren Linie ueber die volle Breite: der Block
   bleibt freistehend, bekommt aber eine Unterkante. */
.quote-block::after {
  content: "";
  display: block;
  width: 56px; height: 3px;
  margin: 28px auto 0;
  border-radius: var(--radius-pill);
  background: var(--navy);
}

/* ---------- 29. Kennzahlen ----------
   Linksbündig mit Haarlinie über jeder Zahl: das Band steht unter einer
   Section-Head und soll als Teil dieses Blocks lesen, nicht als freischwebende
   Zahlenreihe. Die Linie übernimmt die Trennung, die vorher die Zentrierung
   leisten musste. */
.kennzahlen { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px 32px; }
.kennzahlen > * { border-top: 1px solid var(--line); padding-top: 20px; }
/* Sechs Kennzahlen (/ueber-uns/, seit 10.10.2026): Im Vierer-Raster standen
   über 1024px vier Zahlen in der ersten Reihe und zwei allein in der zweiten,
   rechts daneben eine halbe Reihe Leere. Drei Spalten ergeben zwei volle
   Reihen. Steht bewusst vor der 1024px-Regel: Gleich gewichtet gewinnt ab
   dort wieder deren zweispaltiges Raster, darunter ändert sich also nichts. */
.kennzahlen--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* 2x2 schon ab 1024px statt ab 860px: bei 900px blieben 202px pro Kennzahl,
   und die Beschriftungen („aus 1.700+ Bewertungen") brachen zweizeilig um,
   während die kürzeren einzeilig blieben — vier Zahlen auf drei verschiedenen
   Grundlinien. Als 2x2 stehen die Beschriftungen wieder auf einer Zeile. */
@media (max-width: 1024px) { .kennzahlen { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kennzahl__num { font-size: clamp(34px, 4vw, 48px); font-weight: 700; letter-spacing: -0.025em; color: var(--navy); line-height: 1.05; font-variant-numeric: tabular-nums; }
.kennzahl__num .unit { color: var(--orange); }
/* 16px statt 14px in Textfarbe: die Beschriftung trägt die eigentliche Aussage
   („aus 1.700+ Bewertungen"), als graue 14px ging sie neben der 48px-Zahl unter. */
.kennzahl__label { font-size: 16px; color: var(--ink); margin-top: 10px; }
.section--navy .kennzahl__num { color: #fff; }
.section--navy .kennzahl__num .unit { color: var(--orange); }
.section--navy .kennzahl__label { color: #9FB8CE; }

/* ---------- 30. Reveals ----------
   Die Scroll-Rolle des Bewegungssystems: zwei Zustände statt Keyframe, weil
   der IntersectionObserver (main.js) den Start setzt. Dieselbe Hubhöhe wie
   fade-up, damit Einstieg und Scroll gleich aussehen.

   .reveal--fade   nur aufblenden, kein Hub — für Flächen, die beim Verschieben
                   flackern (breite Grafiken, ganze Bahnen).
   .reveal auf einer Medienfigur ist die Bild-Rolle („image-reveal"): Foto und
   Platzhalter blenden auf wie jeder andere Block. Kein eigener Mechanismus,
   damit die 206 Platzhalter beim Austausch gegen echte Fotos nichts ändern. */
/* Der Hub läuft über die eigenständige `translate`-Eigenschaft, nicht über
   `transform`. Grund: `.reveal.is-visible { transform: none }` hat jeden
   Hover-Hub gleicher Spezifität überschrieben — .news-card und .stufe-card
   trugen zwar Schatten und Rahmen beim Hover, hoben aber nie ab, weil sie
   fast überall zusätzlich `reveal` tragen. Getrennte Eigenschaften können sich
   nicht mehr in die Quere kommen; `transform` gehört jetzt allein dem Hover. */
.reveal { opacity: 0; translate: 0 var(--fade-y); transition: opacity .6s var(--ease), translate .6s var(--ease); }
.reveal.is-visible { opacity: 1; translate: none; }

@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; translate: none; } }

/* ---------- 31. Sonstiges ---------- */
.anchor-offset { scroll-margin-top: 90px; }

.kicker-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }

.team-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; }
@media (max-width: 860px) { .team-grid { grid-template-columns: repeat(2, 1fr); } }
.team-card .img-placeholder--avatar { margin: 0 auto 14px; }
.team-card__name { font-weight: 700; color: var(--navy); display: block; letter-spacing: -0.01em; }
.team-card__role { font-size: 13.5px; color: var(--muted); font-weight: 600; }

.newsletter-form { display: flex; gap: 12px; flex-wrap: wrap; max-width: 520px; }
.newsletter-form input[type="email"] {
  flex: 1; min-width: 220px;
  font-family: var(--font-sans); font-size: 16px;
  padding: 13px 14px; border: 1.5px solid var(--line); border-radius: var(--radius-input);
  min-height: 48px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.newsletter-form input[type="email"]:focus { outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px rgba(255, 148, 10, .22); }

/* ---------- 32. Zeitstrahl (Unternehmensgeschichte) ----------
   Zweispaltig: links bleibt die Jahreszahl stehen und wechselt mit dem
   Lesefortschritt, rechts laufen die Stationen durch. Das Umschalten macht
   der Beobachter in main.js; ohne JS steht schlicht die erste Station da. */
.timeline { display: grid; grid-template-columns: minmax(240px, 34%) 1fr; gap: 56px; }

.timeline__stage { position: sticky; top: 96px; align-self: start; }
.timeline__now {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(52px, 7vw, 82px);
  font-weight: 700; line-height: 1; letter-spacing: -.03em;
  color: var(--navy);
}
/* Nur das Innere blendet um, der Kasten selbst darf nicht springen. */
.timeline__now span { display: inline-block; transition: opacity .3s var(--ease), transform .3s var(--ease); }
.timeline__stage.is-swapping .timeline__now span { opacity: 0; transform: translateY(-8px); }
.timeline__era { margin-top: 14px; font-size: 15px; font-weight: 600; color: var(--orange-text); min-height: 24px; transition: opacity .3s var(--ease); }
.timeline__stage.is-swapping .timeline__era { opacity: 0; }

.timeline__eras { list-style: none; margin: 26px 0 0; padding: 0; max-width: none; display: grid; gap: 7px; }
.timeline__eras li { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 13px; color: var(--muted-soft); }
/* Breite über scaleX statt width: kein Reflow beim Umschalten. */
.timeline__eras i { display: block; width: 40px; height: 2px; border-radius: 2px; background: var(--line-strong); transform: scaleX(.65); transform-origin: left; transition: background .3s var(--ease), transform .3s var(--ease); }
.timeline__eras li.is-active { color: var(--navy); font-weight: 600; }
.timeline__eras li.is-active i { background: var(--orange); transform: scaleX(1); }

.timeline__list { list-style: none; margin: 0; padding: 0; max-width: none; }
.timeline__list > li { position: relative; margin: 0; padding: 0 0 64px; }
.timeline__list > li:last-child { padding-bottom: 0; }
.timeline__list > li::after { content: ""; position: absolute; left: 0; right: 0; bottom: 32px; height: 1px; background: var(--line); }
.timeline__list > li:last-child::after { display: none; }
.timeline__year {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px; font-weight: 600; letter-spacing: .04em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-bottom: 6px;
}
.timeline__list h3 { font-size: 21px; margin-bottom: 8px; }
.timeline__list p { font-size: 16px; color: var(--muted); margin: 0; max-width: 60ch; }
.timeline__list > li.is-current h3 { color: var(--orange-text); }

@media (max-width: 860px) {
  .timeline { grid-template-columns: 1fr; gap: 0; }
  /* Aus der Spalte wird eine schmale Leiste direkt unter dem Header. */
  .timeline__stage {
    top: 73px; z-index: 4;   /* Header: 72px + 1px Rahmen, sonst schiebt er sich 2px drüber */
    display: flex; align-items: baseline; gap: 14px;
    /* Vollbreite Leiste: der Ausbruch muss exakt dem Container-Polster
       entsprechen — 10px bis 767, erst darunter 20px. */
    margin: 0 -10px 24px; padding: 12px 10px;
    background: rgba(255, 255, 255, .94);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
  }
  .timeline__now { font-size: 30px; }
  .timeline__era { margin-top: 0; font-size: 13px; min-height: 0; }
  .timeline__eras { display: none; }
  .timeline__list > li { padding-bottom: 42px; }
  .timeline__list > li::after { bottom: 21px; }
}
@media (max-width: 767px) {
  .timeline__stage { margin-left: -20px; margin-right: -20px; padding-left: 20px; padding-right: 20px; }
}

/* ---------- 33. Profil-Karte (Berater, E-E-A-T) ---------- */
.profile-card { display: flex; gap: 24px; align-items: flex-start; }
.profile-card .img-placeholder--avatar { flex: none; margin: 0; }
.profile-card h3 { margin-bottom: 2px; }
.profile-card__role { font-size: 13.5px; color: var(--muted); font-weight: 600; display: block; margin-bottom: 12px; }
@media (max-width: 767px) { .profile-card { flex-direction: column; gap: 16px; } }

/* ---------- 34. Fließtext-Seiten (Rechtstexte, Langtexte) ---------- */
/* Textmaß wie .section-head (Token --container-content) — vorher 760px, also
   dasselbe Bedürfnis mit einem eigenen Wert. */
.prose { max-width: var(--container-content); }
.prose p, .prose ul, .prose ol { max-width: none; }
.prose h2 { font-size: clamp(20px, 2.1vw, 24px); margin-top: 48px; }
.prose > h2:first-child { margin-top: 0; }
.prose h3 { font-size: 17px; margin-top: 30px; }
/* Vierte Ebene nur im langen Rechtstext /datenschutz/ (je Verarbeitung und je Empfänger
   eine H4, seit 06.10.2026). Kleiner als die H3, sonst sind beide gleich groß und die
   Gliederung verschwimmt. */
.prose h4 { font-size: var(--text-small); margin: 24px 0 6px; }
/* Das Inhaltsverzeichnis der Datenschutzerklärung ist eingerückt und schmal: bei 320px
   bricht „Standarddatenverarbeitung“ sonst mitten im Wort ohne Trennstrich um. */
@media (max-width: 767px) { .prose nav { hyphens: auto; } }
.prose address { font-style: normal; }
/* Rechtstexte nennen Belegstellen als nackte URL im Fliesstext
   ("facebook.com/legal/terms/page_controller_addendum"). Ein solches Wort ist
   laenger als der 320px-Viewport und schiebt die ganze Seite horizontal auf —
   nur hier, nicht global, weil break-word sonst auch Komposita zerlegt, wo
   die Silbentrennung der Ueberschriften schon greift. */
.prose p, .prose li { overflow-wrap: break-word; }

/* ---------- 35. Angebots-Umschalter (Agenturservice) ----------
   Zwei Angebotsarten nacheinander statt nebeneinander: der Umschalter ist
   die einzige Entscheidung im Blickfeld. Pauschalangebote bekommen eine
   Faktenspalte, die Lösungen werden zur Zeilenliste statt zur Kachelwand. */
.segmented {
  display: inline-flex; gap: 4px; padding: 4px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-pill); margin-bottom: 40px;
}
.segmented__btn {
  font-family: var(--font-sans); font-size: 15px; font-weight: 600;
  color: var(--muted); background: none; border: none; cursor: pointer;
  padding: 11px 22px; border-radius: var(--radius-pill); min-height: 44px;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.segmented__btn:hover { color: var(--navy); }
.segmented__btn[aria-selected="true"] { background: var(--navy); color: #fff; }

/* inline-flex zentriert sich nicht von selbst */
.segmented--center { display: flex; width: max-content; max-width: 100%; margin-left: auto; margin-right: auto; }
@media (max-width: 767px) {
  /* minmax(0, 1fr), nicht 1fr: 1fr ist minmax(auto, 1fr), also darf ein langes
     Wort die Spalte aufziehen. Mit vier Reitern („Datenanreicherung") standen
     147px neben 119px, das Raster wirkte kaputt. Bei zwei kurzen Reitern fällt
     es nicht auf — deshalb ist es bis jetzt niemandem aufgefallen. */
  .segmented { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); width: 100%; border-radius: var(--radius-input); }
  .segmented__btn { border-radius: calc(var(--radius-input) - 2px); padding: 11px 8px; font-size: 14px; }
}

/* ---------- 36. Lösungskarten (KI-Lösungen auf /ki/) ----------
   Bis 11.10.2026 Wendekarten (.flip-card: Vorderseite Aufgabe, Rückseite Ergebnis, erst nach einem Klick). Auftraggeber,
   11.10.2026: „Ich finde es blöd, wenn man da drauf klicken muss … dass man das auch sofort sehen kann.“ Jetzt stehen Idee
   und Wirkung untereinander in einer .card--cta. Die Wirkung sitzt unten über einer Haarlinie, damit sie in einer Reihe auf
   derselben Höhe beginnt; der Abstand nach oben kommt vom Absatz darüber (p: margin-bottom 16px). */
.card__nutzen {
  margin: auto 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  max-width: none;
}
.card__nutzen strong { color: var(--navy); }

/* ---------- 37. Signatur-Momente ---------- */

/* Der eine Keyframe der Seite: Aufblenden mit kurzem Hub. Die Hubhöhe kommt
   aus --fade-y, die Dauer vom Verwender. Vorher taten fade-rise-lg (16px),
   rise-in (14px) und fade-rise-sm (6px) dasselbe mit drei Namen.
   Reines Aufblenden ohne Hub = --fade-y: 0. */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(var(--fade-y)); }
}

/* Staffel-Mechanik: --i zählt die Position in der Reihe, --stagger-step hält
   den Abstand. Verzögerung immer calc(var(--i) * var(--stagger-step)).
   Bewusst KEINE .stagger-Klasse: die zwei Reihen der Seite brauchen je einen
   eigenen Auslöser (Hero läuft beim Seitenaufbau, die Stufen-Kette erst beim
   Sichtwerden). Eine Klasse ohne Verwender wäre Ballast — kommt eine dritte
   Reihe mit einfachem Aufbau, wird sie eine.
   --stagger-step: 55ms  (Standard, siehe .stufen-grid) */

/* Hero-Einstieg: eine einstudierte Sequenz statt verstreuter Effekte.
   Eigene Selektoren statt .stagger, weil die Reihenfolge hier an Rollen hängt
   (Eyebrow, H1, Lead, Handlungen, Belege) und nicht an der Kindposition. */
.hero { --fade-y: 16px; }
.hero .eyebrow { animation: fade-up .5s var(--ease) both; }
.hero h1 { animation: fade-up .6s var(--ease) .06s both; }
.hero .lead { animation: fade-up .6s var(--ease) .16s both; }
.hero .hero__ctas { animation: fade-up .6s var(--ease) .26s both; }
.hero .microcopy, .hero .trust-bar { animation: fade-up .6s var(--ease) .36s both; }

/* Der Logo-Bogen zeichnet sich unter dem Schlüsselwort des Heros.

   inline-block + padding-bottom, weil der Bogen 0,18em unter der Grundlinie
   hängt und die H1 mit line-height 1.1 sehr eng steht: steht das
   Schlüsselwort nicht in der letzten Zeile, lief der Bogen bisher durch die
   Versalien der Folgezeile („Echte Ergebnisse / statt Versprechen"). Das
   Polster wächst nur die Zeile mit dem Bogen, nicht die ganze Überschrift —
   deshalb hier und nicht als größeres line-height an der H1. Betrifft die
   neun Seiten, deren Schlüsselwort mitten in der Headline sitzt.

   Das Polster verschiebt auch die Bezugskante von position:absolute. Der
   Bogen muss deshalb um denselben Betrag zurück (.3em Polster minus .18em
   Hang = .12em), sonst rutscht er vom Wort weg. */
.swoosh {
  font-style: normal; position: relative; white-space: nowrap;
  display: inline-block; padding-bottom: .3em;
}
.swoosh::after {
  content: "";
  position: absolute;
  left: -0.05em; right: -0.05em;
  bottom: 0.12em;
  height: 0.22em;
  background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 12' preserveAspectRatio='none'%3E%3Cpath d='M3 9.5 Q 60 1.5 117 6.5' fill='none' stroke='%23FF940A' stroke-width='3.2' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  clip-path: inset(0 100% 0 0);
  animation: swoosh-draw .6s var(--ease) .7s forwards;
}
@keyframes swoosh-draw { to { clip-path: inset(0 0 0 0); } }
@media (prefers-reduced-motion: reduce) {
  .swoosh::after { clip-path: inset(0 0 0 0); }
}

/* Die 9-Stufen-Kette baut sich in ihrer eigenen Reihenfolge auf. Der Aufbau
   startet erst beim Sichtwerden (.is-visible vom IntersectionObserver),
   deshalb kein reines .stagger: die Verzögerung darf nicht schon beim
   Seitenaufbau ablaufen. Zählung und Abstand kommen trotzdem aus derselben
   Mechanik wie .stagger (--i, --stagger-step). */
.stufen-grid .reveal { transition: none; }
.stufen-grid .reveal.is-visible {
  animation: fade-up .5s var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-step, 55ms));
}
.stufen-grid li:nth-child(1) { --i: 0; }
.stufen-grid li:nth-child(2) { --i: 1; }
.stufen-grid li:nth-child(3) { --i: 2; }
.stufen-grid li:nth-child(4) { --i: 3; }
.stufen-grid li:nth-child(5) { --i: 4; }
.stufen-grid li:nth-child(6) { --i: 5; }
.stufen-grid li:nth-child(7) { --i: 6; }
.stufen-grid li:nth-child(8) { --i: 7; }
.stufen-grid li:nth-child(9) { --i: 8; }

/* FAQ-Antwort tritt weich ein — derselbe Keyframe, kürzerer Hub. */
.faq details[open] .faq__answer { --fade-y: 6px; animation: fade-up .35s var(--ease); }

/* Funnel-Auswahl bestätigt spürbar */
.funnel-tile.is-selected .funnel-tile__check { animation: check-pop .3s var(--ease); }
@keyframes check-pop {
  0% { transform: scale(.5); }
  60% { transform: scale(1.15); }
  100% { transform: scale(1); }
}

/* Buttons antworten auf den Klick */
.btn:active { transform: translateY(0) scale(.97); }

/* Der Signatur-Bogen unter dem Schluss-CTA ist am 25.09.2026 entfallen, siehe
   Kommentar bei .cb__bogen in Abschnitt 16a. position/overflow/z-index bleiben:
   die Bahn laeuft randlos und braucht den Stapelkontext weiterhin. */
.cta-block { position: relative; overflow: hidden; }
.cta-block .container { position: relative; z-index: 1; }

/* ---------- 38. KI-Kreislauf (KI-Seite, 9 Stufen) ----------
   Auf kundensystem.html steht der Satz "Zusammen ergeben sie einen Kreislauf".
   Hier ist er das Bild: die neun Stufen liegen auf dem Ring, die KI-Aufgabe der
   gewählten Stufe steht in der Mitte. Vorher war das eine 9x3-Tabelle, also 27
   gleich gewichtete Zellen, in der die einzige verkaufende Spalte ganz rechts
   in Grau stand.
   Umgeschaltet wird über echte Radios plus :has(). Damit laufen die Pfeiltasten
   von selbst im Kreis, jede Stufe ist per Tastatur erreichbar und die Section
   braucht kein JavaScript. */
.kreislauf {
  /* Masse als Eigenschaften, damit es eine kompakte Variante geben kann. Die
     Vorgaben sind exakt die bisherigen Werte — /ki/ aendert sich dadurch nicht. */
  --kreis-groesse: 660px;
  --kreis-radius: 250px;    /* Abstand Mitte -> Knoten */
  --kreis-node: 148px;      /* Breite eines Knotens */
  --kreis-mitte: 330px;     /* Breite der Inhaltsflaeche */
  --kreis-dot: 34px;        /* Durchmesser der Nummernkreise */
  /* Der Ring liegt GENAU auf der Bahn der Punktmittelpunkte — deshalb
     gerechnet und nicht geschaetzt. Vorher stand hier 80px; die Punkte lagen
     damit 13px ausserhalb der Linie. */
  --kreis-rand: calc(var(--kreis-groesse) / 2 - var(--kreis-radius));
  position: relative;
  width: var(--kreis-groesse);
  height: var(--kreis-groesse);
  margin: 0 auto;
}

/* Kompakt — fuer schmalere Spalten, etwa den Hero einer App-Seite. Dieselbe
   Komponente, kleinere Masse. Die Knotenbreite faellt mit: bei 9 Knoten auf
   40 Grad betraegt der Bogenabstand 2*r*sin(20deg) — bei r=190 sind das 130px,
   ein 148px breiter Knoten wuerde den Nachbarn ueberlappen. */
.kreislauf--kompakt {
  --kreis-groesse: 498px;
  --kreis-radius: 188px;
  --kreis-node: 112px;
  --kreis-mitte: 232px;
  --kreis-dot: 30px;
}
.kreislauf--kompakt .kreislauf__dot { font-size: 14px; }
.kreislauf--kompakt .kreislauf__name { font-size: 13px; }
.kreislauf--kompakt .kreislauf__task { font-size: 16px; }

/* Markenzeile unter dem wechselnden Text. Steht ausserhalb der Panels und
   bleibt deshalb stehen, waehrend die Stufen durchlaufen — das ist die
   Aussage: Welche Stufe auch laeuft, darunter liegt dieselbe App. */
/* Feste Kernaussage statt wechselnder Stufentexte — die Bauform fuer die
   App-Seiten. Grund: Ein Erklaersatz je Stufe waere je App neu zu schreiben,
   neun Saetze mal rund dreissig Apps. Die Aussage steht deshalb still,
   waehrend der Ring laeuft: Welche Stufe auch dran ist, darunter liegt
   dieselbe App. Je App wechseln nur zwei Dinge — dieser Satz und das Logo. */
.kreislauf__kern {
  font-size: 17px;
  line-height: 1.35;
  font-weight: 700;
  color: var(--navy);
  letter-spacing: -0.01em;
  margin: 0;
  max-width: none;
}
.kreislauf--kompakt .kreislauf__kern { font-size: 16px; }

.kreislauf__marke {
  margin: 14px 0 0;
  padding-top: 13px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  font-weight: 700;
  color: var(--navy);
  letter-spacing: -0.01em;
}
/* max-height statt height: Die Zoho-Produktlogos haben alle dieselbe Hoehe
   (296 Einheiten), aber sehr verschiedene Breiten — von 644 bei „One" bis 2077
   bei „Marketing Automation". Bei fester Hoehe waere das letzte 239px breit und
   spraengte die 232px breite Mitte. max-width deckelt, width/height auto halten
   das Seitenverhaeltnis. Lange Namen werden so etwas kleiner statt zu ueberlaufen. */
.kreislauf__marke img {
  display: block;
  margin: 0 auto;
  max-height: 34px;
  max-width: 100%;
  width: auto;
  height: auto;
}
.kreislauf input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }
.kreislauf__disc {
  position: absolute; inset: var(--kreis-rand);
  border: 1px dashed var(--line-strong);
  border-radius: 50%;
}
.kreislauf__node {
  position: absolute; left: 50%; top: 50%;
  width: var(--kreis-node);
  /* Der Knoten haengt an seinem PUNKT, nicht an seiner Mitte. Vorher waren es
     feste -30px und der Drehpunkt lag in der Knotenmitte — die verschiebt sich
     aber mit der Zeilenzahl der Beschriftung. Ergebnis: Die Punkte lagen auf
     keinem Kreis, ihre Radien schwankten zwischen 174 und 203px.
     Jetzt startet die Punktmitte exakt im Zentrum und wandert um genau
     --kreis-radius nach aussen. Die Beschriftung haengt hinten dran und darf
     beliebig hoch sein. */
  margin: calc(var(--kreis-dot) / -2) 0 0 calc(var(--kreis-node) / -2);
  transform-origin: 50% calc(var(--kreis-dot) / 2);
  /* Zweite Rotation stellt die Beschriftung wieder aufrecht. */
  transform: rotate(var(--a)) translateY(calc(-1 * var(--kreis-radius))) rotate(calc(-1 * var(--a)));
  text-align: center; cursor: pointer;
}
.kreislauf__dot {
  display: block; width: var(--kreis-dot); height: var(--kreis-dot); margin: 0 auto 8px;
  border-radius: 50%; background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  color: var(--navy); font-weight: 700; font-size: 15px;
  font-variant-numeric: tabular-nums; line-height: var(--kreis-dot);
  transition: background .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease);
}
.kreislauf__name {
  display: block; font-size: 14px; line-height: 1.25; color: var(--muted);
  transition: color .2s var(--ease);
}
.kreislauf__node:hover .kreislauf__dot { box-shadow: inset 0 0 0 1px var(--navy); }
.kreislauf__node:hover .kreislauf__name { color: var(--navy); }
.kreislauf input:checked + .kreislauf__node .kreislauf__dot { background: var(--orange); color: var(--ink); box-shadow: none; }
.kreislauf input:checked + .kreislauf__node .kreislauf__name { color: var(--navy); font-weight: 700; }
.kreislauf input:focus-visible + .kreislauf__node .kreislauf__dot { outline: 2px solid var(--orange); outline-offset: 3px; }

.kreislauf__center {
  position: absolute; left: 50%; top: 50%; width: var(--kreis-mitte);
  transform: translate(-50%, -50%);
  text-align: center;
  /* Deckt die gestrichelte Kreislinie hinter dem Text ab. */
  background: var(--paper); padding: 10px 14px;
}
.section--soft .kreislauf__center { background: var(--surface-2); }
.kreislauf__panel { display: none; }
/* Welches Panel sichtbar ist, haengt an der POSITION des gewaehlten Radios,
   nicht an festen IDs. Grund: IDs sind je Dokument eindeutig — ein zweiter
   Kreislauf auf einer anderen Seite (Hero von /zoho-crm/) braucht eigene und
   fiele durch ID-gebundene Regeln durch. Das Ergebnis waere eine leere Mitte.
   :nth-of-type zaehlt nur die <input>; die <label> dazwischen stoeren nicht. */
.kreislauf:has(.kreislauf__nodes input:nth-of-type(1):checked) [data-stufe="1"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(2):checked) [data-stufe="2"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(3):checked) [data-stufe="3"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(4):checked) [data-stufe="4"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(5):checked) [data-stufe="5"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(6):checked) [data-stufe="6"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(7):checked) [data-stufe="7"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(8):checked) [data-stufe="8"],
.kreislauf:has(.kreislauf__nodes input:nth-of-type(9):checked) [data-stufe="9"] { display: block; }
@media (prefers-reduced-motion: no-preference) {
  .kreislauf__panel { --fade-y: 6px; animation: fade-up .28s var(--ease) both; }
}

.kreislauf__stufe { font-size: 12.5px; font-weight: 700; letter-spacing: .01em; color: var(--orange-text); margin: 0 0 10px; }
.kreislauf__task { font-size: 17px; line-height: 1.4; font-weight: 700; color: var(--navy); margin: 0 0 14px; max-width: none; }
.kreislauf__gain { font-size: 15px; color: var(--muted); margin: 0; padding-top: 14px; border-top: 1px solid var(--line); max-width: none; }

/* Unter 760px trägt kein Kreis mehr neun Beschriftungen. Dann werden die Knoten
   zu einem kompakten Nummernraster, die Mitte rutscht darunter. */
@media (max-width: 767px) {
  .kreislauf { width: auto; height: auto; }
  .kreislauf__disc { display: none; }
  .kreislauf__nodes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 32px; }
  .kreislauf__node {
    position: static; width: auto; margin: 0; transform: none;
    display: flex; gap: 10px; align-items: center; text-align: left;
    padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-input);
  }
  /* text-align muss hier wieder gesetzt werden, die Node ist jetzt linksbündig. */
  .kreislauf__dot { margin: 0; width: 26px; height: 26px; line-height: 26px; font-size: 13px; flex: none; text-align: center; }
  .kreislauf__name { font-size: 13px; }
  .kreislauf input:checked + .kreislauf__node { border-color: var(--orange); }
  .kreislauf__center { position: static; width: auto; transform: none; text-align: left; padding: 0; }
}
@media (max-width: 767px) { .kreislauf__nodes { grid-template-columns: repeat(2, 1fr); } }

/* ---------- 40. News-Artikel (C20) ----------
   Lesestrecke mit Lese-Rail (Sprungmarken + Fortschritt) und Randnotizen.
   Nur für Artikelseiten wie neuigkeiten-*.html — Aufbau:
   .article-head > .article-layout(.article-rail | .article-body | .article-aside)
   ------------------------------------------------------------ */
.article-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.article-meta__dot { width: 4px; height: 4px; border-radius: 50%; background: var(--line-strong); flex: none; }

.article-head { padding: 64px 0 0; }
.article-head h1 { max-width: 26ch; margin: 14px 0 18px; }
.article-head__lead { font-size: 20px; line-height: 1.55; color: var(--muted); max-width: 60ch; margin: 0 0 28px; }
.article-head__rule { display: flex; justify-content: space-between; gap: 16px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 13px 0; }
@media (max-width: 767px) { .article-head { padding: 40px 0 0; } .article-head__rule { flex-direction: column; gap: 10px; } }

.article-layout { display: grid; grid-template-columns: 186px minmax(0, 672px) 208px; gap: 0 56px; align-items: start; padding: 44px 0 96px; }
@media (max-width: 1024px) { .article-layout { grid-template-columns: 170px minmax(0,1fr); gap: 0 40px; } }
/* minmax(0, 1fr) statt 1fr (08.10.2026): Auf /erfolgsgeschichten/guido-bayer/ wuchs die Spalte bei 320px mit
   „Finanzdienstleistungsunternehmen“ in „Kurz gefasst“ auf 322px und schob den ganzen Artikel aus dem Bild. */
@media (max-width: 860px)  { .article-layout { grid-template-columns: minmax(0, 1fr); padding: 32px 0 64px; } }

/* Lese-Rail: Sprungmarken, aktiver Abschnitt und Lesefortschritt als Linie */
.article-rail { position: sticky; top: 96px; }
@media (max-width: 860px) { .article-rail { display: none; } }
.article-rail__label { font-size: 11px; font-weight: 700; letter-spacing: .01em; color: var(--muted); margin-bottom: 14px; }
.article-rail__track { position: relative; padding-left: 20px; }
.article-rail__track::before { content: ""; position: absolute; left: 3px; top: 6px; bottom: 6px; width: 2px; background: var(--line); border-radius: 2px; }
.article-rail__fill { position: absolute; left: 3px; top: 6px; bottom: 6px; width: 2px; background: var(--orange); border-radius: 2px; transform: scaleY(0); transform-origin: top; }
.article-rail ol { list-style: none; margin: 0; padding: 0; max-width: none; }
.article-rail li { margin: 0; }
.article-rail a {
  display: block; position: relative; padding: 7px 0; font-size: 14px; line-height: 1.35;
  color: var(--muted); text-decoration: none; transition: color .18s var(--ease);
}
.article-rail a::before {
  content: ""; position: absolute; left: -21px; top: 13px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--paper); box-shadow: inset 0 0 0 2px var(--line-strong);
  transition: box-shadow .18s var(--ease), transform .18s var(--ease);
}
.article-rail a:hover { color: var(--navy); }
.article-rail a[aria-current="true"] { color: var(--navy); font-weight: 700; }
.article-rail a[aria-current="true"]::before { box-shadow: inset 0 0 0 4px var(--orange); transform: scale(1.15); }
.article-rail__read { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Artikel-Körper */
.article-body > h2 { margin-top: 48px; scroll-margin-top: 96px; }
.article-body > h2:first-child { margin-top: 0; }
.article-body p { font-size: 18px; line-height: 1.68; }
/* Notnagel wie bei .prose: ein Kompositum, das breiter ist als die Spalte, bricht, statt über den Rand zu laufen. */
.article-body p, .article-body li { overflow-wrap: break-word; }
.article-tldr { border-left: 1px solid var(--line-strong); padding: 2px 0 2px 24px; margin: 0 0 8px; scroll-margin-top: 96px; }
.article-tldr .eyebrow { color: var(--muted); }
.article-tldr p { font-size: 18px; line-height: 1.62; margin: 0; }

/* Schritte im Tabellen-Rhythmus statt als Kartenreihe */
.article-steps { list-style: none; padding: 0; margin: 24px 0 0; max-width: none; counter-reset: astep; }
.article-steps li {
  counter-increment: astep; display: grid; grid-template-columns: 44px minmax(0,1fr);
  gap: 0 16px; margin: 0; padding: 20px 0; border-top: 1px solid var(--line);
}
.article-steps li:last-child { border-bottom: 1px solid var(--line); }
.article-steps li::before {
  content: counter(astep, decimal-leading-zero);
  font-size: 14px; font-weight: 700; color: var(--orange-text); font-variant-numeric: tabular-nums;
  padding-top: 3px; letter-spacing: .02em;
}
.article-steps h3 { font-size: 18px; margin: 0 0 5px; }
.article-steps p { font-size: 16px; line-height: 1.6; margin: 0; color: var(--muted); }

.article-verdict { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 16px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin: 0 0 26px; }
.article-verdict__why { font-size: 15px; color: var(--muted); }

.article-quote { margin: 0; }
.article-quote blockquote {
  margin: 0 0 12px; padding: 0; font-size: 23px; line-height: 1.42; font-weight: 600;
  color: var(--navy); letter-spacing: -0.015em; text-wrap: pretty;
}
.article-quote blockquote::before { content: "\201E"; color: var(--orange); }
.article-quote blockquote::after  { content: "\201C"; color: var(--orange); }
.article-quote cite { font-style: normal; font-size: 14px; color: var(--muted); }
.article-quote cite strong { color: var(--ink); }
/* Wortlaut einer Kundenstimme (Detailseiten /erfolgsgeschichten/<slug>/): das Video als Text,
   als Zitat gesetzt, mit derselben Kante wie „Kurz gefasst“. */
.wortlaut { margin: 0; border-left: 2px solid var(--line-strong); padding-left: 22px; }
.wortlaut p { font-size: 17px; line-height: 1.68; }
/* Wortlaut weiterer Videos derselben Firma (seit 07.10.2026): zugeklappt im Akkordeon aus Abschnitt 14,
   damit die Seite nicht fünf Abschriften hintereinander zeigt. Der Text steht trotzdem im HTML. Eigene
   Innenklasse statt .faq__answer, weil scripts/faq-abgleich.py jede .faq__answer als häufige Frage liest. */
.faq--wortlaut summary { font-size: 16px; }
.faq__wortlaut { padding: 0 24px 22px 42px; }
@media (max-width: 767px) { .faq__wortlaut { padding: 0 18px 18px 22px; } }
/* Das Video steht dort als erstes im Artikel, „Kurz gefasst“ folgt mit Abstand. */
.article-body > .vp { margin-bottom: 36px; }
/* Kurzbewertungen aus dem Zoho-Partnerverzeichnis (seit 08.10.2026, scripts/bewertungen.json): Karte = .card,
   Sterne nur Schmuck (aria-hidden), die Note steht als Text daneben. Orange nur für die Sterne, nie für Text.
   --bericht: der Kasten im Erfahrungsbericht derselben Firma, unter dem Kernzitat. */
.bewertung { display: flex; flex-direction: column; gap: 12px; }
.bewertung__kopf { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 0; font-size: 14px; color: var(--muted); }
.sterne { color: var(--orange); font-size: 16px; letter-spacing: 2px; }
.bewertung__text { margin: 0; font-size: 16px; line-height: 1.6; color: var(--ink); }
.bewertung__text::before { content: "\201E"; }
.bewertung__text::after { content: "\201C"; }
.bewertung__wer { margin: auto 0 0; font-size: 14px; color: var(--muted); }
.bewertung__wer strong { color: var(--ink); font-weight: 600; }
.bewertung--bericht { margin: 36px 0; }
.bewertungen-hinweis { max-width: none; font-size: 13px; line-height: 1.55; color: var(--muted); }
/* Bewertungsbalken (seit 08.10.2026, Vorlage des Auftraggebers: Sterne, Note und Anzahl in einer Pille) über den
   Bewertungen auf /erfolgsgeschichten/ und der Partnerseite. Als Link führt er auf die Partnerseite, nie zu Zoho.
   Orange nur für die Sterne, die Note fett in --navy. Unter 767px bricht der Text unter die Sterne; die Pille wird
   dann zur Karte (--radius-card), weil eine zweizeilige Pille die Zeilenenden in die Rundung schiebt. */
.bewertung-balken-zeile { display: flex; justify-content: center; max-width: none; margin: 0 0 32px; }
.bewertung-balken {
  display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 12px;
  padding: 10px 24px; border: 1px solid var(--line-strong); border-radius: var(--radius-pill);
  background: var(--paper); color: var(--muted); font-size: 16px; line-height: 1.45; text-align: center;
  text-decoration: none; transition: border-color .18s var(--ease);
}
.bewertung-balken .sterne { font-size: 20px; letter-spacing: 3px; }
.bewertung-balken__note { color: var(--navy); font-size: 20px; font-weight: 700; }
a.bewertung-balken:hover { border-color: var(--navy); }
/* Persönliches Video (Wowing, seit 08.10.2026, /persoenliches-video/): Kasten mit Hinweis und Knopf, nach dem Klick
   lädt main.js das Skript hinein. Ohne Rahmen, sobald das Video da ist. */
.wowing { max-width: 720px; margin-top: 28px; display: grid; gap: 16px; justify-items: start; }
.wowing__hinweis { margin: 0; font-size: 14px; line-height: 1.55; color: var(--muted); }
.wowing--geladen { padding: 0; border: 0; background: none; display: block; }
@media (max-width: 767px) { .bewertung-balken { border-radius: var(--radius-card); padding: 10px 18px; } }

/* Randnotizen — auf Schmal wandern sie unter den Artikel */
.article-aside { position: sticky; top: 96px; display: grid; gap: 26px; }
@media (max-width: 1024px) {
  .article-aside { position: static; grid-column: 1 / -1; grid-template-columns: repeat(3,1fr); gap: 24px; margin-top: 48px; padding-top: 26px; border-top: 1px solid var(--line); }
}
@media (max-width: 767px) { .article-aside { grid-template-columns: 1fr; } }
.article-note { border-left: 2px solid var(--line-strong); padding-left: 15px; }
.article-note__t { font-size: 11px; font-weight: 700; letter-spacing: .01em; color: var(--muted); display: block; margin-bottom: 7px; }
.article-note p, .article-note ul { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0; }
.article-note ul { list-style: none; padding: 0; display: grid; gap: 7px; max-width: none; }
.article-note li { margin: 0; }
.article-note a { font-weight: 600; text-decoration-color: var(--line-strong); }

/* ---------- 41. Video-Lightbox (natives dialog) ---------- */
.video-trigger { width: 100%; font-family: inherit; font-size: 12px; cursor: pointer; padding: 16px; transition: border-color .18s var(--ease); }
.video-trigger::before { width: 44px; height: 44px; background-size: 16px; transition: transform .18s var(--ease); }
.video-trigger:hover { border-color: var(--navy); }
.video-trigger:hover::before { transform: scale(1.08); }

.lightbox { border: 0; padding: 0; background: transparent; width: 100%; max-width: none; height: 100%; max-height: none;
  overflow: auto; }
/* Polster oben, weil der Schließen-Knopf 52px ÜBER dem Kasten sitzt: ohne
   Reserve schiebt ein hoher Kasten ihn aus dem Bild. Gemessen bei 1440er
   Breite: bei 768px Fensterhöhe lag er auf -17px, bei 640px komplett draußen.
   Unten weniger, dort steht nichts. Auf dem Handy wandert der Knopf unter den
   Kasten, deshalb dreht die Mobile-Regel das Polster.

   Zentriert wird über margin:auto am Kasten, nicht über place-items: bei
   place-items schiebt ein zu hoher Kasten über die Oberkante hinaus, und
   dieser Überlauf ist nicht scrollbar — der Knopf bliebe unerreichbar.
   margin:auto fällt bei Platzmangel auf 0 zurück, dann greift overflow. */
.lightbox[open] { display: grid; padding: 60px 0 24px; }
.lightbox::backdrop { background: rgba(22, 51, 79, .74); }
/* Markenblau statt Weiß: der Kasten steht auf dem abgedunkelten Backdrop und
   umschließt ein Video — eine weiße Fläche ist dort der hellste Punkt des
   Bildschirms und zieht den Blick vom Bild weg. Auf --navy tritt das Video
   nach vorn, und der Kasten gehört sichtbar zur Marke.
   Polster großzügiger als die 14px von vorher, weil eine dunkle Fläche einen
   knappen Rand als Fehler zeigt, wo Weiß ihn verschluckt. */
.lightbox__inner { position: relative; margin: auto; width: min(1040px, 92vw); background: var(--navy); border-radius: var(--radius-card); box-shadow: var(--shadow-float); padding: var(--space-4); }
/* eigene Flaeche, damit der Kontrast nicht am Backdrop haengt */
.lightbox__close {
  position: absolute; top: -52px; right: 0; display: inline-flex; align-items: center; gap: 8px;
  background: var(--navy); border: 1px solid rgba(255,255,255,.28); border-radius: var(--radius-card);
  padding: 9px 18px; cursor: pointer; font: 600 14px/1 var(--font-sans); color: #fff;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.lightbox__close:hover { background: var(--orange); color: var(--ink); border-color: transparent; }
@media (max-width: 767px) {
  .lightbox__close { top: auto; bottom: -50px; right: 50%; transform: translateX(50%); }
  /* Knopf unter dem Kasten — also die Reserve nach unten drehen */
  .lightbox[open] { padding: 24px 0 62px; }
}
/* Die Zeile unter dem Video ist keine Bildunterschrift mehr, sondern Titel plus
   Fließtext. Farben und Größen kommen aus dem, was für dunkle Bahnen schon
   festgelegt ist (.section--navy, Abschnitt 3): #fff für die Überschrift,
   #D6E2EE für Text darauf — keine neuen Werte für diesen einen Ort.
   17px/1.6 ist --text-body, also derselbe Fließtext wie in der Seite. */
.lightbox__cap { margin: var(--space-5) var(--space-2) var(--space-3);
  font-size: var(--text-body); line-height: 1.6; color: #D6E2EE; }
/* display: block macht aus der angehängten Beschreibung eine eigene Zeile —
   der Titel trägt sie nicht mehr in derselben Zeile weiter. Rolle H3 (21px)
   aus der Typo-Skala: größer als die 17px der Karte, weil die Lightbox das
   Video groß zeigt, aber unter H2 — es ist keine Seitenüberschrift. */
.lightbox__cap strong { display: block; margin-bottom: var(--space-2);
  font-size: var(--text-h3); font-weight: 700; line-height: 1.3; color: #fff; }

/* 16:9-Rahmen für das <iframe> in der Lightbox. Eigener Rahmen, weil das
   iframe selbst keine aspect-ratio mitbringt und sonst 150px hoch wäre. */
.lb-frame { position: relative; aspect-ratio: 16 / 9; background: #000;
  border-radius: 10px; overflow: hidden; }
.lb-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Der Consent-Platzhalter liegt ÜBER dem iframe. Genau dafür sitzt der Player
   in der Lightbox und nicht in der Seite: die Einwilligung braucht nur einen
   Ort.
   PROD: display auf grid stellen — dann ist der Hinweis der Grundzustand, und
   der Klick auf „Video laden" blendet ihn aus und setzt erst dann den
   iframe-src. Solange „Video laden" ein Mock ist, bleibt der Block verdeckt,
   sonst blockiert er genau das Video, das er freigeben soll.

   place-CONTENT, nicht place-items: Hinweis und Knopf sollen als Gruppe in der
   Mitte stehen. Mit place-items zentriert jede Grid-Zeile für sich, dann klebt
   der Text oben und der Knopf in der Bildmitte. justify-items dazu, sonst
   dehnt sich der Knopf auf die ganze Breite. */
.lb-consent { position: absolute; inset: 0; z-index: 2; display: none;
  place-content: center; justify-items: center;
  text-align: center; padding: 24px; background: var(--navy); }
.lb-consent p { color: #D6E2EE; font-size: var(--text-small); max-width: 46ch; margin: 0 0 14px; }

/* ---------- 41b. Video-Karte (Poster + Play, öffnet die Lightbox) ----------
   Ersetzt den grauen .img-placeholder--video in den Video-Sections. Vor dem
   Klick wird kein YouTube-Request ausgelöst — das ist der Zweck des Posters.

   Ein Video = ein Container mit EINEM <button>, der als unsichtbare Fläche
   über der ganzen Karte liegt (.vp-hit). Warum nicht die ganze Karte als
   <button>? Weil in einen Button kein <h3> und kein <p> darf — Buttons nehmen
   nur Text auf. So bleibt die Überschrift eine echte Überschrift, und
   Tastatur, Enter, Leertaste und Fokusring kommen trotzdem vom Browser.
   Kein <a href="#">, weil die Aktion auf derselben Seite bleibt. */
.vp { position: relative; }
.vp-hit { position: absolute; inset: 0; z-index: 3;
  width: 100%; padding: 0; border: 0; background: none; cursor: pointer; }
.vp-hit:focus-visible { outline: 2px solid var(--orange); outline-offset: 4px; border-radius: var(--radius-card); }
.vp-body { display: block; }

/* Das Poster. aspect-ratio statt Höhe, damit ein selbst hochgeladenes
   16:9-Bild nie beschnitten wirkt und kein Layout-Sprung entsteht.
   Der navy Grund liegt darunter: solange das Bild lädt (oder fehlt),
   ist die Fläche markenfarben und nicht weiß. */
.vp-thumb { display: block; position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--radius-card); background: var(--navy); }
.vp-thumb > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform .5s var(--ease), opacity .3s var(--ease); }

/* Der Play-Button. Primärfarbe des Style Guides: oranger Vollton mit
   anthrazitfarbenem Glyph — dieselbe Logik wie .btn--primary.

   Kein Kreis: der Radius ist --radius-card, dieselben 14px wie Karten und
   Buttons der Seite. Ein runder Play-Knopf ist der Vorgabewert jedes
   Video-Players im Netz; das Rechteck macht ihn zu einem Element DIESES
   Systems. Aus demselben Grund ruht er, statt zu hüpfen: auf Hover wächst er
   nach rechts zur Leiste und gibt die Beschriftung frei, das ersetzt das
   Aufskalieren.

   Getrennt wird er vom Bild nicht durch einen weißen Schein, sondern durch
   drei sachliche Kanten: eine hauchfeine Lichtkante oben (inset), eine
   anthrazitfarbene Haarlinie außen und ein neutraler Schlagschatten. Das
   trägt auch auf einem hellen Standbild. */
.vp-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  height: 58px; min-width: 58px; padding: 0 18px;
  border-radius: var(--radius-card);
  background: var(--orange); color: var(--ink);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    0 0 0 1px rgba(25, 45, 77, .13),
    0 8px 22px rgba(16, 38, 60, .32);
  transition: box-shadow .24s var(--ease), background .18s var(--ease);
  pointer-events: none;   /* die Klickfläche liegt darüber, der Knopf ist nur Optik */
}
/* Das Dreieck bekommt seine weichen Ecken über stroke-linejoin statt über
   einen handgerechneten Pfad mit Bögen — gleiche Optik, eine Zeile. */
.vp-play svg { flex: none; width: 19px; height: 19px; margin-left: 2px;
  fill: currentColor; stroke: currentColor; stroke-width: 2.6; stroke-linejoin: round; }
/* Die Beschriftung ist eingeklappt und nicht display:none — nur so lässt sich
   die Breite animieren. 14ch: „Video ansehen" braucht in 700/14px gemessene
   99px, ein ch sind hier ~8px — bei 11ch fehlte das letzte n. Deckel bleibt,
   damit eine längere Beschriftung die Leiste nicht aus dem Poster schiebt. */
.vp-play__label { font: 700 14px/1 var(--font-sans); white-space: nowrap;
  max-width: 0; margin-left: 0; opacity: 0; overflow: hidden;
  transition: max-width .3s var(--ease), margin-left .3s var(--ease), opacity .22s var(--ease); }
/* Tastatur bekommt dieselbe Rückmeldung wie die Maus — sonst sieht man beim
   Durchtabben nur den Rahmen und nicht, dass der Knopf gemeint ist. */
.vp:hover .vp-play, .vp:has(.vp-hit:focus-visible) .vp-play {
  background: var(--orange-dark);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    0 0 0 1px rgba(25, 45, 77, .16),
    0 12px 30px rgba(16, 38, 60, .38);
}
.vp:hover .vp-play__label, .vp:has(.vp-hit:focus-visible) .vp-play__label {
  max-width: 14ch; margin-left: 10px; opacity: 1;
}
.vp:hover .vp-thumb > img { transform: scale(1.045); }

/* Laufzeit-Plakette. Liegt unten rechts, wo sie kein Gesicht und keine
   Bildunterschrift des Standbilds verdeckt. */
.vp-time { position: absolute; right: 10px; bottom: 10px; z-index: 2;
  background: rgba(25, 45, 77, .82); color: #fff;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  padding: 4px 9px; border-radius: var(--radius-pill);
  font-variant-numeric: tabular-nums;
}

/* Auf dem Handy ist das Poster nur noch ~236px breit — dort nimmt der Knopf in
   Originalgröße ein Viertel der Bildbreite ein und verdeckt das Motiv. Die
   Beschriftung fällt weg: ohne Zeiger gibt es keinen Hover, der sie
   aufklappen könnte. */
@media (max-width: 767px) {
  .vp-play { height: 50px; min-width: 50px; padding: 0 15px; }
  .vp-play svg { width: 17px; height: 17px; }
}
@media (prefers-reduced-motion: reduce) {
  .vp:hover .vp-thumb > img { transform: none; }
  /* Die Leiste klappt ohne Laufzeit auf — die Beschriftung bleibt, nur der Weg
     dorthin fällt weg. Das Cursorlicht wandert nicht mit (siehe main.js). */
  .vp-play__label { transition: none; }
}

/* Titel und Laufzeit unter dem Bild auf Weiß: das Bild muss keine Schrift
   tragen, der Titel ist auch bei einem hellen Standbild ohne Kontrast lesbar.
   Auf Seiten, die über dem Video schon eine Überschrift führen (Testimonial),
   bleibt .vp-body weg — die Karte ist dann nur Poster plus Knopf. */
.vp--karte .vp-body { padding: 16px 2px 0; }
.vp--karte h3 { font-size: var(--text-h4); line-height: 1.4; margin: 0 0 6px; color: var(--navy); }
.vp--karte:hover h3 { color: var(--orange-text); }
.vp--karte .vp-sub { font-size: var(--text-small); color: var(--muted); margin: 0; }
/* Kundenstimmen (scripts/build-referenzen.py, seit 07.10.2026): Branche und die ersten zwei Themen
   als Chips unter der Unterzeile. Sie stehen im Kartentext, damit die Freitextsuche sie findet. */
.vp--karte .vp-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 0; max-width: none; }
/* Kurzbox einer Kundenstimme: der Zitat-Kasten D4c (Abschnitt 16a), dessen Bild das Video startet.
   Format, Rundung und Ring wie beim Foto dort; die Klickfläche liegt nur auf dem Bild. */
.cb-d4c__bild > .vp > .vp-thumb { aspect-ratio: 3 / 4; box-shadow: 0 0 0 5px var(--surface-2), var(--shadow-card); }
/* Karte einer Kundenstimme (.vp--stimme): Titel, Zitat, Name, Chips und ein Link mit Namen. Die Karte ist
   eine Spalte, der Link steht unten, damit er in einer Reihe auf gleicher Höhe liegt. Die Klickfläche bleibt
   .vp-hit über der ganzen Karte; der Link ist deshalb nur Optik (<span class="btn-arrow">, Abschnitt 6). */
.vp--stimme { display: flex; flex-direction: column; }
.vp--stimme .vp-body { display: flex; flex-direction: column; flex: 1; }
.vp--stimme .vp-zitat { font-size: 15px; line-height: 1.55; color: var(--ink); margin: 2px 0 10px; }
.vp--stimme .vp-cta { margin: auto 0 0; padding-top: 14px; max-width: none; }
.vp--stimme:hover .btn-arrow, .vp--stimme:has(.vp-hit:focus-visible) .btn-arrow {
  color: var(--navy-deep); text-decoration-color: var(--navy-deep); }
/* Kennzahl aus dem Video als Plakette unten links auf dem Standbild, auf einer Linie mit der Laufzeit
   unten rechts. Oben links steht in den Standbildern das ICOS-Logo, das bliebe sonst verdeckt. */
.vp-kennzahl { position: absolute; left: 10px; bottom: 10px; z-index: 2;
  background: var(--orange); color: var(--ink);
  font-size: 12px; font-weight: 700; letter-spacing: .01em;
  padding: 4px 10px; border-radius: var(--radius-pill); }

/* ---------- Cursorlicht ----------
   Indirektes oranges Licht, das hinter der Karte hervorkommt und dem Cursor
   folgt. Umgesetzt als ::before HINTER der Karte (z-index: -1): das Poster ist
   deckend, sichtbar ist deshalb nur, was seitlich auf den Weißraum austritt —
   das Licht liegt nie über dem Bild.

   --mx/--my kommen kartenrelativ in px aus main.js; die --glow-spread
   dazuzurechnen ist Sache des calc() hier, damit die Zahl nur an einer Stelle
   steht. Ohne JS (und auf Touch) bleiben die Startwerte: Licht sitzt mittig.

   Der Überstand des Kastens über die Karte ist die Strecke, auf der das Licht
   auf den Weißraum austritt — und er ist absichtlich NICHT quadratisch:

   waagerecht 170px, damit das Licht über die Grid-Spalte hinaus auf den
   Seitenrand läuft. Der Überstand ragt damit auch über den Container; die
   Sektion (.vp-section) schneidet ihn am Bildschirmrand ab, wo nichts zu sehen
   ist.

   Vorher standen hier 90px, und das war zu wenig — nicht weil das Licht nicht
   weiter reichte, sondern weil die Maske unten die letzten ~28 % des Kastens
   ausblendet: bei 90px Überstand lag der ganze Austrittsstreifen neben der
   Karte in dieser Ausblendzone, der Effekt war fast weg. Überstand und
   Maskenkante gehören deshalb zusammen — größerer Überstand ohne späteren
   Maskenstop bringt nichts.

   senkrecht nur 56px, weil dieselbe Sektion oben und unten mitschneidet (CSS
   erlaubt clip nicht nur auf einer Achse). 56px bleiben unter dem kleinsten
   Sektionspolster der Seite (--section-sm, 64px) — deshalb liegt der Schnitt
   dort immer hinter dem Licht und nie darin. */
/* isolation: isolate ist hier Pflicht, kein Feinschliff. z-index: -1 malt
   hinter die Hintergründe ALLER Vorfahren im gleichen Stapelkontext — in einer
   .section--soft lag das Licht damit unter der grauen Fläche und war komplett
   unsichtbar (gemessen auf /erfolgsgeschichten/ und /wissen/). Mit einem
   eigenen Stapelkontext an der Karte reicht das -1 nur noch bis hinter die
   (transparente) Karte selbst: über der Sektionsfläche, unter dem Poster, und
   der Text in .vp-body bleibt als Nicht-positioniertes Element ohnehin oben. */
/* Drei Stufen, weil die Karte in drei Größen vorkommt: einspaltig 880px
   (/erfolgsgeschichten/), im .grid-2 rund 580px (Stufenseiten), im .grid-3 rund
   375px (/wissen/). Dieselbe Reichweite und Deckkraft wirkt auf der kleinen
   Karte drei Mal so stark — das Licht muss dort nur ein Drittel der Strecke
   überbrücken, tritt also viel heller aus. Gestuft wird an den vorhandenen
   Grid-Klassen; die einspaltige Karte ist der Standard.

   Nur ZWEI Zahlen pro Stufe: --glow-reach (Reichweite) und --glow-a
   (Deckkraft des Kerns). Ausläufer, Grundschein und senkrechter Radius sind
   davon abgeleitet — sonst driften sechs Werte über drei Stufen auseinander. */
.vp--karte {
  --glow-spread: 170px; --glow-spread-y: 56px;
  --glow-reach: 900px; --glow-a: .26;
  isolation: isolate;
}
.grid-2 > .vp--karte { --glow-reach: 640px; --glow-a: .21; }
.grid-3 > .vp--karte { --glow-reach: 460px; --glow-a: .17; }
.vp--karte::before {
  content: "";
  position: absolute; z-index: -1;
  inset: calc(-1 * var(--glow-spread-y)) calc(-1 * var(--glow-spread));
  /* Größe und Abfall des Lichts. Die Untergrenze ist hier nicht Geschmack:
     das Poster ist deckend, sichtbar wird das Licht erst dort, wo es seitlich
     oder unter der Karte austritt — bei zentriertem Cursor sind das rund
     160px (halbe Posterhöhe). Ein Verlauf, der vorher bei null ist, ist
     unsichtbar; mit 240px war der Effekt weg (gemessen).

     Die Reduzierung liegt deshalb nicht im Radius, sondern im Abfall: 40 % der
     Kerndeckkraft schon bei 30 % und null bei 85 %. Ein langer, flacher Ausläufer
     (.08 erst bei 55 %, null bei 80 %) färbte den ganzen Weißraum neben der
     Karte ein — jetzt ist das Licht ein Fleck auf Cursorhöhe, der nach oben
     und unten wegfällt, statt eines gleichmäßigen Schleiers.

     Waagerecht --glow-reach, senkrecht 47 % davon — und die Ungleichheit ist
     der Punkt: eine 880px breite Karte (/erfolgsgeschichten/) hat von der Mitte
     bis zum Austrittsstreifen über 440px. Mit dem früheren Radius von 380px
     erreichte das Licht diesen Streifen bei mittigem Cursor gar nicht erst,
     deshalb war der Effekt dort praktisch unsichtbar; auf den schmalen
     grid-2-Karten (~580px) reichte es knapp. Senkrecht darf es NICHT auf
     denselben Wert wachsen, sonst wird aus dem Fleck auf Cursorhöhe wieder ein
     Schleier bis unter die Überschrift.

     Deckkraft bleibt niedrig: auf Weiß wird aus Orange sofort eine Fläche,
     und unter der Karte steht Text, der lesbar bleiben muss. Der Effekt darf
     nur eine Ahnung von Licht sein — bei .9/.3 war es ein oranger
     Farbverlauf. Auch .46/.20 war zu viel: der breite Radius verteilt die
     Deckkraft über eine viel größere Fläche als früher, dieselbe Zahl wirkt
     dadurch stärker. Reichweite und Deckkraft gehören hier gegenläufig. */
  background:
    radial-gradient(var(--glow-reach) calc(var(--glow-reach) * .47) at calc(var(--mx, 50%) + var(--glow-spread)) calc(var(--my, 50%) + var(--glow-spread-y)),
      rgba(255, 148, 10, var(--glow-a)), rgba(255, 148, 10, calc(var(--glow-a) * .4)) 30%, rgba(255, 148, 10, 0) 85%);
  /* Der Kasten des Pseudo-Elements hat harte Kanten, und der Verlauf ist dort
     noch nicht bei null — genau das wäre ein sichtbarer Abbruch an der
     Grid-Kante. Die Maske blendet das Licht an allen vier Seiten des Kastens
     auf null aus, unabhängig davon, wo der Cursor steht. Damit darf der Kasten
     beliebig weit reichen, ohne je eine Kante zu zeigen. Ein blur() darüber
     wäre überflüssig und würde bei jeder Mausbewegung neu gerechnet.

     ACHTUNG: dieser Kommentar muss EIN Block bleiben. Stand hier ein zweites,
     nicht geöffnetes Kommentarstück, verwarf der CSS-Parser bei der
     Fehlerbehebung bis zum nächsten Semikolon — und das war genau die
     mask-image-Zeile. Ohne Maske zeigte der Kasten wieder seine Kante.

     Zwei Kanten-Verläufe statt einer Ellipse (closest-side, #000 72 %), und der
     Wechsel war nötig, nicht kosmetisch: eine Ellipse blendet in PROZENT des
     Kastens aus. Ihre Ausblendzone war damit rund 148px breit — breiter als der
     ganze Austrittsstreifen neben der Karte, der Effekt lag komplett darin und
     war kaum zu sehen. Größerer Überstand vergrößerte die Zone mit. Dazu traf
     die Ellipse die Kartenecken (r ≈ 1,09) und löschte das Licht genau dort,
     wo der Cursor in einer Ecke steht.

     In px ist die Zone unabhängig vom Überstand: waagerecht die äußeren 100px
     der 170px, senkrecht 44px der 56px. Neben der Karte bleiben dadurch 70px
     volles Licht, und die Kartenfläche selbst ist nie maskiert. mask-composite:
     intersect, weil zwei Masken sonst vereinigt (add) werden — dann maskiert
     keine der beiden und die Kante ist wieder da. */
  mask-image:
    linear-gradient(to right, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%);
  mask-composite: intersect;
  opacity: 0;
  transition: opacity .3s var(--ease);
  pointer-events: none;
}
/* Nur wo es einen echten Zeiger gibt — auf dem Handy bleibt :hover nach dem
   Antippen hängen und die Karte würde dauerhaft leuchten. */
@media (hover: hover) {
  .vp--karte:hover::before { opacity: 1; }
}
/* Beim Durchtabben gibt es keinen Cursor — dann leuchtet die Karte mittig,
   damit Tastatur dieselbe Rückmeldung bekommt wie die Maus. */
.vp--karte:has(.vp-hit:focus-visible)::before { opacity: 1; }
/* Auf dem Handy gibt es keinen Hover, der das Licht zeigen könnte — dann muss
   das Element auch nicht existieren. */
@media (max-width: 767px) {
  .vp--karte::before { display: none; }
}
/* Das Poster hebt sich beim Leuchten leicht aus der Fläche, sonst wirkt das
   Licht wie hinter Glas statt hinter der Karte.

   Der zweite, orange Schatten ist der Grundschein und nicht bloß Deko: das
   Cursorlicht oben kann nur dort austreten, wo neben der Karte Platz ist —
   auf der 880px breiten Karte (/erfolgsgeschichten/) sind das vom mittigen
   Cursor aus über 440px, dort ist der Verlauf längst bei fast null und der
   Effekt praktisch unsichtbar. Der Schein am Poster hängt dagegen nicht am
   Cursor: er liegt auf allen vier Seiten an und ist auf jeder Kartenbreite
   gleich da. Das Cursorlicht bleibt darüber der wandernde helle Fleck.

   Weite und wenig Streuung statt Deckkraft — auf hellem Grund wird aus Orange
   sofort eine Fläche, und unter der Karte steht Text, der lesbar bleiben muss.
   Mit 60px/18px bei .30 war es ein oranger Rahmen um das Poster statt eines
   Scheins; die Streuung ist der empfindlichere Wert, sie trägt die volle
   Deckkraft nach außen, bevor die Weite überhaupt anfängt zu verlaufen. Deshalb
   bleibt sie bei 5px konstant, während die Weite (5 % der Reichweite: 45/32/23px
   über die drei Stufen) und die Deckkraft (halbe Kerndeckkraft) mitwandern —
   ein 45px-Schein um eine 375px-Karte wäre Nebel.

   Wie beim Cursorlicht nur bei echtem Zeiger: auf dem Handy bleibt :hover nach
   dem Antippen hängen, und ein oranger Schein, der dann dauerhaft um eine
   Karte steht, sieht aus wie ein Fehler. */
@media (hover: hover) {
  .vp--karte:hover .vp-thumb {
    box-shadow:
      0 10px 30px rgba(25, 45, 77, .14),
      0 0 calc(var(--glow-reach) * .05) 5px rgba(255, 148, 10, calc(var(--glow-a) * .5));
  }
}

/* Das Licht ragt --glow-spread über die Karte hinaus — an engen Fenstern also
   auch über den Container, und das erzeugt waagerechtes Scrollen (gemessen:
   336px Scrollbreite bei 320px Fenster). Diese Klasse gehört an die Sektion,
   die die Karten trägt, und unterdrückt genau das.

   overflow: clip statt hidden, weil hidden einen Scroll-Container aufmacht und
   damit position: sticky im Header bricht. Beide Achsen, nicht nur x: bei
   overflow-x: clip mit overflow-y: visible rechnet der Browser die zweite
   Achse auf auto — dann wird oben und unten mitgeschnitten (sichtbar als
   waagerechte Kante an der Sektionsoberkante).

   Kein overflow-clip-margin: der Freibetrag verschiebt nur die Schnittkante,
   zählt aber wieder als Überlauf (gemessen: 990px Scrollbreite bei 900px
   Fenster). Stattdessen ist der senkrechte Überstand des Lichts kleiner
   gehalten als das Sektionspolster — dann schneidet clip nur Leerraum. */
.vp-section { overflow: clip; }

/* ---------- 42. Terminliste (Webinare) ----------
   Zwei Termine als zwei gleich große Karten nebeneinander stellen eine
   Wahl in den Raum, die niemand treffen will — beide sind kostenfrei,
   beide 45 Minuten, es unterscheidet sie nur das Thema. Als Zeilen
   gelesen fällt die Wahl weg: Datum, Titel, Fakten und Aktion liegen
   auf einer Achse, das Auge läuft eine Spalte hinunter statt zwischen
   zwei Blöcken hin und her. Und die Liste trägt zehn Termine genauso
   wie zwei, ein Kartenraster bricht ab drei Stück um.

   Keine Karten also, sondern Haarlinien: nichts an einem Termin ist
   erhaben, er steht nur früher oder später im Kalender. Erst der Hover
   hebt die Zeile auf Weiß und setzt die orange Kante — dieselbe
   Zustandsanzeige wie beim geöffneten FAQ-Eintrag (Abschnitt 20).
   ============================================================ */
.termin-liste { border-top: 1px solid var(--line-strong); }

.termin {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) auto;
  gap: 28px;
  align-items: center;
  padding: 26px 24px 26px 21px;
  border-bottom: 1px solid var(--line-strong);
  /* Der transparente Rahmen liegt von Anfang an da, sonst springt die
     Zeile beim Hover um 3px nach rechts. */
  border-left: 3px solid transparent;
  transition: background .2s var(--ease), border-left-color .2s var(--ease);
}
.termin:hover { background: var(--paper); border-left-color: var(--orange); }
.section--soft .termin:hover { background: var(--paper); }

.termin__datum { text-align: center; font-variant-numeric: tabular-nums; }
.termin__tag {
  display: block; font-size: 38px; font-weight: 700; line-height: 1;
  color: var(--navy); letter-spacing: -0.03em;
}
.termin__monat {
  display: block; font-size: 12px; font-weight: 700; letter-spacing: .01em; color: var(--muted); margin-top: 5px;
}
.termin h3 { font-size: 19px; margin: 0 0 8px; }

/* Die Fakten sind bei jedem Webinar dieselben. Als Fließtext liest man
   sie beim zweiten Termin noch einmal mit, als Icon-Zeile erkennt man
   sie wieder, ohne sie zu lesen. Icons als Data-URI wie bei .check-list,
   damit die Zeile im Markup kein SVG mitschleppt. */
.termin__meta {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  font-size: 14px; color: var(--muted); margin: 0; max-width: none;
}
.termin__meta span { display: inline-flex; align-items: center; gap: 7px; }
.termin__meta span::before {
  content: ""; flex: none; width: 15px; height: 15px;
  background: center / contain no-repeat;
}
.termin__meta .is-dauer::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%231E4975' stroke-width='1.6'%3E%3Ccircle cx='8' cy='8' r='6.5'/%3E%3Cpath d='M8 4.5V8l2.5 1.5' stroke-linecap='round'/%3E%3C/svg%3E");
}
.termin__meta .is-qa::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%231E4975' stroke-width='1.6'%3E%3Cpath d='M2 4.5h12v7.5H9l-3 2v-2H2z' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.termin__meta .is-aufzeichnung::before {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%231E4975' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M8 2v8m0 0 3-3m-3 3L5 7M2.5 12.5h11'/%3E%3C/svg%3E");
}

.termin__aktion { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }

/* Kein Button, weil daneben schon einer steht und zwei gleich laute
   Aktionen die Anmeldung schwächen. */
.termin__ics {
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--muted);
  background: none; border: 0; cursor: pointer;
  text-decoration: underline; text-decoration-color: var(--line-strong);
  text-underline-offset: 3px;
  /* 18px hoch war der kleinste Klickbereich der ganzen Seite. Das Polster
     bringt die Fläche auf 34px, ohne die Zeile optisch zu verschieben:
     der negative Rand nimmt die Einrückung nach links wieder zurück. */
  padding: 8px 4px; margin-left: -4px;
}
.termin__ics:hover { color: var(--navy); text-decoration-color: currentColor; }

.termin__naechster {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; letter-spacing: .01em;
  /* #FF940A trägt auf Weiß keine Schrift (2,21:1) — als Text gilt #B65E00. */
  color: var(--orange-text); margin-bottom: 8px;
}
.termin__naechster::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange); flex: none;
}

@media (max-width: 767px) {
  /* Der Button rutscht unter den Titel statt an den rechten Rand, sonst
     bleibt neben dem Datum nichts mehr für die Überschrift übrig. Beide
     Aktionen bleiben untereinander: nebeneinander bricht spätestens auf
     390px die Button-Beschriftung um. */
  .termin { grid-template-columns: 64px minmax(0, 1fr); gap: 18px; padding: 22px 0 22px 15px; }
  .termin__tag { font-size: 30px; }
  .termin__aktion { grid-column: 2; align-items: flex-start; gap: 12px; }
  .termin__aktion > * { white-space: nowrap; }
}

/* ---------- 43. Glossar-Explorer (C22) ----------
   Ersetzt das Sechser-Kartenraster auf wissen.html. Begriffe als
   Reiterleiste, darunter die Erklärung: Begriff links, Text rechts.
   Die Auswahl läuft über Radio-Inputs statt JavaScript — damit
   funktionieren Pfeiltasten, Tab und Deep-Link-freies Zurück ohne
   eine Zeile Skript. Die sechs Inputs stehen vor .glossar__grid,
   weil die :checked-Regeln über den Geschwister-Kombinator laufen.
   ------------------------------------------------------------ */
.glossar input { position: absolute; opacity: 0; pointer-events: none; }
.glossar__grid { display: grid; gap: 40px; }

.glossar__nav {
  display: flex; flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
}
.glossar__nav label {
  position: relative; padding: 12px 22px 16px; cursor: pointer;
  font-size: 16px; font-weight: 600; color: var(--muted);
  transition: color .2s var(--ease);
}
.glossar__nav label:first-of-type { padding-left: 0; }
.glossar__nav label:hover { color: var(--navy); }
.glossar__nav label::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--orange); transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease);
}

.glossar__stage { min-height: 300px; }
.glossar__panel { display: none; column-gap: 56px; grid-template-columns: 300px minmax(0, 1fr); }
.glossar__panel h3 { font-size: clamp(28px, 3.4vw, 40px); letter-spacing: -0.025em; }
.glossar__panel p { font-size: 19px; line-height: 1.6; color: var(--ink); max-width: 54ch; }
/* Satzspiegel ohne zusätzliche Wrapper: Kategorie und Begriff links,
   alles weitere rechts. Der Begriff spannt über die Folgezeilen, sonst
   drückt seine Höhe eine Lücke zwischen Absatz und Trennstrich. */
.glossar__panel > *         { grid-column: 2; }
.glossar__panel > .glossar__cat { grid-column: 1; grid-row: 1; margin: 0; }
.glossar__panel > h3        { grid-column: 1; grid-row: 2 / span 3; align-self: start; margin: 10px 0 0; }
.glossar__panel > p         { grid-column: 2; grid-row: 1 / span 2; margin: 0; }
.glossar__cat {
  font-size: 11px; font-weight: 700; letter-spacing: .01em;
  color: var(--muted-soft);
}
.glossar__panel .btn-arrow { margin-top: 28px; padding-top: 0; }

/* Querverweise: dieselben Radios, die Bühne springt also direkt weiter. */
.glossar__rel {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 34px; padding-top: 20px; border-top: 1px solid var(--line);
}
.glossar__rel span { font-size: 13px; color: var(--muted-soft); margin-right: 6px; }
.glossar__rel label {
  padding: 6px 14px; border-radius: var(--radius-pill);
  background: var(--navy-soft); color: var(--navy);
  font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.glossar__rel label:hover { background: var(--navy); color: #fff; }

.glossar__i1:checked ~ .glossar__grid .glossar__panel:nth-of-type(1),
.glossar__i2:checked ~ .glossar__grid .glossar__panel:nth-of-type(2),
.glossar__i3:checked ~ .glossar__grid .glossar__panel:nth-of-type(3),
.glossar__i4:checked ~ .glossar__grid .glossar__panel:nth-of-type(4),
.glossar__i5:checked ~ .glossar__grid .glossar__panel:nth-of-type(5),
.glossar__i6:checked ~ .glossar__grid .glossar__panel:nth-of-type(6) {
  display: grid; --fade-y: 10px; animation: fade-up .4s var(--ease) both;
}
.glossar__i1:checked ~ .glossar__grid .glossar__nav label:nth-of-type(1),
.glossar__i2:checked ~ .glossar__grid .glossar__nav label:nth-of-type(2),
.glossar__i3:checked ~ .glossar__grid .glossar__nav label:nth-of-type(3),
.glossar__i4:checked ~ .glossar__grid .glossar__nav label:nth-of-type(4),
.glossar__i5:checked ~ .glossar__grid .glossar__nav label:nth-of-type(5),
.glossar__i6:checked ~ .glossar__grid .glossar__nav label:nth-of-type(6) { color: var(--navy); }
.glossar__i1:checked ~ .glossar__grid .glossar__nav label:nth-of-type(1)::before,
.glossar__i2:checked ~ .glossar__grid .glossar__nav label:nth-of-type(2)::before,
.glossar__i3:checked ~ .glossar__grid .glossar__nav label:nth-of-type(3)::before,
.glossar__i4:checked ~ .glossar__grid .glossar__nav label:nth-of-type(4)::before,
.glossar__i5:checked ~ .glossar__grid .glossar__nav label:nth-of-type(5)::before,
.glossar__i6:checked ~ .glossar__grid .glossar__nav label:nth-of-type(6)::before { transform: scaleX(1); }
/* Der echte Input ist unsichtbar, der Fokusring muss also an die Leiste. */
.glossar input:focus-visible ~ .glossar__grid .glossar__nav { outline: 2px solid var(--orange); outline-offset: 6px; border-radius: 4px; }

@media (max-width: 860px) {
  /* Die Kante zeigt, dass rechts noch Begriffe stehen — bei 390px sind 4,5 von
     6 sichtbar, und ohne Hinweis liest ein abgeschnittenes Wort als Fehler,
     nicht als Scroller. mask blendet nur die letzten 32px aus. */
  .glossar__nav {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none;
    mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
  }
  .glossar__nav::-webkit-scrollbar { display: none; }
  .glossar__nav label { flex: none; scroll-snap-align: start; white-space: nowrap; padding: 10px 14px; font-size: 15px; }
  .glossar__nav label:first-of-type { padding-left: 14px; }
  /* Alle Kinder zurück in eine Spalte. Die Regeln oben sind spezifischer
     als ein reines > *, deshalb stehen sie hier noch einmal namentlich. */
  .glossar__panel { grid-template-columns: 1fr; }
  .glossar__panel > *,
  .glossar__panel > .glossar__cat,
  .glossar__panel > h3,
  .glossar__panel > p { grid-column: 1; grid-row: auto; }
  .glossar__panel > h3 { margin: 6px 0 14px; }
  .glossar__panel > p { margin-bottom: 16px; font-size: 17px; }
  .glossar__stage { min-height: 340px; }
}

/* ---------- 44. Newsletter kompakt (C21) ----------
   Eine Zeile statt einer ganzen Sektion: Text links, Formular rechts.
   Bewusst ohne h2 — auf den News-Seiten folgt direkt der CTA-Block,
   der die Hauptaussage tragen soll. Der Titel hat trotzdem H2-Grösse:
   die Zeile ging in der alten Fassung (19px, keine eigene Fläche) neben
   dem Beitragsgrid unter, obwohl sie das Abo tragen soll. Gewicht ohne
   Gliederungsebene — im Dokumentumriss bleibt es ein Absatz.

   Die Fläche kommt nicht von der Farbe, sondern von der Höhe: die Bahn ist
   getönt (.section--soft im Markup), die Box liegt als weisse Karte darüber.
   Kein Navy — direkt darunter stehen .cta-block und der Footer, beide navy;
   eine dritte dunkle Bahn hintereinander verschwimmt zu einem Block.

   Die orange Flanke ist 3px: dasselbe Mass wie bei .termin (Abschnitt 42),
   .faq summary::before und der Trust-Bar im Hero — nicht dicker, sonst gäbe
   es zwei Konventionen für dieselbe Kante.
   ------------------------------------------------------------ */
.newsletter-compact { padding: 56px 0; }
@media (max-width: 767px) { .newsletter-compact { padding: 40px 0; } }
.newsletter-compact__box {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 460px); gap: 20px 44px; align-items: center;
  background: var(--paper); border-radius: var(--radius-card);
  border-left: 3px solid var(--orange);
  box-shadow: var(--shadow-card); padding: 32px 36px;
  /* Nur Schatten und transform: eine animierte Rahmenbreite oder ein
     wachsendes Polster rechnet bei jedem Frame das Layout neu und schiebt
     den Karteninhalt mit. Derselbe Grund, aus dem .termin die Kantenfarbe
     animiert und nicht die Kante. */
  transition: box-shadow .25s var(--ease), transform .25s var(--ease);
}
/* Sobald jemand im Feld steht, hebt die Karte an — Rückmeldung ohne ein
   zusätzliches Wort. :focus-within statt :hover, weil die Karte selbst nichts
   ist, was man anklickt; die Handlung steckt im Formular. */
.newsletter-compact__box:focus-within { box-shadow: var(--shadow-float); transform: translateY(-2px); }
@media (max-width: 860px) { .newsletter-compact__box { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 767px) { .newsletter-compact__box { padding: 24px 20px; } }
/* text-wrap: balance, weil der Titel ein Absatz ist und den Ausgleich der
   Überschriften (Abschnitt 2) nicht erbt — ohne ihn hing „1×" allein am Ende
   der ersten Zeile, getrennt von „im Monat". */
.newsletter-compact__title { font-size: var(--text-h2); line-height: 1.15; font-weight: 700; color: var(--navy); letter-spacing: -0.02em; text-wrap: balance; margin: 8px 0 8px; max-width: 30ch; }
.newsletter-compact__text { font-size: 15px; color: var(--muted); margin: 0; max-width: 52ch; }
.newsletter-compact .newsletter-form { max-width: none; }
.newsletter-compact .newsletter-form input[type="email"] { min-width: 240px; }
/* Sichtbare Beschriftung seit 05.10.2026, damit der Pflicht-Stern einen Platz
   hat. Eigene Zeile über Feld und Knopf, Werte wie .field label. */
.newsletter-form__label { flex-basis: 100%; font-size: 14px; font-weight: 600; color: var(--navy); margin-bottom: -4px; }
.newsletter-compact__foot { margin: 12px 0 0; }

/* Zustände des Anmeldeformulars — Mock, bis der Campaigns-Webhook dran ist */
.newsletter-error { display: none; font-size: 13px; font-weight: 600; color: var(--error); margin: 10px 0 0; }
form.has-error .newsletter-error { display: block; }
.newsletter-ok { display: none; align-items: center; gap: 10px; font-size: 16px; font-weight: 600; color: var(--navy); margin: 0; }
.newsletter-ok::before {
  content: ""; width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: var(--success) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-6' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px no-repeat;
}
/* [data-newsletter] mit im Selektor, damit diese Regeln die Layout-Regeln schlagen */
[data-newsletter].is-done form { display: none; }
[data-newsletter].is-done .newsletter-ok { display: flex; }
[data-newsletter].is-done .hide-on-done { display: none; }

/* ---------- 45. Filterleiste (C23) ----------
   Zwei Dropdowns (wachsen mit dem Datenbestand) + ein Suchfeld für alles,
   was keine feste Dimension hat. Alle drei nutzen .field aus Abschnitt 20,
   deshalb stehen sie ohne Sonderregel auf einer Grundlinie.
   Motor: [data-filter-grid] in main.js.
   ------------------------------------------------------------ */
.filter-bar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px 20px;
  padding: 24px 0; margin-bottom: 40px;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.filter-bar .field { flex: 1 1 200px; max-width: 260px; }

.filter-bar__count { flex: 1 1 auto; margin: 0; text-align: right; font-size: 14px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.filter-bar__count b { color: var(--navy); }
@media (max-width: 860px) {
  .filter-bar .field { max-width: none; }
  .filter-bar__count { text-align: left; }
}

/* Leer-Zustand einer Filterung */
.filter-empty { border: 1.5px dashed var(--line-strong); border-radius: var(--radius-card); padding: 36px 24px; text-align: center; color: var(--muted); margin: 0; max-width: none; }

/* ---------- 45a. Kopfkarte mit Kanalliste (Karriere & Kontakt) ----------
   (Trug bis zur Übergabe versehentlich ebenfalls die 43 — die gehört dem
   Glossar-Explorer weiter oben. Querverweise auf „§43" meinen das Glossar.)
   Zwei Karten nebeneinander bleiben, aber jede bekommt eine eigene
   Kopfzone: Navy für Kontakt, das helle Blaugrau für Karriere. Das
   trennt die beiden Angebote, ohne dass eine Karte größer werden muss,
   und gibt der Liste darunter eine Kante, an der sie ansetzt.

   Der eigentliche Grund für den Umbau steckt aber im Karteninneren:
   Telefonnummer und Mail standen als zwei unterstrichene Wörter in
   einer Adresszeile, also in Fließtextgröße zwischen Trennpunkten.
   Als eigene Zeile mit Wert und Zusatzinfo sind sie das, was sie sein
   sollen — drei Wege, jeder mit einem Klick erreichbar. Diese Section
   ist die einzige Stelle der Seite mit Anschrift und Rufnummer, der
   Footer führt sie nicht.
   ============================================================ */
.kopfkarte {
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-card);
  box-shadow: 0 1px 2px rgba(22, 51, 79, .05);
  overflow: hidden;
}
.kopfkarte__kopf { background: var(--navy-soft); padding: 26px 34px; }
.kopfkarte__kopf h3 { font-size: 23px; margin-bottom: 0; }
.kopfkarte--navy .kopfkarte__kopf { background: var(--navy); }
/* :is(h2,h3,h4) statt nur h3: /ueber-uns/ setzt in den Kartenkopf ein <h3>,
   /kontakt/ setzte bis 05.10.2026 ein <h2> (dort war es die Überschrift der
   Section). Solange hier nur h3 stand, blieb eine solche Überschrift in der
   Erbfarbe --navy auf der navy Fläche stehen, Kontrast 1:1, faktisch
   unsichtbar. Bewusst NUR die Farbe geöffnet: die Zeile darüber lässt
   font-size weiter an h3 hängen. */
.kopfkarte--navy .kopfkarte__kopf :is(h2, h3, h4) { color: #fff; }
.kopfkarte--navy .kopfkarte__kopf .eyebrow { color: #9FB8CE; }
.kopfkarte__body { display: flex; flex-direction: column; flex: 1; padding: 24px 34px 34px; }
.kopfkarte__body > p { font-size: 16px; }
/* Der Fuß sitzt unten, damit beide Karten trotz unterschiedlich
   langer Inhalte auf einer Linie abschließen. */
/* Selektor mit .kopfkarte__body, weil `.kopfkarte__body > p` (0,1,1) sonst die
   14px überstimmt — die Faktenzeile lief dadurch in Fließtextgröße mit 1.6er
   Zeilenhöhe. Als kleine Zeile braucht sie eine engere Zeilenhöhe (1.5). */
.kopfkarte__body > .kopfkarte__fakt { font-size: 14px; line-height: 1.5; color: var(--muted); margin: 16px 0 0; }
.kopfkarte__fuss { margin-top: auto; padding-top: 24px; }

.kanal-liste { list-style: none; margin: 0; padding: 0; max-width: none; font-style: normal; }
.kanal-liste li { margin: 0; border-top: 1px solid var(--line); }
.kanal-liste li:first-child { border-top: 0; }
.kanal {
  position: relative;
  display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 16px; align-items: center;
  padding: 16px 2px;
  text-decoration: none; color: inherit;
}
/* Icons als Data-URI wie bei .check-list — hält das Markup frei von SVG. */
.kanal::before {
  content: ""; width: 20px; height: 20px;
  background: center / contain no-repeat;
  transition: transform .2s var(--ease);
}
.kanal--tel::before  { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%231E4975' stroke-width='1.5' stroke-linejoin='round'%3E%3Cpath d='M6.5 3h-2A1.5 1.5 0 0 0 3 4.5C3 11 9 17 15.5 17A1.5 1.5 0 0 0 17 15.5v-2l-3.5-1.2-1.6 1.9a11.6 11.6 0 0 1-4.1-4.1l1.9-1.6z'/%3E%3C/svg%3E"); }
.kanal--mail::before { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%231E4975' stroke-width='1.5' stroke-linejoin='round'%3E%3Crect x='2.5' y='4.5' width='15' height='11' rx='1.5'/%3E%3Cpath d='m3 5.5 7 5 7-5'/%3E%3C/svg%3E"); }
.kanal--pin::before  { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%231E4975' stroke-width='1.5' stroke-linejoin='round'%3E%3Cpath d='M10 17.5s5.5-5 5.5-9a5.5 5.5 0 1 0-11 0c0 4 5.5 9 5.5 9z'/%3E%3Ccircle cx='10' cy='8.5' r='2'/%3E%3C/svg%3E"); }

/* Der Unterstrich wächst aus der Zeile heraus, statt sie einzufärben:
   die Karte bleibt ruhig, das Feedback sitzt an der Kante, an der die
   Zeile ohnehin endet. */
.kanal::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--orange);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .28s var(--ease);
}
.kanal:hover::after, .kanal:focus-visible::after { transform: scaleX(1); }
.kanal:hover::before { transform: translateX(2px); }

/* 19px, nicht 17px: auf Fließtextgröße unterscheidet den Wert nur noch
   das Fettgewicht vom Absatz — dann geht er wieder unter, und genau das
   war der Anlass. Stufen in der Karte: 23 / 19 / 16 / 14. */
.kanal__wert { display: block; font-size: 19px; font-weight: 700; color: var(--navy); letter-spacing: -0.015em; }
.kanal__note { display: block; font-size: 14px; color: var(--muted); margin-top: 2px; }
.kanal:hover .kanal__wert { color: var(--orange-text); }

/* Die drei Zeilen laufen nacheinander ein, von oben nach unten — genau
   die Reihenfolge, in der sie gelesen werden sollen. */
.kanal-liste li { opacity: 0; transform: translateY(8px); }
.kanal-liste.is-visible li { animation: kanal-ein .5s var(--ease) forwards; }
.kanal-liste.is-visible li:nth-child(2) { animation-delay: .09s; }
.kanal-liste.is-visible li:nth-child(3) { animation-delay: .18s; }
@keyframes kanal-ein { to { opacity: 1; transform: none; } }
/* Abschnitt 2 schaltet Animationen bei prefers-reduced-motion global ab —
   ohne diese Zeile blieben die Kanäle dann unsichtbar. */
@media (prefers-reduced-motion: reduce) {
  .kanal-liste li { opacity: 1; transform: none; }
}
/* .reveal würde die ganze Liste zusätzlich hochschieben. Hier sollen nur
   die Zeilen laufen, die Karte steht sofort. Zwei Klassen schlagen .reveal. */
.kanal-liste.reveal { opacity: 1; transform: none; }

.chip-liste { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 18px 0 0; padding: 0; max-width: none; }
.chip-liste li { margin: 0; }

@media (max-width: 860px) {
  .kopfkarte__kopf { padding: 22px 24px; }
  .kopfkarte__body { padding: 20px 24px 28px; }
}

/* ---------- 46. Fokus-Liste (Symptome, Variante D) ----------
   Überschrift und Einordnung stehen links, die Aussagen rechts. Beim
   Überfahren tritt eine Aussage hervor, die anderen treten zurück — reine
   CSS-Zugabe: ohne Maus und auf dem Handy steht alles gleichwertig da.
   ------------------------------------------------------------ */
.fokus { display: grid; grid-template-columns: minmax(240px, 32%) 1fr; gap: 56px; align-items: start; }
/* Der Kopf läuft mit, solange die Liste noch scrollt: Der Grid-Bereich ist so
   hoch wie die Liste, deshalb endet das Kleben von allein am Section-Ende —
   kein JS. `align-self: start` ist Bedingung, ein gestrecktes Element hat
   keinen Weg zum Wandern. 88px = 72px Header + 16px Luft. */
.fokus__aside { position: sticky; top: 88px; align-self: start; }
.fokus__aside h2 { font-size: 26px; letter-spacing: -.02em; margin-bottom: 12px; }
.fokus__aside p { font-size: 16px; color: var(--muted); margin: 0; }
.fokus__liste { list-style: none; margin: 0; padding: 0; max-width: none; }  /* main.css deckelt ul auf 66ch */
.fokus__liste li { margin: 0; border-top: 1px solid var(--line); transition: opacity .25s var(--ease); }
.fokus__liste li:last-child { border-bottom: 1px solid var(--line); }
.fokus__liste:hover li { opacity: .38; }
.fokus__liste:hover li:hover { opacity: 1; }
.fokus__row { display: grid; grid-template-columns: 32px 1fr; gap: 18px; align-items: start; padding: 26px 0; }
/* Zahlkreis wie .stufe-card__num / .steps li::before — Zahlkreise sehen auf
   der ganzen Seite gleich aus. 2px Versatz, damit der Kreis optisch auf der
   ersten Textzeile sitzt (Zeilenhöhe 1.45 bei 17–20px). */
.fokus__num {
  width: 32px; height: 32px;
  margin-top: -2px;
  border-radius: 50%;
  background: var(--navy-soft);
  color: var(--navy);
  font-weight: 700;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s ease, color .2s ease;
}
.fokus__row p { font-size: clamp(17px, 1.6vw, 20px); line-height: 1.45; color: var(--ink); margin: 0; max-width: 46ch; }
/* Ziffer auf Orange anthrazit, nicht weiss — wie bei .stufe-card__num. */
.fokus__liste li:hover .fokus__num { background: var(--orange); color: var(--ink); }
@media (max-width: 860px) {
  .fokus { grid-template-columns: 1fr; gap: 28px; }
  .fokus__aside { position: static; }      /* Einspaltig gibt es nichts zu begleiten. */
  .fokus__liste:hover li { opacity: 1; }   /* Auf Touch gibt es kein Überfahren. */
  .fokus__row { padding: 20px 0; gap: 14px; }
}

/* ---------- 47. App-Kern mit Andockung (zoho.html, Variante D) ----------
   Nimmt die Kernaussage der Seite wörtlich: Das CRM steht oben allein, die
   drei Phasen des Kundensystems docken darunter an. Vorher standen hier drei
   gleich laute Karten nebeneinander — nichts trat hervor.
   Regel dieser Section: genau EINE orange Markierung (der Kern). Alles
   andere trägt Hierarchie über Größe, Weißraum und Haarlinien.
   Die Verbindungslinien sind reine CSS-Flächen, keine Grafik.
   ------------------------------------------------------------ */
.core-tag {
  display: inline-block; vertical-align: 2px;
  font-size: 11px; font-weight: 700; letter-spacing: .01em;
  color: var(--ink); background: var(--orange);
  padding: 2px 8px; border-radius: var(--radius-pill);
}

.app-hub__cols, .app-hub__list, .app-hub__core p { max-width: none; }  /* main.css deckelt p/ul auf 66ch */

.app-hub__core {
  max-width: 520px; margin: 0 auto;
  /* Kein oranger Balken oben: Die KERN-Pille trägt den Akzent schon, und ein
     3px-Rand über einer 14px-Rundung bricht an den Ecken. Eine Markierung. */
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-card); background: var(--paper);
  padding: 24px 28px; text-align: center;
}
.app-hub__core h3 { font-size: 21px; margin-bottom: 6px; }
.app-hub__core p { font-size: 15px; color: var(--muted); margin: 0; }

/* Zulauf: ein Stiel vom Kern nach unten, ein Querbalken, drei Abgänge.
   Der Querbalken reicht von Mittelachse zu Mittelachse der äußeren Spalten,
   also 2/3 der Breite plus 2/3 des Spaltenabstands (24px). */
.app-hub__wires { position: relative; height: 62px; }
.app-hub__wires i { position: absolute; display: block; background: var(--line-strong); transform-origin: top center; }
.app-hub__wires .w-stem { left: 50%; top: 0; width: 2px; height: 30px; margin-left: -1px; }
.app-hub__wires .w-bar  { top: 30px; left: 50%; height: 2px; width: calc(66.666% + 16px); transform: translateX(-50%); transform-origin: center; }
.app-hub__wires .w-drop { top: 30px; width: 2px; height: 32px; margin-left: -1px; }
.app-hub__wires .w-drop:nth-of-type(3) { left: 16.666%; }
.app-hub__wires .w-drop:nth-of-type(4) { left: 50%; }
.app-hub__wires .w-drop:nth-of-type(5) { left: 83.333%; }

/* Die Linien zeichnen sich beim Hereinscrollen. Ohne Scroll-Timeline
   (ältere Browser) stehen sie einfach fertig da — nichts fehlt. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .app-hub__wires i { transform: scaleY(0); }
    .app-hub__wires .w-bar { transform: translateX(-50%) scaleX(0); }
    /* Früh im Sichtbereich fertig: Der Zulauf soll gezeichnet sein, sobald
       die Section wirklich gelesen wird — nicht erst am unteren Rand. */
    .app-hub__wires .w-stem { animation: app-hub-grow .01s linear both; animation-timeline: view(); animation-range: cover 6%  cover 16%; }
    .app-hub__wires .w-bar  { animation: app-hub-span .01s linear both; animation-timeline: view(); animation-range: cover 14% cover 26%; }
    .app-hub__wires .w-drop { animation: app-hub-grow .01s linear both; animation-timeline: view(); animation-range: cover 24% cover 34%; }
  }
}
@keyframes app-hub-grow { to { transform: scaleY(1); } }
@keyframes app-hub-span { to { transform: translateX(-50%) scaleX(1); } }

.app-hub__cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; list-style: none; padding: 0; margin: 0; }
.app-hub__col { margin: 0; }
.app-hub__colhead { text-align: center; margin-bottom: 16px; }
.app-hub__colhead .eyebrow { margin-bottom: 6px; font-variant-numeric: tabular-nums; }
.app-hub__colhead h3 { font-size: 19px; margin: 0; }
.app-hub__list { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.app-hub__list li {
  margin: 0; padding: 13px 16px;
  background: var(--paper); border: 1px solid transparent; border-radius: 10px;
  box-shadow: 0 1px 2px rgba(22, 51, 79, .05);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease);
}
.app-hub__list b { display: block; color: var(--navy); font-size: 16px; }
.app-hub__list span { display: block; font-size: 14px; color: var(--muted); margin-top: 2px; }
/* Apps mit eigener Seite werden klickbar. Der Link fuellt die Kachel per
   negativem Rand, damit die ganze Flaeche trifft und nicht nur die zwei
   Zeilen Text. Farbe und Unterstreichung bleiben die der Kachel — das
   vorhandene Hover der Kachel ist das Signal, eine zweite Auszeichnung
   waere im Vierer-Raster Unruhe. Apps ohne Seite bleiben unveraendert. */
.app-hub__list a {
  display: block; margin: -13px -16px; padding: 13px 16px;
  color: inherit; text-decoration: none; border-radius: 10px;
}
.app-hub__list a:hover b { color: var(--orange-text); }
.app-hub__list a:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.app-hub__col:hover .app-hub__list li { box-shadow: var(--shadow-card); }
.app-hub__col:hover .app-hub__list li:hover { transform: translateY(-2px); }
/* Beim Überfahren einer Spalte leuchtet ihr Zulauf auf. */
.app-hub:has(.app-hub__col:nth-child(1):hover) .w-drop:nth-of-type(3),
.app-hub:has(.app-hub__col:nth-child(2):hover) .w-drop:nth-of-type(4),
.app-hub:has(.app-hub__col:nth-child(3):hover) .w-drop:nth-of-type(5) { background: var(--orange); }

@media (max-width: 767px) {
  .app-hub__cols { grid-template-columns: 1fr; gap: 32px; }
  .app-hub__wires { height: 34px; }
  .app-hub__wires .w-bar, .app-hub__wires .w-drop { display: none; }
  .app-hub__wires .w-stem { height: 34px; }
  /* Gestapelt wird aus dem Fächer eine Kette: Kern → Phase → Phase → Phase.
     Ohne das hinge nur die erste Spalte sichtbar am Kern. */
  .app-hub__col + .app-hub__col::before {
    content: ""; display: block; width: 2px; height: 26px;
    background: var(--line-strong); margin: -6px auto 14px;
  }
}

/* ---------- 48. Siegel-Wand (zertifikate.html, Variante D) ----------
   Vier Zertifikate als Karten. Die Siegel liegen als farbige Bilddateien
   unter assets/img/siegel/, das Schwarz-Weiß macht CSS. Beim Austausch
   gegen die echten Logos ändert sich nur der src — es braucht keine
   zweite S/W-Fassung, und die Marken-Assets bleiben unverändert, was bei
   TÜV Süd und Zoho lizenzrechtlich der sichere Weg ist.

   Unter dem Zeiger geht das Siegel in Farbe und der Text auf volle
   Schwärze. Versteckt wird nichts: alle vier Texte stehen von Anfang an
   im Dokument, das Hover ist nur Betonung. */
.siegel-wand { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.siegel-karte {
  display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 28px; align-items: start;
  padding: 30px;
  border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--paper);
  transition: border-color .25s var(--ease), box-shadow .3s var(--ease);
}
.siegel-karte:hover { border-color: var(--line-strong); box-shadow: var(--shadow-card); }
.siegel-karte__bild {
  display: block; width: 100%; height: auto;
  filter: grayscale(1); opacity: .45;
  transition: filter .45s var(--ease), opacity .45s var(--ease);
}
.siegel-karte:hover .siegel-karte__bild { filter: none; opacity: 1; }
.siegel-karte__tag {
  display: inline-block; margin-bottom: 12px; padding: 4px 12px;
  font-size: 12px; font-weight: 700; letter-spacing: .01em;
  color: var(--muted-soft); background: var(--surface-2); border-radius: var(--radius-pill);
}
.siegel-karte h3 { font-size: 19px; margin-bottom: 10px; }
.siegel-karte__text {
  margin: 0 0 14px; max-width: none;
  font-size: 15.5px; line-height: 1.6; color: var(--muted-soft);
  transition: color .3s var(--ease);
}
.siegel-karte:hover .siegel-karte__text { color: var(--ink); }
/* Die Folge-Zeile trennt eine Haarlinie, kein farbiger Balken: viermal
   derselbe Akzent im Raster wäre Tapete statt Auszeichnung. */
.siegel-karte__folge {
  margin: 0; padding-top: 14px; border-top: 1px solid var(--line); max-width: none;
  font-size: 15px; line-height: 1.6; color: var(--muted-soft);
  transition: color .3s var(--ease);
}
.siegel-karte__folge strong { color: var(--navy); }
.siegel-karte:hover .siegel-karte__folge { color: var(--muted); }

/* Ohne Zeiger löst nie ein Hover aus. Auf Touch stehen deshalb alle
   Siegel dauerhaft farbig — sonst bliebe die Section dort für immer grau. */
@media (hover: none) {
  .siegel-karte__bild { filter: none; opacity: 1; }
  .siegel-karte__text { color: var(--ink); }
  .siegel-karte__folge { color: var(--muted); }
}
@media (max-width: 1024px) { .siegel-wand { grid-template-columns: 1fr; } }
@media (max-width: 767px) {
  .siegel-karte { grid-template-columns: 76px minmax(0, 1fr); gap: 18px; padding: 22px; }
}
/* Breite Pruefzeichen (AZAV, seit 05.10.2026): Der TUEV SUED liefert das Zeichen
   nur mit Text daneben, und zuschneiden darf man es nicht. In der quadratischen
   Spalte waere es 104px breit und unlesbar, deshalb eine eigene Spalte. Mobil
   steht es ueber dem Text. */
.siegel-karte--breit { grid-template-columns: 168px minmax(0, 1fr); }
@media (max-width: 767px) {
  .siegel-karte--breit { grid-template-columns: minmax(0, 1fr); }
  .siegel-karte--breit .siegel-karte__bild { max-width: 200px; }
}

/* Print: Sticky-Elemente ausblenden */
@media print {
  .site-header, .sticky-cta, .mobile-nav { display: none !important; }
}

/* ---------- 50. Reduzierte Seite (Erstgespräch) ----------
   Conversion-Strecke: Header ohne Menü, Footer ohne Spalten. Beides trug seine
   Maße als Inline-Style — der Footer wird auf dieser Seite bewusst NICHT von
   sync-nav.py überschrieben, deshalb ist die Variante hier eine Klasse. */
.header-back {
  font-weight: 600;
  font-size: var(--text-small);
  text-decoration: none;
  color: var(--navy);
}
.site-footer--compact { padding: var(--space-6) 0; }
.site-footer--compact .footer-legal { border: none; padding-top: 0; }

/* Mini-Hero: Textblock auf Leseweite, links gesetzt. Die eine Form für alle
   Mini-Heros (/prozesskostenrechner/, /erstgespraech/) — vorher stand sie auf
   der einen Seite als Inline-Style und auf der anderen als zentrierte
   Sondervariante. */
.hero__block { max-width: 760px; }
/* Listen sind global auf 66ch gedeckelt (Abschnitt 2) — im Hero brach der
   Deckel die Häkchenzeilen bei ~635px um, obwohl der Block 760px breit ist
   und rechts daneben nur Weissraum steht. Hier zählt die Blockbreite. */
.hero__block .check-list { max-width: none; }

/* Abschnitt 2 schaltet Übergänge bei prefers-reduced-motion global ab. Die
   Basis-Stauchung ist ein statisches transform und bleibt — die Linie ist
   dort also 2px und springt beim Hover ohne Übergang auf 4px. Nichts wird
   unsichtbar, deshalb braucht es hier keinen Ausweg. */

/* ---------- 54. Schichten mit gekoppelter Liste (KI-Detailseiten, Slot 8) ----------
   „Wo liegen meine Daten" wird gezeichnet statt zugesichert: drei
   ineinanderliegende Flächen (außen Rechenzentrum, darin die Zoho-Umgebung,
   darin die Daten), daneben die Aussagen als nummerierte Zeilen. Erster
   Verwender: Slot 8 „Datenkontrolle" der KI-Detailseiten.

   Der Vorgänger war eine .card--soft über die volle Containerbreite. Das ist
   gescheitert: sehr breite Fläche, Blocktext darin, die Aussage geht unter.

   Die Kopplung Zeile → Schicht macht :has(), wie an zwei Dutzend anderen
   Stellen der Datei — kein JS. Sie ist eine reine Maus-Zugabe ohne
   Tastatur-Entsprechung, weil in den Zeilen nichts Fokussierbares steckt;
   :focus-within wäre toter Code und würde Unterstützung vortäuschen, die es
   nicht gibt. Zulässig ist das nur, weil NICHTS hinter der Interaktion liegt:
   die Aussagen und die ganze Grafik stehen ohne Maus vollständig da (dieselbe
   Haltung wie Abschnitt 46). Bekommt eine Zeile einen Link, muss
   :focus-within nachgezogen werden.

   Die Grafik gehört auf HELLE Bahn: ihre äußere Fläche ist --surface-2, auf
   einer --soft-Bahn verschwindet die äußerste Schicht.
   ------------------------------------------------------------ */
.ds { display: grid; grid-template-columns: minmax(0, 42%) minmax(0, 1fr); gap: var(--space-8); align-items: center; }
.ds__figur { width: 100%; height: auto; }
.ds__schicht { transition: stroke .3s var(--ease); }
.ds__fuellung { transition: fill .3s var(--ease); }

.ds__liste { list-style: none; margin: 0; padding: 0; max-width: none; }  /* Abschnitt 2 deckelt ul auf 66ch */
.ds__liste li {
  margin: 0; padding: var(--space-4) 0; border-top: 1px solid var(--line);
  display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: var(--space-4); align-items: start;
  transition: opacity .25s var(--ease);
}
.ds__liste li:last-child { border-bottom: 1px solid var(--line); }
/* Zahlkreis wörtlich wie .fokus__num (Abschnitt 46) — Zahlkreise sehen auf der
   ganzen Seite gleich aus, und die Zeile daneben ist dieselbe Bauart. Ziffer
   auf Orange in Anthrazit, nicht weiß: Markenregel. Die 2px Versatz setzen den
   Kreis optisch auf die erste Textzeile. */
.ds__nr {
  width: 32px; height: 32px; margin-top: -2px;
  border-radius: 50%;
  background: var(--navy-soft); color: var(--navy);
  font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s ease, color .2s ease;
}
.ds__liste li:hover .ds__nr { background: var(--orange); color: var(--ink); }
.ds__liste:hover li { opacity: .38; }
.ds__liste:hover li:hover { opacity: 1; }
/* Zwei Zeilen übereinander, nicht ein Fließtext mit fettem Anfang: die Aussage
   steht oben, die Präzisierung darunter. Als eine Zeile lief die Präzisierung
   optisch in die Aussage hinein und die drei Punkte waren nicht auf einen Blick
   vergleichbar. Kein Satzpunkt am Ende — das sind Aufzählungsglieder, keine
   Sätze; ein Punkt hinter der ersten Zeile würde die zweite als neuen Satz
   ausweisen, was sie nicht ist. */
.ds__liste p { margin: 0; font-size: var(--text-small); }
.ds__liste strong { display: block; color: var(--navy); }
.ds__note { display: block; margin-top: 2px; color: var(--muted); }
/* Der Verweis sitzt in der rechten Spalte unter den Punkten, nicht unter der
   ganzen Section: so tragen beide Spalten annähernd dieselbe Höhe, und der
   nächste Schritt steht dort, wo gerade gelesen wurde. */
.ds__fuss { margin: var(--space-5) 0 0; }

/* Zeile 1 und 2 färben ihre eigene Schicht. Zeile 3 (die Richtlinien) färbt
   ALLE Schichten — „sie gelten über allen Schichten" ist die Aussage, also
   muss sie auch alle treffen. Der Kern „Deine Daten" bleibt in jedem Fall
   unangetastet: die Regeln gelten rundherum, die Daten selbst nicht. */
.ds:has(.ds__eu:hover) .ds__s-eu,
.ds:has(.ds__zoho:hover) .ds__s-zoho,
.ds:has(.ds__regel:hover) .ds__s-eu,
.ds:has(.ds__regel:hover) .ds__s-zoho { stroke: var(--orange); }
.ds:has(.ds__eu:hover) .ds__f-eu,
.ds:has(.ds__zoho:hover) .ds__f-zoho,
.ds:has(.ds__regel:hover) .ds__f-eu,
.ds:has(.ds__regel:hover) .ds__f-zoho { fill: var(--orange-flaeche); }

@media (max-width: 860px) {
  .ds { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
  .ds__figur { max-width: 380px; }
  .ds__liste:hover li { opacity: 1; }   /* Auf Touch gibt es kein Überfahren. */
}

/* --- 55b · Kontaktkarte (/service-support/, /kontakt/) ---
   Auf /kontakt/ nur mit Vorderseite und ohne data-flipcard, je Karte ein Knopf
   statt des Kontaktwerts: Anruf, Formular und Termin sind dort sofort da. */
.kkarte { perspective: 1600px; height: 100%; }
.kkarte__inner {
  display: grid; height: 100%; transform-style: preserve-3d;
  transition: transform .55s var(--ease); min-height: 300px;
}

/* Die Oberkante ist der obere RAHMEN der Karte, kein Pseudoelement: ein 4px
   hoher Balken mit eigenem border-radius endet an der Rundung in der Luft,
   weil 4px die 14px-Rundung nicht ausfahren können. Als border-top läuft die
   Farbe sauber in die Seitenrahmen aus. */
.kkarte__face {
  grid-area: 1 / 1; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 4px solid var(--kk-farbe, var(--navy));
  border-radius: var(--radius-card); padding: 26px 28px 28px;
}

.kkarte__medaillon {
  width: 56px; height: 56px; border-radius: 50%; margin-bottom: 18px;
  display: flex; align-items: center; justify-content: center;
  background: var(--kk-flaeche, var(--navy-soft));
  color: var(--kk-glyph, var(--navy));
}
.kkarte__medaillon svg { width: 26px; height: 26px; display: block; }
.kkarte__face h3 { margin-bottom: 10px; }
.kkarte__face p { font-size: 15px; }
/* Kontaktelement sitzt unten, per auto an den Kartenfuß geschoben. */
.kkarte__kontakt { margin-top: auto; padding-top: 18px; border-top: 1px solid var(--kk-linie, var(--line)); }

.kkarte__note { display: block; font-size: 14px; color: var(--muted); margin-top: 4px; }

.kkarte--anruf  { --kk-farbe: var(--orange);      --kk-flaeche: var(--orange-flaeche); --kk-linie: var(--orange-flaeche-linie); --kk-glyph: var(--ink); }
.kkarte--mail   { --kk-farbe: var(--navy);        --kk-flaeche: #DCE6F1;               --kk-linie: #C3D4E6;                     --kk-glyph: var(--navy); }
.kkarte--termin { --kk-farbe: var(--line-strong); --kk-flaeche: var(--surface-2);      --kk-linie: var(--line-strong);          --kk-glyph: var(--navy); }

/* --- 55c · Gemeinsames Verhalten --- */
@media (prefers-reduced-motion: reduce) {
  .kkarte__inner { transition: none; transform: none !important; }
  .kkarte__face { backface-visibility: visible; }
  
}

/* ---------- 55d. Zwei Programmkarten nebeneinander (.pricing-2) ---------- */
/* Gleiche Kartenhöhe: ohne align-items richtet sich jede Karte nach ihrem
   Inhalt, die Knöpfe fluchten dann nicht. Karte als Flex-Spalte, Knopf per
   auto ans Ende. */
.pricing-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
.pricing-2 > .card { display: flex; flex-direction: column; }
.pricing-2 > .card > .btn { margin-top: auto; align-self: flex-start; }
@media (max-width: 860px) { .pricing-2 { grid-template-columns: minmax(0, 1fr); } }

/* ---------- 56. Katalog-Umschalter (KI-Detailseiten Muster B, Slot 3) ----------
   Vier benannte Einheiten, von denen immer eine ausführlich dasteht. Erster
   Verwender /ki-loesungen/ (die vier KI-Lösungen), danach die neun Stufen auf
   /ki-im-kundensystem/.

   Die Reiterleiste selbst ist nicht neu: .segmented mit role="tablist" läuft
   bereits auf /foerderung/ und /ki/, den Umschalter macht main.js. Neu ist nur
   das Panel — und das ist absichtlich karg. Der Vorgänger .offer-row stellte
   pro Einheit eine Zeile mit einer Definitionsliste daneben; alle vier
   gleichzeitig, alle gleich laut, nichts trat hervor.

   Zwei Dinge, die man beim Ändern wissen muss:

   1. Die Fakten stehen in jedem Panel an derselben Stelle und in derselben
      Reihenfolge. Das ist der ganze Gewinn der Bauform: der Leser vergleicht
      vier Einheiten, ohne die Augen wandern zu lassen. Wer die Reihenfolge je
      Panel anders setzt, nimmt der Section ihren Sinn.
   2. Ohne JS steht Panel 1 allein da, die anderen bleiben hidden. Deshalb
      gehört in Panel 1 die Einheit, die am häufigsten gebraucht wird — nicht
      die alphabetisch erste.
   ------------------------------------------------------------ */
.ku__panel { padding-top: var(--space-6); }
.ku__panel[hidden] { display: none; }
/* Textspalte auf 66ch, nicht 1fr: der Absatz ist global auf 66ch gedeckelt,
   eine 1fr-Spalte wird auf grossen Breiten breiter als ihr Inhalt und die
   Faktenspalte rutscht an den Seitenrand. */
.ku__grid { display: grid; grid-template-columns: minmax(0, 66ch) minmax(0, 320px); gap: var(--space-7); align-items: start; }
.ku__grid h3 { margin: 0 0 var(--space-3); }
.ku__grid p { font-size: var(--text-small); }
.ku__grid p:last-child { margin-bottom: 0; }
.ku__grid b { color: var(--navy); }

.ku__fakten { display: grid; gap: 0; margin: 0; border-top: 2px solid var(--orange); }
/* Label über dem Wert, nicht daneben: die erste Zeile trägt „Ersetzt" und
   damit einen ganzen Halbsatz („Notizen abtippen nach jedem Termin"), keine
   zwei Wörter. Nebeneinander mit rechtsbündigem Wert wurde dieser Wert auf
   drei Zeilen gequetscht, während die Labelspalte leer stand. Untereinander
   trägt jede Zeile jede Länge — dieselbe Entscheidung wie bei .ds__note in
   Abschnitt 54. */
.ku__fakt { padding: var(--space-4) 0; border-bottom: 1px solid var(--line); }
.ku__fakt dt { font-size: var(--text-eyebrow); font-weight: 700; letter-spacing: .01em; color: var(--muted); margin-bottom: 4px; }
.ku__fakt dd { margin: 0; font-size: var(--text-small); font-weight: 700; color: var(--navy); }

@media (max-width: 860px) {
  .ku__grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
}

/* ---------- 57. Zertifizierungs-Wand (/zoho-premium-partner-deutschland/) ----------
   25 bestandene Zoho-Zertifizierungen als dichtes Raster. Gezeigt wird NICHT
   das offizielle Zoho-Badge je Pruefung, sondern das Produktlogo aus
   assets/img/zoho/: die Badges liegen als 400x400-PNG vor, 25 davon waeren
   rund 1,5 MB und auf Kartenbreite ohnehin unleserlich. Die Produktlogos sind
   SVG, auf eine gemeinsame Hoehe normalisiert (viewBox-Hoehe 296) und
   zusammen kleiner als ein einziges Badge.

   Kein Hover-Effekt wie bei der Siegel-Wand (Abschnitt 48): dort sind es vier
   Karten mit Text, hier 25 Kacheln ohne. Ein Zustandswechsel auf 25 Feldern
   ist Flimmern, keine Betonung. */
.zerti-wand {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px;
  list-style: none; padding: 0; margin: 0; max-width: none;
}
.zerti {
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; gap: 14px;
  min-height: 104px;
  padding: 18px;
  margin: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
}
/* Feste Hoehe, Breite nach Bedarf: die Wortmarken sind zwischen 600 und 1100
   Einheiten breit, ueber die Hoehe gefuehrt stehen sie alle gleich gross da.
   max-width deckelt die langen („Marketing Automation") im 2-Spalten-Fall
   bei 320px, wo im Kartenkoerper nur 97px bleiben. */
.zerti__logo { display: block; height: 22px; width: auto; max-width: 100%; }
.zerti__stufe {
  font-size: 12px; font-weight: 700; letter-spacing: .01em;
  color: var(--muted);
}
@media (max-width: 1024px) { .zerti-wand { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 767px)  { .zerti-wand { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } }

/* ---------- 57a. Textvorlage (/zoho-premium-partner-deutschland/, Slot 7) ----------
   Die englische E-Mail an den Zoho-Support steht zum Abtippen oder Kopieren
   da, ihre Zeilenumbrueche tragen Bedeutung (Anrede, Aufzaehlung, Gruss).
   Deshalb pre-wrap und nicht <p>: der Umbruch aus der Quelle bleibt, der
   Text bricht bei schmalem Fenster trotzdem um. Kein <pre> mit Monospace —
   das ist ein Brieftext, kein Quelltext. */
.vorlage {
  white-space: pre-wrap;
  max-width: none;
  margin: 0;
  padding: var(--space-5);
  background: var(--surface-2);
  border-left: 3px solid var(--orange);
  border-radius: var(--radius-card);
  font-size: var(--text-small); line-height: 1.7; color: var(--ink);
}
.vorlage mark { background: rgba(255, 148, 10, .28); color: inherit; padding: 0 3px; border-radius: 3px; }

/* ---------- 58. Zoho-Einbettungen (Bookings, Forms) ----------
   Fertige Zoho-Module, die in einem Iframe auf der Seite stehen: der
   Buchungskalender auf /erstgespraech/ und /termin-zoho-foerder-moeglichkeiten/,
   der Foerdermittel-Check auf /foerderung/.

   Warum ein eigener Rahmen und nicht .card: Das Modul bringt sein eigenes
   Weiss und seine eigenen Innenabstaende mit. Eine Karte darum haette
   doppelte Polsterung und zwei Radien ineinander. Hier steht deshalb nur
   der Radius plus eine haarfeine Kante, damit das fremde Weiss auf hellem
   Untergrund nicht ausfranst.

   Die Hoehe setzt das Skript (data-zoho-hoehe) und bei Zoho Forms danach
   dessen eigene postMessage-Meldung. min-height haelt den Platz, damit beim
   Nachladen nichts springt — CLS ist sonst sofort sichtbar, das Modul ist
   das groesste Element der Seite. */
.zoho-embed {
  position: relative;
  min-height: 620px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: #fff;
}
.zoho-embed iframe { display: block; width: 100%; border: 0; }

/* Hinweis, solange das Modul laedt oder wenn es blockiert wird. Er liegt
   HINTER dem Iframe (z-index 0 gegen 1) und verschwindet damit von selbst,
   sobald etwas geladen ist — ohne JavaScript, das ihn wegnehmen muesste. */
.zoho-embed__warten {
  position: absolute; inset: 0; z-index: 0;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
  text-align: center; color: var(--muted); font-size: var(--text-small);
}
/* Eigenes Weiss auf dem Iframe, nicht nur auf dem Kasten: Zoho Forms
   liefert einen durchsichtigen Hintergrund, und der Wartehinweis darunter
   schien durch das geladene Formular hindurch. Am 27.09.2026 gesehen. */
.zoho-embed iframe { position: relative; z-index: 1; background: #fff; }

@media (max-width: 767px) { .zoho-embed { min-height: 520px; } }

/* ---------- 59. Satz-Tabelle (/credit-pakete/) ----------
   Die erste und bisher einzige echte Tabelle im Projekt. Begruendung, damit
   niemand sie spaeter in Karten umbaut: Es sind fuenf Zeilen mit drei Spalten
   gleicher Art, und der Leser vergleicht genau eine davon (die Credits). Ein
   Kartenraster stellt die Werte nebeneinander statt untereinander und macht
   genau diesen Vergleich schwerer. <table> ist hier auch semantisch richtig.

   Bei 767px bricht sie in Bloecke um: drei Spalten passen auf 320px nicht,
   und horizontales Scrollen innerhalb der Seite ist keine Loesung. Die
   Spaltenueberschriften stehen dann vor dem Wert (::before mit data-label). */
.satz-tabelle {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  border-collapse: collapse;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
}
.satz-tabelle th, .satz-tabelle td {
  padding: 16px 20px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.satz-tabelle thead th {
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--muted);
  background: var(--surface-2);
  white-space: nowrap;
}
.satz-tabelle tbody th { font-weight: 700; color: var(--navy); }
.satz-tabelle tbody td:first-of-type { white-space: nowrap; color: var(--navy); }
.satz-tabelle tr:last-child th, .satz-tabelle tr:last-child td { border-bottom: 0; }

@media (max-width: 767px) {
  .satz-tabelle thead { display: none; }
  .satz-tabelle, .satz-tabelle tbody, .satz-tabelle tr, .satz-tabelle th, .satz-tabelle td { display: block; }
  .satz-tabelle tr { padding: 18px 20px; border-bottom: 1px solid var(--line); }
  .satz-tabelle tr:last-child { border-bottom: 0; }
  .satz-tabelle th, .satz-tabelle td { padding: 0; border: 0; }
  .satz-tabelle tbody th { margin-bottom: 4px; }
  .satz-tabelle tbody td:first-of-type { margin-bottom: 6px; }
}

/* Agenda der Veranstaltungsseiten (/icos-zoho-days/, /icos-umsetzungs-tage/, seit 08.10.2026): nur Zeit und
   Programm. Die erste Datenzelle ist hier der lange Programmtext und muss umbrechen, sonst schiebt sie die Tabelle
   über den Rand (gemessen 08.10.2026: 2.076px bei 1.280px Fenster). Die Uhrzeit bleibt so schmal wie nötig. */
.satz-tabelle--agenda tbody td:first-of-type { white-space: normal; color: var(--ink); }
.satz-tabelle--agenda tbody th { width: 1%; white-space: nowrap; }
@media (max-width: 767px) { .satz-tabelle--agenda tbody th { width: auto; } }

/* ---------- 60. Videokarte im Hero ----------
   Die Videokarte war fuer Kartenraster gebaut, die in einer .vp-section
   liegen — und nur diese Sektion schneidet das Cursorlicht ab, das seitlich
   170px ueber die Karte hinausragt (Begruendung in Abschnitt 41b).

   Im Hero von /workshops-seminare/ gibt es diese Sektion nicht. Ergebnis war
   ein Seitenueberlauf von 40px bei 1440px, gemessen am 27.09.2026 — unsichtbar
   im Layout, aber die Seite liess sich waagerecht schieben.

   Statt den Hero zu beschneiden (was Belegleiste und Ueberschrift mit
   erwischen wuerde) faellt hier das Licht weg. Am Seitenanfang, auf weissem
   Grund und ohne Nachbarkarten traegt es ohnehin kaum: Der Effekt lebt davon,
   dass das Licht zwischen mehreren Karten hervortritt. */
.hero .vp--karte::before { display: none; }

/* ---------- 61. Feldpaar im Kontaktbildschirm ----------
   Vorname und Nachname stehen nebeneinander. Sie sind kurz, und untereinander
   macht der Bildschirm einen langen Schlauch — bei einer Strecke, die sich auf
   drei Fragen beschraenkt, faellt das auf.

   Bei 767px zurueck auf eine Spalte: zwei Felder nebeneinander sind auf 320px
   je rund 130px breit, und darin steht ein Nachname nicht mehr lesbar.

   minmax(0, 1fr) wie ueberall — mit 1fr waechst die Spalte am laengsten Wort
   der Beschriftung aus dem Kasten. */
.feld-paar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 767px) { .feld-paar { grid-template-columns: minmax(0, 1fr); } }

/* ---------- 62. Sendebestaetigung im Danke-Bildschirm ----------
   Ein schmaler gruener Streifen ueber dem Dank, mit Haken: "wurde erfolgreich
   versendet". Wunsch des Auftraggebers vom 27.09.2026.

   Die Formulierung ist mit Bedacht VERSENDET und nicht ANGEKOMMEN. Der POST
   laeuft mit mode: "no-cors", der Antwortstatus ist fuer den Browser nicht
   lesbar (Begruendung in main.js). Abgeschickt wissen wir, angenommen nicht —
   und der Streifen behauptet genau so viel, wie wir belegen koennen.

   Eigenes Element statt Einfaerben des vorhandenen Danke-Blocks: Der Dank ist
   Zuwendung ("wir melden uns"), die Bestaetigung ist eine Quittung. Zwei
   verschiedene Aussagen, die auch verschieden aussehen duerfen.

   Kein role="alert": Der Bildschirm wechselt ohnehin, und die Ueberschrift
   bekommt den Fokus — eine zusaetzliche Ansage wuerde sie unterbrechen. */
.funnel__gesendet {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  max-width: 560px;
  margin: 0 auto 22px;
  padding: 12px 18px;
  background: #E7F4EC;
  border: 1px solid rgba(30, 142, 87, .28);
  border-radius: var(--radius-card);
  color: #14663E;            /* dunkler als --success: auf hellgruen lesbar */
  font-size: var(--text-small);
  font-weight: 600;
  line-height: 1.45;
  text-align: left;
}
.funnel__gesendet svg {
  flex: none;
  width: 20px; height: 20px;
  fill: none;
  stroke: var(--success);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 767px) {
  .funnel__gesendet { padding: 11px 14px; gap: 9px; }
}

/* ---------- 63. Brotkrumen ----------
   Sichtbarer Pfad über der H1: Start › Bereich › Seite. Seit 04.10.2026,
   zuerst auf /zoho-crm/ als Muster (SEO-Leitfaden, docs/seo-geo-leitfaden.md,
   Abschnitt 2). Der Pfad folgt dem Hauptmenü, nicht der URL: Zoho und KI sind
   getrennte Bereiche, also „Start › Zoho › Zoho CRM“ (Entscheidung 04.10.2026).

   Geschrieben wird er nicht von Hand, sondern von scripts/sync-brotkrumen.py
   aus dem BreadcrumbList-Schema derselben Seite. So können sichtbarer Pfad
   und Schema nie auseinanderlaufen.

   Bewusst klein und gedämpft: Orientierung, keine zweite Navigation. Die
   letzte Ebene ist die aktuelle Seite und deshalb kein Link
   (aria-current="page"). max-width: none, weil ol global auf 66ch gedeckelt
   ist (Abschnitt 2). */
.brotkrumen { margin: 0 0 var(--space-4); }
.brotkrumen ol {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
  font-size: var(--text-small);
  line-height: 1.5;
  color: var(--muted);
}
.brotkrumen li { display: inline-flex; align-items: center; }
.brotkrumen li + li::before { content: "›"; margin: 0 var(--space-2); color: var(--muted-soft); }
.brotkrumen a { color: var(--muted); text-decoration: none; }
.brotkrumen a:hover,
.brotkrumen a:focus-visible { color: var(--navy); text-decoration: underline; }
.brotkrumen [aria-current="page"] { color: var(--navy); font-weight: 600; }

/* ---------- 64. Landingpage „So verkauft man heute“ (seit 05.10.2026) ----------
   Zwei Bauteile, die es auf der übrigen Website nicht gibt: die Eckdaten des
   Termins im Hero und die Kette der neun Stufen mit der Stelle, an der sie
   reißt. Beide nur aus Tokens, beide nur auf /so-verkauft-man-heute/. */
.eckdaten dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px 18px; margin: 0 0 22px; font-size: 15px; }
.eckdaten dt { color: var(--muted); }
.eckdaten dd { margin: 0; font-weight: 600; color: var(--ink); }
.eckdaten .microcopy { display: block; text-align: center; margin-top: 12px; }
/* Terminliste im Kasten: vergangene Termine blendet main.js aus (data-termin-ende). */
/* Rahmen der Leistungsseiten (Briefing Leistungsstruktur, 08.10.2026): links stehen lange Begriffe wie
   „Business- & KI-Begleitung“, die Spalte „auto“ drückte den Wert bei 320px auf zwei Zeichen. Unter 767px
   deshalb Begriff über Wert. */
@media (max-width: 767px) {
  .eckdaten--rahmen dl { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .eckdaten--rahmen dd { margin-bottom: 12px; }
  .eckdaten--rahmen dd:last-child { margin-bottom: 0; }
}
.eckdaten__termine { list-style: none; margin: 0; padding: 0; max-width: none; }
.eckdaten__termine li { margin: 0; }

/* Drei Bereiche nebeneinander, unter 860px untereinander. Die gerissene Stufe
   trägt Rahmen und Ziffer in --error und dazu das Wort „reißt hier“, damit die
   Aussage nicht an der Farbe allein hängt. */
.kette { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; }
.kette__bereich { padding: 22px; border-right: 1px solid var(--line); }
.kette__bereich:last-child { border-right: 0; }
.kette__bereich h3 { font-size: 14px; letter-spacing: .04em; text-transform: uppercase; color: var(--orange-text); margin: 0 0 14px; }
.kette__glieder { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; max-width: none; }
.kette__glieder li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0; padding: 9px 12px; font-size: 15px; background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: 10px; }
.kette__nr { flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; font-size: 12px; font-weight: 700; color: var(--navy); background: var(--navy-soft); font-variant-numeric: tabular-nums; }
.kette__glieder li.is-riss { border: 2px solid var(--error); background: var(--paper); }
.kette__glieder li.is-riss .kette__nr { color: #fff; background: var(--error); }
.kette__riss { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--error); }
@media (max-width: 860px) {
  .kette { grid-template-columns: minmax(0, 1fr); }
  .kette__bereich { border-right: 0; border-bottom: 1px solid var(--line); }
  .kette__bereich:last-child { border-bottom: 0; }
}
