/* ============================================================
   Zahnarztpraxis Kim · Design-System v2
   Quelle: design-guide.md (CI Module 3 + 5)
   v2 (2026-07-06): Skala nach oben geöffnet, Bogen-Motiv
   (abgeleitet aus dem Zahnbogen im Logo), editoriale Layouts.
   Bewusste Abweichungen vom Guide v1: größere Display-Typo,
   Ghost-Ziffern, Marquee — bei Gefallen Guide nachziehen.
   ============================================================ */

:root {
  /* Farben */
  --color-bg: #F6F6F6;            /* Verkehrsweiß */
  --color-surface: #FFFFFF;
  --color-panel: #CBC4BC;         /* Beige */
  --color-panel-soft: #D8D3CD;    /* Beige 90% */
  --color-panel-softer: #ECE9E5;  /* Beige-Hauch */
  --color-text: #4B4F54;          /* Graphite */
  --color-text-soft: #6E7277;
  --color-accent: #004860;        /* Dark Teal */
  --color-accent-deep: #00374B;
  --color-accent-80: #33607F;
  --color-on-accent: #FFFFFF;
  --color-line: rgba(75, 79, 84, 0.16);
  --color-line-soft: rgba(75, 79, 84, 0.09);

  /* Typografie */
  --font-heading: 'Poppins', 'Segoe UI', sans-serif;
  --font-body: 'Quicksand', 'Segoe UI', sans-serif;
  --font-callout: 'Playfair Display', Georgia, serif;
  --text-display: clamp(2.7rem, 6.2vw, 5.2rem);        /* Hero Start */
  --text-h1: clamp(2.4rem, 4.5vw, 3.4rem);             /* Unterseiten */
  --text-h2: clamp(1.9rem, 3.2vw, 2.6rem);
  --text-h3: clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);
  --text-body: 1.0625rem;
  --text-lead: 1.1875rem;
  --text-caption: 0.875rem;
  --text-legal: 0.75rem;
  --leading-body: 1.7;

  /* Abstände (8-Point-Grid) */
  --space-xs: 16px;
  --space-s: 24px;
  --space-m: 32px;
  --space-l: 48px;
  --space-xl: 72px;
  --space-xxl: clamp(88px, 12vw, 160px);

  /* Layout */
  --container-max: 1240px;
  --container-narrow: 780px;
  --gutter: clamp(20px, 4vw, 32px);
  --radius: 2px;
  --radius-arch: 320px;           /* Bogen-Motiv aus dem Logo-Zahnbogen */
  --header-h: 80px;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.44, 1);
}

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

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: 500;
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Feines Korn — nimmt digitalen Flächen die Sterilität */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 999;
  pointer-events: none;
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

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

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--color-accent);
  line-height: 1.15;
  margin: 0 0 var(--space-s);
  text-wrap: balance;
  letter-spacing: -0.015em;
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); line-height: 1.35; letter-spacing: 0; }

p { margin: 0 0 1em; max-width: 66ch; }
p:last-child { margin-bottom: 0; }

a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; transition: color 0.2s; }
a:hover { color: var(--color-accent-80); }

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

/* Anker-Ziele landen nie unter dem Sticky-Header */
[id] { scroll-margin-top: calc(var(--header-h) + 24px); }

ul { padding-left: 1.2em; }
li { margin-bottom: 0.45em; }

.container { max-width: var(--container-max); margin-inline: auto; padding-inline: var(--gutter); }
.container-narrow { max-width: var(--container-narrow); margin-inline: auto; padding-inline: var(--gutter); }

.lead { font-size: var(--text-lead); max-width: 60ch; }

/* Bewusst KEINE Haarlinie + Versalien-Tracking mehr (bis 2026-08-19) — genau
   diese Kombination ist die generische "Eyebrow/Kicker"-Konvention, an der
   KI-generierte Marketingseiten sofort erkennbar sind (Daniel, 2026-08-19:
   Funktion behalten, Optik von der Konvention lösen). Die Ziffer (`.eyebrow-num`,
   Ghost-Outline in `--font-heading`) ist site-eigenes Material und bleibt der
   fuehrende visuelle Anker — sie traegt nun mehr Gewicht (1.3em → 1.6em),
   damit sie den Wegfall der Linie ausgleicht. Reiner Text-Eyebrow ohne Ziffer
   (z. B. "Ihr naechster Schritt") traegt seine Rolle jetzt allein ueber
   Farbe/Gewicht, keine zusaetzliche Formensprache noetig. */
.eyebrow {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-accent-80);
  margin-bottom: var(--space-s);
}

.section { padding-block: var(--space-xxl); }
.section-tight { padding-block: var(--space-xl); }

/* Serif-Akzent in Headlines (Playfair, max. 1 Einsatz pro Seite) */
h1 em, .statement-line em, .situations-close em {
  font-family: var(--font-callout);
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
}

/* ---------- Buttons ---------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1;
  padding: 19px 34px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  transition: color 0.3s, border-color 0.3s, background-color 0.3s, box-shadow 0.3s, transform 160ms var(--ease-out);
}
.btn::after { content: "→"; transition: transform 0.3s var(--ease-spring); }
.btn:hover::after { transform: translateX(5px); }
/* Externer Link (verlaesst die Seite, z.B. Doctolib): das "↗" im Text ist
   schon das Verlassen-Zeichen — der automatische "→"-Pfeil waere ein
   zweiter, widerspruechlicher Pfeil direkt daneben. */
.btn-external::after { content: none; }
.btn:active { transform: scale(0.97); }

.btn-primary { background: var(--color-accent); color: var(--color-on-accent); }
.btn-primary:hover { background: var(--color-accent-deep); color: var(--color-on-accent); box-shadow: 0 16px 32px -16px rgba(0, 55, 75, 0.5); }

.btn-inverse { background: var(--color-on-accent); color: var(--color-accent); }
.btn-inverse:hover { background: var(--color-bg); color: var(--color-accent-deep); }

.btn-ghost { background: transparent; color: var(--color-accent); border-color: rgba(0, 72, 96, 0.4); }
.btn-ghost:hover { border-color: var(--color-accent); background: rgba(0, 72, 96, 0.05); }

.arrow-link {
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 3px;
}
.arrow-link::after { content: "→"; display: inline-block; margin-left: 6px; transition: transform 0.3s var(--ease-spring); }
.arrow-link:hover::after { transform: translateX(5px); }

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(246, 246, 246, 0.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-line-soft);
}

.header-inner { display: flex; align-items: center; gap: var(--space-s); min-height: var(--header-h); }

.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.brand img { width: 50px; height: 50px; }
.brand-name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--color-accent);
  white-space: nowrap;
}

.site-nav { display: flex; gap: clamp(16px, 2.5vw, 40px); margin-inline: auto; }
.site-nav a {
  position: relative;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--color-text);
  text-decoration: none;
  padding: 6px 2px;
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: 2px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--ease-out);
}
.site-nav a:hover { color: var(--color-accent); }
.site-nav a:hover::after, .site-nav a[aria-current="page"]::after { transform: scaleX(1); }
.site-nav a[aria-current="page"] { color: var(--color-accent); }

.header-actions { display: flex; align-items: center; gap: var(--space-xs); margin-left: auto; }
.header-phone { font-weight: 600; font-size: 0.95rem; text-decoration: none; color: var(--color-text); white-space: nowrap; }
.header-phone:hover { color: var(--color-accent); }
.header-actions .btn { padding: 13px 22px; font-size: 0.95rem; white-space: nowrap; }
.lang-switch { font-size: var(--text-caption); font-weight: 600; color: var(--color-text-soft); text-decoration: none; letter-spacing: 0.06em; }

.nav-toggle { display: none; background: none; border: none; padding: 10px; cursor: pointer; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--color-accent); margin: 5px 0; transition: transform 0.3s var(--ease-out), opacity 0.2s; }
.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 900px) {
  :root { --header-h: 64px; } /* mobiler Sticky-Stack (Header + Kapitel-Nav) frisst sonst ~20 % Viewport */
  .brand img { width: 40px; height: 40px; }
  .header-phone, .lang-switch { display: none; }
  .nav-toggle { display: block; }
  .site-nav {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    gap: 0;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-line);
    padding: var(--space-xs) var(--gutter) var(--space-s);
  }
  .nav-open .site-nav { display: flex; }
  .site-nav a { padding: 14px 4px; border-bottom: 1px solid var(--color-line-soft); }
  .site-nav a::after { display: none; }
}
@media (max-width: 560px) {
  .brand-name { display: none; }
  /* Touch-Ziel [MESS] 38px hoch (F5, feinschliff-pilot 2026-08-13) — die Breite
     bleibt am Innenpolster der Shorthand, nur die Hoehe waechst auf das
     Padding-Ziel, das das Ziel ueber 44px hebt. */
  .header-actions .btn { padding: 11px 14px; padding-block: 15px; font-size: 0.88rem; }
}

/* ---------- Hero (Startseite) — editorial, hell, Bogen-Bild ---------- */

.hero {
  position: relative;
  min-height: calc(100vh - var(--header-h));
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--color-bg);
}
/* weiche Beige-Aura hinter dem Text */
.hero::before {
  content: "";
  position: absolute;
  width: 60vw; height: 60vw;
  max-width: 900px; max-height: 900px;
  border-radius: 50%;
  left: -18vw; top: -22vw;
  background: radial-gradient(circle, rgba(203, 196, 188, 0.45), transparent 65%);
  pointer-events: none;
}

.hero-inner {
  position: relative;
  display: grid;
  gap: var(--space-l);
  align-items: center;
  width: 100%;
  padding-block: var(--space-xl);
}
@media (min-width: 981px) {
  .hero-inner { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(40px, 6vw, 96px); }
}

.hero h1 {
  font-size: var(--text-display);
  line-height: 1.04;
  color: var(--color-accent);
  margin-bottom: var(--space-s);
  max-width: none;
}
/* Basis-Fassung des Komponenten-Selektors — `.hero` existiert aktuell nur auf
   `index.html`, wo `.page-home .hero h1 .rotator` (weiter unten) wegen
   hoeherer Spezifitaet immer gewinnt. Trotzdem auf denselben Stand gebracht
   (2026-08-19, Playfair-Akzent-Fix), damit diese Basis nicht die alte
   zurueckgezogene Farbe/das alte Gewicht traegt, falls `.hero` je ohne
   `.page-home` wiederverwendet wird. */
.hero h1 .rotator {
  font-family: var(--font-callout);
  font-style: italic;
  font-weight: 600;
  color: var(--color-accent-deep);
  white-space: nowrap;
}
.hero h1 .h1-static { color: var(--color-text); font-size: 0.5em; display: block; margin-top: 0.35em; font-family: var(--font-body); font-weight: 500; letter-spacing: 0; }

.rotator { display: inline-block; transition: opacity 0.55s ease, transform 0.55s var(--ease-out); }
.rotator.is-fading { opacity: 0; transform: translateY(10px); }

/* Nutzen-Subline vor dem Claim (Hero-Stratege-Review 2026-07-07, umgesetzt 2026-08-18) —
   übersetzt den Marken-Claim in ein konkretes Versprechen; der Claim rückt darunter
   als leisere Signatur, verliert aber nicht seine CI-Pflichtstelle im Hero. */
.hero-sub { font-size: var(--text-lead); font-weight: 500; color: var(--color-text); margin-bottom: var(--space-xs); }
.hero-claim { font-size: var(--text-body); font-weight: 500; color: var(--color-text-soft); margin-bottom: var(--space-m); }

.hero-cta { display: flex; align-items: center; gap: var(--space-s); flex-wrap: wrap; }
/* Touch-Ziel [MESS] 32px hoch (F5, feinschliff-pilot 2026-08-13) — Telefonnummer
   neben den CTAs ist auf dem Telefon der direkteste Weg in die Praxis. */
.hero-phone { display: inline-block; color: inherit; font-weight: 600; text-decoration: none; border-bottom: 1px solid currentColor; padding-block: 8px; }
.hero .hero-phone { color: var(--color-accent); }

/* Bogen-Bild rechts */
.hero-media { position: relative; }
.hero-media .arch-img {
  border-radius: var(--radius-arch) var(--radius-arch) var(--radius) var(--radius);
  min-height: clamp(380px, 56vh, 620px);
  box-shadow: 0 40px 80px -40px rgba(0, 55, 75, 0.45);
}
/* dünner Bogen als Echo hinter dem Bild */
.hero-media::before {
  content: "";
  position: absolute;
  inset: -22px 22px 22px -22px;
  border: 1px solid rgba(0, 72, 96, 0.25);
  border-radius: var(--radius-arch) var(--radius-arch) var(--radius) var(--radius);
  pointer-events: none;
}

.hero-badge {
  position: absolute;
  left: -28px;
  bottom: 44px;
  background: var(--color-surface);
  border: 1px solid var(--color-line-soft);
  border-radius: var(--radius);
  box-shadow: 0 24px 48px -24px rgba(0, 55, 75, 0.35);
  padding: 16px 22px;
  display: flex;
  align-items: center;
  gap: 14px;
}
.hero-badge .stars { color: var(--color-accent); font-size: 1.1rem; letter-spacing: 2px; white-space: nowrap; }
.hero-badge .stars strong { font-family: var(--font-heading); font-size: 1.5rem; margin-right: 6px; }
.hero-badge span { font-size: var(--text-caption); color: var(--color-text-soft); line-height: 1.4; }
@media (max-width: 980px) {
  .hero-media { margin-inline: 24px 0; }
  .hero-badge { left: -16px; bottom: 24px; }
}

/* ---------- Marquee — Leistungen als Laufband ---------- */

.marquee {
  overflow: hidden;
  border-block: 1px solid var(--color-line-soft);
  background: var(--color-surface);
  padding-block: 22px;
  white-space: nowrap;
}
.marquee-track {
  display: inline-flex;
  gap: 0;
  animation: marquee 46s linear infinite;
  will-change: transform;
}
.marquee-track span {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(1.8rem, 3.6vw, 3rem);
  line-height: 1.1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.55);
  padding-inline: 28px;
  flex-shrink: 0;
}
.marquee-track span::after { content: "✦"; -webkit-text-stroke: 0; color: rgba(0, 72, 96, 0.35); font-size: 0.55em; vertical-align: middle; margin-left: 56px; }
.marquee-track span.filled { color: var(--color-accent); -webkit-text-stroke: 0; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- Statement (Wofür wir stehen) ---------- */

.statement-line {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(1.7rem, 3.6vw, 2.9rem);
  line-height: 1.25;
  color: var(--color-accent);
  letter-spacing: -0.015em;
  max-width: 24ch;
  margin: 0 0 var(--space-m);
  text-wrap: balance;
}
/* Playfair-Akzent muss deutlicher hervortreten als der Umtext, nicht weniger
   (design-guide.md #1: "Akzentwort", keine Randnotiz). Bis 2026-08-19 stand
   hier `--color-accent-80` — heller/blasser als `--color-accent` der Zeile
   davor, das Akzentwort trat also zurueck statt hervor. Jetzt dunkler +
   Semibold (600 Italic, eigens ueber den Google-Fonts-Link nachgeladen) statt
   Regular: echte Betonung durch Gewicht UND Farbe. Daniel, 2026-08-19: erst
   Graphite getestet (wirkte in den dunklen .outcome-Sektionen schlechter als
   das bestehende Beige), danach diese Fassung bestaetigt ("klingt gut"). */
.statement-line em { color: var(--color-accent-deep); font-weight: 600; }

/* ---------- Karten ---------- */

.card-grid { display: grid; gap: var(--space-s); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
/* Vergleichsraster mit genau zwei Kacheln: Breite an die Drei-/Vierer-Raster
   der Nachbarseiten angleichen statt auf volle 2-Spalten-Breite zu strecken,
   und zentrieren statt linksbündig mit einer leeren dritten Spalte zu stehen
   (Daniel, 2026-08-18: Zahnersatz-Kacheln zu breit, Schienentherapie-Kacheln
   unzentriert — dieselbe Ursache, eine Regel für beide). */
.section-ways .card-grid:has(> .card-static:nth-child(2):last-child) {
  grid-template-columns: repeat(2, minmax(0, 370px));
  justify-content: center;
}
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* versetzte Anordnung — bricht das gelernte Raster */
@media (min-width: 901px) {
  .card-grid.stagger > :nth-child(even) { margin-top: var(--space-l); }
}

.card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-line-soft);
  border-radius: var(--radius);
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform 0.45s var(--ease-out), border-color 0.45s, box-shadow 0.45s, background-color 0.45s;
}
.card:hover {
  transform: translateY(-6px);
  border-color: rgba(0, 72, 96, 0.35);
  box-shadow: 0 24px 48px -28px rgba(0, 55, 75, 0.4);
}
.card h3 { margin-bottom: 4px; transition: color 0.45s; }
.card p { font-size: 0.98rem; transition: color 0.45s; }
.card .arrow-link { margin-top: auto; font-size: 0.95rem; align-self: flex-start; transition: color 0.45s; }

/* Index-Ziffer in der Kartenecke */
.card[data-num]::before {
  content: attr(data-num);
  position: absolute;
  top: 18px; right: 22px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 2.4rem;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.28);
  transition: -webkit-text-stroke-color 0.45s, color 0.45s;
  pointer-events: none;
}

/* Dark-Flip beim Hover (Leistungsgruppen Start).
   transform: none ist hier eigens gesetzt, nicht nur Erbe von .card:hover.
   Auf der Startseite kam die Lift-Unterdrueckung bisher zufaellig aus der
   Reveal-Stagger-Regel (Zeile 914, `html.js .reveal-stagger.is-visible > *`,
   die per Spezifitaet ueber .card:hover gewinnt) — sobald .card-flip aber
   OHNE .reveal-stagger steht (z. B. Angebots-Kacheln auf Detailseiten ohne
   fuenften Reveal-Moment, R8), greift nichts mehr und die Karte hebt sich
   beim Hover an. Daniel, 2026-08-17, an genau diesem Fall entdeckt: nur
   Farbflaeche und Icon sollen sich bewegen, kein Lift. */
.card-flip:hover { transform: none; }
.card-flip:hover { background: var(--color-accent); border-color: var(--color-accent); }
.card-flip:hover h3, .card-flip:hover p { color: #fff; }
.card-flip:hover .card-links a, .card-flip:hover .arrow-link { color: #fff; }
.card-flip:hover .card-icon { border-color: rgba(255, 255, 255, 0.5); color: #fff; }
.card-flip:hover[data-num]::before { -webkit-text-stroke-color: rgba(255, 255, 255, 0.4); }

/* Wieder voller Kreis (Ruecknahme 2026-08-19, selber Tag wie der Bogen-Versuch
   darueber). Der Bogen-Versuch (Bogen-Form statt Kreis, Radius identisch zu
   `.arch-img`) stand kurz und war freigegeben — Daniel nach erneutem Ansehen:
   die Kreisform wirkt hier stimmiger. Funktion/Groesse unveraendert, nur die
   Form zurueckgesetzt. Kein Widerspruch zur E9-Entscheidung (Kreisbogen bleibt
   Signatur-Motiv fuer die grossen Bilder) — hier ist es umgekehrt: der Kreis
   ist fuer dieses kleine, symmetrische Icon-Format schlicht die passendere
   Form, nicht jede Flaeche muss den Bogen tragen. */
.card-icon {
  width: 52px; height: 52px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(0, 72, 96, 0.25);
  border-radius: 50%;
  color: var(--color-accent);
  margin-bottom: 8px;
  transition: border-color 0.45s, color 0.45s;
}
.card-icon svg { width: 24px; height: 24px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }

.card-links { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: var(--text-caption); }
.card-links a { font-weight: 600; transition: color 0.45s; }

/* ---------- Journey — „So läuft Ihr erster Besuch ab" (Start, dunkel) ---------- */

.journey {
  background:
    radial-gradient(1000px 500px at 85% 8%, rgba(203, 196, 188, 0.10), transparent 60%),
    linear-gradient(160deg, #0B4C63 0%, #004860 50%, #00303F 100%);
  color: rgba(255, 255, 255, 0.88);
  padding-block: var(--space-xxl);
}
.journey-grid { display: grid; gap: var(--space-xl); }
@media (min-width: 981px) {
  .journey-grid { grid-template-columns: 5fr 7fr; gap: clamp(48px, 7vw, 120px); }
  .journey-intro { position: sticky; top: calc(var(--header-h) + 48px); align-self: start; }
}
.journey h2 { color: #fff; font-size: clamp(2.1rem, 3.8vw, 3.1rem); }
.journey-intro p { color: rgba(255, 255, 255, 0.75); }
.journey .eyebrow { color: rgba(255, 255, 255, 0.65); }

.journey-steps { list-style: none; margin: 0; padding: 0; counter-reset: jstep; }
.journey-steps li {
  counter-increment: jstep;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(20px, 3vw, 44px);
  align-items: start;
  padding-block: clamp(28px, 4vw, 44px);
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  margin: 0;
}
.journey-steps li:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.16); }
.journey-steps li::before {
  content: "0" counter(jstep);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(2.6rem, 5vw, 4.2rem);
  line-height: 0.9;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, 0.35);
  transition: color 0.4s, -webkit-text-stroke-color 0.4s;
}
.journey-steps li:hover::before { color: #fff; -webkit-text-stroke-color: #fff; }
.journey-steps h3 { color: #fff; font-size: 1.35rem; margin-bottom: 8px; }
.journey-steps p { color: rgba(255, 255, 255, 0.72); font-size: 1rem; margin: 0; max-width: 52ch; }
.journey .btn { margin-top: var(--space-m); }

/* ---------- Prozess-Panel (Unterseiten, Beige — großzügig) ---------- */

.process-panel {
  background: var(--color-panel-soft);
  border-radius: var(--radius);
  padding: clamp(40px, 6vw, 72px) clamp(24px, 5vw, 64px);
}
.process-panel h2 { font-size: clamp(1.8rem, 3vw, 2.4rem); }
/* Einleitungszeile ueber den Schritten (R2-A/R4/R5, feinschliff-pilot
   2026-08-13). Bewusst `> h2 + p`, nicht `> p`: der breitere Selektor griff
   auch auf eine zwischenzeitliche `.process-note` am Panelfuss und machte sie
   optisch so laut wie die Einleitung — im Rollout tragen mehrere Detailseiten
   (Aligner, Prophylaxe, Wurzelbehandlung) diese Note zusaetzlich, `> p` wuerde
   sie dort mit einfangen. */
.process-panel > h2 + p {
  font-size: var(--text-lead);
  max-width: none;
  color: var(--color-text);
  text-wrap: balance;
}

.process-steps {
  display: grid;
  gap: var(--space-l) var(--space-m);
  counter-reset: step;
  margin-top: var(--space-l);
  padding: 0;
  list-style: none;
}
@media (min-width: 901px) {
  .process-steps { grid-template-columns: repeat(var(--steps, 5), 1fr); }
  /* R2-A, feinschliff-pilot 2026-08-13: [MESS] Titelhoehen 90/90/90/120/60px,
     die Beschreibungen begannen dadurch auf drei verschiedenen Hoehen.
     subgrid legt alle Titel in dieselbe Zeile und alle Beschreibungen in die
     naechste — die Zeile ist so hoch wie der laengste Titel, ohne feste
     Hoehen, die bei anderem Text wieder brechen wuerden. */
  .process-steps {
    grid-template-rows: auto auto;
    row-gap: 0;
  }
  .process-steps li {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 2;
    row-gap: 0;
  }
}

.process-steps li { position: relative; counter-increment: step; margin: 0; padding-top: 18px; }
.process-steps li::before {
  content: "0" counter(step);
  position: absolute;
  top: -14px;
  left: -4px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(3rem, 4.5vw, 4rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.35);
  pointer-events: none;
}
.process-steps li > * { position: relative; }

@media (min-width: 901px) {
  /* Der Bindestrich klebte an der FOLGENDEN Ziffer und las sich als deren
     Vorzeichen ("-02") statt als Verbindung (R2-A, feinschliff-pilot
     2026-08-13). [MESS] Ziffer ~70px breit, beginnt bei -4px, die naechste
     28px hinter der Spaltenkante — die Mitte der Luecke liegt bei halber
     Spaltenbreite plus 47px, als Prozentwert statt festem Pixelwert, damit
     es mit der Spalte mitwaechst. */
  .process-steps li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 20px;
    left: calc(50% + 39px);
    right: auto;
    width: 16px;
    height: 1px;
    background: rgba(0, 72, 96, 0.3);
  }
}
@media (max-width: 900px) {
  .process-steps { gap: var(--space-l); }
  .process-steps li { padding-top: 8px; padding-left: 84px; min-height: 64px; }
  .process-steps li::before { top: 0; left: 0; font-size: 2.6rem; }
}

.process-steps h3, .process-steps strong {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--color-accent);
  margin-bottom: 8px;
  padding-top: 30px;
}
@media (max-width: 900px) { .process-steps h3, .process-steps strong { padding-top: 0; } }
.process-steps p { font-size: 0.96rem; margin: 0; }
.process-note { margin-top: var(--space-m); font-size: var(--text-caption); color: var(--color-text-soft); }

/* ---------- Showcase — Full-Bleed mit Statement-Karte ---------- */

.showcase { position: relative; }
.showcase-img {
  min-height: clamp(360px, 68vh, 640px);
  border-radius: 0;
  will-change: background-position;
}
.stat-card {
  position: relative;
  background: var(--color-surface);
  border-radius: var(--radius);
  box-shadow: 0 32px 64px -32px rgba(0, 55, 75, 0.45);
  padding: clamp(28px, 4vw, 44px);
  max-width: 460px;
  margin: -72px var(--gutter) 0 auto;
  border-top: 3px solid var(--color-accent);
}
@media (min-width: 981px) { .stat-card { position: absolute; right: 6vw; bottom: -64px; margin: 0; } }
.stat-big {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(3rem, 5vw, 4.2rem);
  line-height: 1;
  color: var(--color-accent);
  margin-bottom: 10px;
}
.stat-card p { font-size: 0.98rem; margin: 0; }
.showcase-spacer { height: 96px; }
@media (max-width: 980px) { .showcase-spacer { height: var(--space-l); } }

/* ---------- Zitatband ---------- */

.quote-band {
  position: relative;
  background: var(--color-panel-softer);
  padding-block: var(--space-xxl);
  text-align: center;
  overflow: hidden;
}
.quote-band::before {
  content: "„";
  position: absolute;
  top: -0.18em;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-callout);
  font-size: clamp(16rem, 30vw, 26rem);
  line-height: 1;
  color: rgba(0, 72, 96, 0.07);
  pointer-events: none;
}
.quote-band blockquote {
  position: relative;
  margin: 0 auto;
  max-width: 26ch;
  font-family: var(--font-callout);
  font-style: italic;
  font-size: clamp(1.6rem, 3.4vw, 2.6rem);
  line-height: 1.45;
  color: var(--color-accent);
}
.quote-band figcaption { position: relative; margin-top: var(--space-m); font-size: var(--text-caption); color: var(--color-text-soft); }

/* ---------- CTA-Band ---------- */
/* Randnotiz (gefunden 2026-08-21, nicht behoben): `<section class="cta-band
   section-tight">` traegt auf allen 14 Leistungsseiten UND jetzt auf
   karriere-zfa.html `.section-tight`, aber padding-block hier unten
   (Zeile 761+, --space-xxl) steht spaeter im Stylesheet als `.section-tight`
   selbst (Zeile 148, --space-xl) — bei gleicher Spezifitaet gewinnt die
   spaetere Regel im Cascade. `.section-tight` ist auf `.cta-band` also
   optisch wirkungslos, das Band nutzt real durchgehend --space-xxl. Kein
   sichtbarer Fehler (die Bands sind seit dem Rollout so abgenommen), nur ein
   irrefuehrender Klassenname — absichtlich nicht angefasst, betrifft alle
   14 Seiten gleich. */
.cta-band {
  position: relative;
  background: linear-gradient(150deg, #0B4C63 0%, #004860 55%, #00303F 100%);
  color: var(--color-on-accent);
  text-align: center;
  padding-block: var(--space-xxl);
  overflow: hidden;
}
/* Bogen-Echo als Dekor */
.cta-band::before, .cta-band::after {
  content: "";
  position: absolute;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 50%;
  pointer-events: none;
}
.cta-band::before { width: 560px; height: 560px; right: -180px; top: -280px; }
.cta-band::after { width: 380px; height: 380px; left: -140px; bottom: -220px; }
.cta-band h2 { color: var(--color-on-accent); font-size: clamp(2rem, 4.4vw, 3.4rem); max-width: 22ch; margin-inline: auto; }
.cta-band p { margin-inline: auto; color: rgba(255, 255, 255, 0.85); }
.cta-band .hero-cta { justify-content: center; margin-top: var(--space-m); }
.cta-band .hero-phone { color: #fff; }
.journey .hero-phone { color: #fff; border-bottom-color: rgba(255, 255, 255, 0.5); }
.journey .journey-intro .hero-cta { margin-top: var(--space-m); }

/* ---------- Split-Layout ---------- */

.split { display: grid; gap: var(--space-l); align-items: center; }
@media (min-width: 901px) {
  .split { grid-template-columns: 1fr 1fr; gap: clamp(48px, 6vw, 96px); }
  .split-reverse > :first-child { order: 2; }
}

/* ---------- FAQ ---------- */

.faq { border-top: 1px solid var(--color-line); }
.faq details { border-bottom: 1px solid var(--color-line); }
.faq summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-xs);
  padding: 26px 4px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--color-accent);
  transition: color 0.2s;
}
.faq summary:hover { color: var(--color-accent-80); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  flex-shrink: 0;
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(0, 72, 96, 0.3);
  border-radius: 50%;
  font-size: 1.4rem;
  font-weight: 400;
  line-height: 1;
  /* 350ms mit Spring lag ueber dem UI-Budget von 150-250ms (F9, feinschliff-pilot
     2026-08-13) — das Element kommt auf 13 Detailseiten je zehnmal vor. */
  transition: transform 220ms var(--ease-out), background-color 220ms, color 220ms, border-color 220ms;
}
.faq details[open] summary::after { transform: rotate(45deg); background: var(--color-accent); color: #fff; border-color: var(--color-accent); }
.faq details > div { padding: 0 4px 26px; max-width: 66ch; }
.faq details > div p { font-size: 1rem; }

/* ---------- Footer — großer Claim, dann Spalten ---------- */

.site-footer {
  background: var(--color-accent-deep);
  color: rgba(255, 255, 255, 0.85);
  padding-block: var(--space-xl) var(--space-m);
  font-size: 0.95rem;
}
.footer-grid { display: grid; gap: var(--space-l); grid-template-columns: 1fr 1fr; margin-bottom: var(--space-l); }
.footer-grid.has-jobs { grid-template-columns: 1fr 1fr 1fr; }
.footer-grid > div:first-child { grid-column: 1 / -1; border-bottom: 1px solid rgba(255, 255, 255, 0.14); padding-bottom: var(--space-l); }
@media (max-width: 700px) { .footer-grid, .footer-grid.has-jobs { grid-template-columns: 1fr; gap: var(--space-m); } }

.site-footer img { width: 72px; height: 72px; margin-bottom: var(--space-s); }
.footer-claim {
  font-family: var(--font-callout);
  font-style: italic;
  font-size: clamp(1.8rem, 4.5vw, 3.2rem);
  line-height: 1.3;
  color: #fff;
  max-width: 18ch;
}
.footer-legacy { font-size: var(--text-legal); color: rgba(255, 255, 255, 0.5); margin-top: 12px; }

/* Fusszeilen-Ueberschriften: h4 war ein uebersprungener Ebenenwechsel im
   Dokument-Outline (F6, feinschliff-pilot 2026-08-13). Rollout jetzt auf allen
   20 Seiten abgeschlossen (Code-Audit 2026-08-18) — nur noch ein Selektor.
   font-family/font-weight/line-height stehen explizit, weil h3 andere
   Browser-Defaults als h4 hat. */
.site-footer h3 { color: #fff; font-family: var(--font-body); font-size: var(--text-caption); font-weight: 600; line-height: 1.15; letter-spacing: 0.14em; text-transform: uppercase; margin: 0 0 var(--space-xs); }
.site-footer a { color: rgba(255, 255, 255, 0.85); }
.site-footer a:hover { color: #fff; }
.site-footer address { font-style: normal; line-height: 1.9; }
.footer-hours { list-style: none; padding: 0; margin: 0; line-height: 2; }
.footer-hours li { margin: 0; }

.footer-bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding-top: var(--space-s);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-m);
  justify-content: space-between;
  font-size: var(--text-caption);
  color: rgba(255, 255, 255, 0.6);
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: var(--space-s); }
.footer-bottom a { color: rgba(255, 255, 255, 0.72); text-decoration: none; }
.footer-bottom a:hover { color: #fff; text-decoration: underline; }

/* ---------- Unterseiten-Kopf ---------- */

.page-hero { padding-block: clamp(56px, 8vw, 104px) var(--space-l); }
.page-hero h1 { font-size: var(--text-h1); }
.page-hero .subline {
  font-size: var(--text-lead);
  font-weight: 500;
  color: var(--color-accent-80);
  max-width: 52ch;
  margin-top: -6px;
}
.claim-line {
  font-family: var(--font-callout);
  font-style: italic;
  font-size: 1.25rem;
  color: var(--color-accent);
  margin-top: var(--space-s);
}

/* ---------- Bild-Platzhalter ---------- */

.ph {
  position: relative;
  border-radius: var(--radius);
  background:
    radial-gradient(600px 300px at 70% 20%, rgba(255, 255, 255, 0.35), transparent 60%),
    linear-gradient(150deg, var(--color-panel-softer) 0%, var(--color-panel-soft) 60%, var(--color-panel) 100%);
  min-height: 320px;
  overflow: hidden;
}
.ph::after {
  content: attr(data-note);
  position: absolute;
  left: 14px; bottom: 12px;
  font-size: var(--text-legal);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(75, 79, 84, 0.55);
}
.ph-tall { min-height: 460px; }
.ph-wide { min-height: clamp(300px, 48vw, 560px); }
.ph-dark {
  background:
    radial-gradient(700px 350px at 75% 15%, rgba(255, 255, 255, 0.12), transparent 60%),
    linear-gradient(150deg, #12556C 0%, #004860 55%, #00374B 100%);
}
.ph-dark::after { color: rgba(255, 255, 255, 0.5); }

.ph.is-photo { background-size: cover; background-position: center; }
.ph.is-photo::after {
  background: rgba(0, 55, 75, 0.72);
  color: rgba(255, 255, 255, 0.92);
  padding: 5px 10px;
  border-radius: var(--radius);
  left: 12px; bottom: 12px;
}

/* Bogen-Maske für Bilder (Team, Hero) */
.arch-img { border-radius: var(--radius-arch) var(--radius-arch) var(--radius) var(--radius); }

/* Team-Kacheln — kein Hebe-Effekt mehr (Daniel, 2026-08-18: "ein wenig much",
   Simplicity). Bild bleibt einfach stehen. */
.team-tile { overflow: hidden; background-size: cover; }

/* ---------- Hinweis-Boxen ----------
   .notice bewusst entfernt (2026-08-21): eine geränderte Box mit Icon-loser
   linker Akzentlinie ist genau der "brave Kasten", den design-guide.md #Teil-G
   ausschließt ("Ruhe entsteht durch Weißraum... nicht durch kleine Typografie
   und brave Kästen"). War schon einmal sitewide entfernt worden, kam über die
   Karriere-Seiten zurück (Daniel, 2026-08-21: "das gilt als KI-Indiz"). Lieber-
   erst-anrufen-Hinweise laufen jetzt als normaler Absatz im Fließtext. Klasse
   hier bewusst nicht neu anlegen, wenn wieder ein Hinweis gebraucht wird. */

.todo-note {
  display: inline-block;
  background: rgba(0, 72, 96, 0.07);
  border: 1px dashed rgba(0, 72, 96, 0.35);
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: var(--text-caption);
  color: var(--color-accent-80);
}

/* ---------- Formular ---------- */

.form-grid { display: grid; gap: var(--space-xs); max-width: 620px; }
.form-row { display: grid; gap: var(--space-xs); grid-template-columns: 1fr 1fr; }
@media (max-width: 620px) { .form-row { grid-template-columns: 1fr; } }

label { font-weight: 600; font-size: var(--text-caption); display: block; margin-bottom: 6px; color: var(--color-accent); }
input[type="text"], input[type="email"], textarea {
  width: 100%;
  font: inherit;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 14px 15px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
input:focus, textarea:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 1px var(--color-accent); }
.checkbox-row { display: flex; gap: 10px; align-items: flex-start; font-size: var(--text-caption); }
.checkbox-row input { margin-top: 3px; accent-color: var(--color-accent); }

.info-cols { display: grid; gap: var(--space-l); grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .info-cols { grid-template-columns: 1fr; gap: var(--space-m); } }
.info-cols h3 { font-size: 1.05rem; }
.info-cols address { font-style: normal; line-height: 1.8; }

/* ---------- Scroll-Reveal ----------
   Versteckt wird nur bei aktivem JS (html.js): ohne JS oder wenn
   site.js nicht lädt, ist jeder Inhalt sofort sichtbar (v3.3-Fix
   aus dem Hub-Review — betraf zuvor die ganze Website). */

/* 0.9s war lang fuer elf identische Eintritte auf einer Seite, und ein Leser
   durchlaeuft am Ende 13 solche Seiten (F3, feinschliff-pilot 2026-08-13,
   [EMIL 1+7] Frequenz und Kohaesion). Halbiert auf 0.55s, bleibt aber im
   Marketing-Rahmen. Bewusst nur die Dauer angefasst, nicht die Distanz-
   Bedeutung von opacity:0 — die bleibt vom Original. */
html.js .reveal { opacity: 0; transform: translateY(16px); transition: opacity 0.55s var(--ease-out), transform 0.55s var(--ease-out); }
html.js .reveal.is-visible { opacity: 1; transform: none; }
html.js .reveal-stagger > * { opacity: 0; transform: translateY(28px); transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out); }
html.js .reveal-stagger.is-visible > * { opacity: 1; transform: none; }
.reveal-stagger.is-visible > :nth-child(2) { transition-delay: 0.1s; }
.reveal-stagger.is-visible > :nth-child(3) { transition-delay: 0.2s; }
.reveal-stagger.is-visible > :nth-child(4) { transition-delay: 0.3s; }
.reveal-stagger.is-visible > :nth-child(5) { transition-delay: 0.4s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .reveal-stagger > * { opacity: 1; transform: none; transition: none; }
  /* .btn und .card standen frueher pauschal in derselben Zeile wie .rotator und
     .brand img (transition: none) — das kappte auch Farbe, Rahmen und Schatten,
     die keine Bewegung sind, sondern einen Zustandswechsel erst lesbar machen
     (F7, feinschliff-pilot 2026-08-13: „fewer and gentler, not zero"). Beide
     bekommen jetzt eine eigene Zeile, die nur die Bewegung stoppt. */
  .rotator, .brand img { transition: none; }
  .btn {
    transition: color 0.3s, border-color 0.3s, background-color 0.3s, box-shadow 0.3s;
    transform: none;
  }
  .btn:active { transform: none; }
  .card { transition: border-color 0.45s, box-shadow 0.45s, background-color 0.45s, color 0.45s; }
  .nextnav-item:active { transform: none; }
  .marquee-track { animation: none; }
}

/* Hover-Bewegung nur, wo es echten Hover gibt (F10, feinschliff-pilot 2026-08-13):
   die JS-Effekte waren bereits gegated, die CSS-Hover-Transforms nicht — am
   Desktop unsichtbar, auf dem Telefon blieb der Zustand nach dem Antippen kleben. */
@media (hover: none), (pointer: coarse) {
  .btn:hover::after { transform: none; }
  .nextnav-item:hover .nn-arrow { transform: none; }
  .nextnav-item:hover .nn-name { transform: none; }
}

/* ---------- Utilities ---------- */

.text-center { text-align: center; }
.mt-s { margin-top: var(--space-s); }
.mt-m { margin-top: var(--space-m); }
.mt-l { margin-top: var(--space-l); }
.mb-m { margin-bottom: var(--space-m); }
.max-narrow { max-width: var(--container-narrow); }
.small { font-size: var(--text-caption); color: var(--color-text-soft); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================
   v3 · WOW-Pass Startseite (Entwurf, 2026-07-07)
   Neue Ebene über v2: Intro-Choreografie, Scroll-Dramaturgie,
   Mikro-Interaktionen. Farben/Fonts unverändert CI-konform.
   Scoping: .page-home (body-Klasse der Startseite) und html.js
   (JS aktiv) — Unterseiten und No-JS-Fall bleiben unberührt.
   Alles Vanilla-CSS → 1:1 ins Kadence-Child-Theme übertragbar.
   ============================================================ */

/* ---------- Header: Scroll-Fortschritt als feine Teal-Linie ---------- */

.site-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--color-accent);
  transform: scaleX(var(--scroll-p, 0));
  transform-origin: left;
  pointer-events: none;
}

/* ---------- Hero: Intro-Choreografie (Zeilen-Maske) ---------- */

.hero h1 .line { display: block; overflow: hidden; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.hero h1 .line-inner { display: inline-block; }
.hero h1 .h1-static { display: block; }

/* Timing nach Team-Review gestrafft: der Termin-CTA muss bei ~0,35s
   lesbar sein — der Auftritt bleibt, die Wartezeit nicht */
html.js .page-home .hero h1 .line-inner {
  transform: translateY(118%);
  transition: transform 0.85s var(--ease-out);
}
html.js .page-home .hero h1 .line:nth-child(2) .line-inner { transition-delay: 0.09s; }
html.js .page-home .hero h1 .line:nth-child(3) .line-inner { transition-delay: 0.16s; }
html.js .page-home.is-loaded .hero h1 .line-inner { transform: none; }

html.js .page-home .hero .hero-sub,
html.js .page-home .hero .hero-claim,
html.js .page-home .hero .hero-actions {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}
html.js .page-home .hero .hero-sub { transition-delay: 0.20s; }
html.js .page-home .hero .hero-claim { transition-delay: 0.27s; }
html.js .page-home .hero .hero-actions { transition-delay: 0.34s; }
html.js .page-home.is-loaded .hero :is(.hero-sub, .hero-claim, .hero-actions) {
  opacity: 1;
  transform: none;
}

/* Copy-Ergänzungen (Daniel-Freigabe 2026-07-07) */
.cta-hint {
  margin: 10px 0 0;
  font-size: var(--text-caption);
  color: var(--color-text-soft);
}
/* Hero-Aktionsblock — CTA, Telefon, Live-Status und Hinweis gebündelt (weniger Wusel) */
.hero-actions {
  margin-top: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  align-items: flex-start;
}
.hero-actions .hero-cta { margin: 0; }
.hero-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; }
.hero-meta .open-pill { margin: 0; }
.hero-meta .cta-hint { margin: 0; }
/* Neupatienten-Hinweis wandert aus dem Hero ins Finale */
.cta-note { margin-top: var(--space-m); font-size: var(--text-caption); color: rgba(255, 255, 255, 0.8); }
.quote-followup {
  position: relative;
  max-width: 46ch;
  margin: var(--space-m) auto 0;
  padding-inline: var(--gutter);
  font-size: 1.05rem;
  color: var(--color-text);
}
/* Daniel, 2026-08-25: "Termin vereinbaren →" brach je nach Fensterbreite
   zwischen den beiden Woertern um, sollte immer in einer Zeile stehen. Der
   ganze Link bleibt ein nowrap-Block und wandert bei Platzmangel als Ganzes
   in die naechste Zeile, statt mitten im Wortpaar zu trennen. */
.quote-followup .arrow-link { white-space: nowrap; }

html.js .page-home .hero-media {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1s var(--ease-out) 0.2s, transform 1s var(--ease-out) 0.2s;
}
html.js .page-home .hero-media .arch-img {
  transform: scale(1.035);
  transition: transform 1.3s var(--ease-out) 0.2s;
}
html.js .page-home.is-loaded .hero-media { opacity: 1; transform: none; }
html.js .page-home.is-loaded .hero-media .arch-img { transform: none; }

/* Hero-Foto als echtes <img> (LCP: priorisiert ladbar, preload im head) */
.hero-photo { position: relative; }
.hero-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
@media (max-width: 620px) { .hero-media .arch-img { min-height: 300px; } }

/* Badge ist verlinkt (Google-Profil) und schwebt sanft nach dem Intro */
.hero-badge { text-decoration: none; color: inherit; }
.hero-badge:hover { color: inherit; }
.page-home .hero-badge { animation: badge-float 8s ease-in-out 2.2s infinite alternate; }
@keyframes badge-float { from { transform: translateY(0); } to { transform: translateY(-6px); } }

/* ---------- Öffnungsstatus-Pill (live per JS) ---------- */

.open-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-accent);
  background: rgba(0, 72, 96, 0.06);
  border: 1px solid rgba(0, 72, 96, 0.16);
  border-radius: 999px;
  padding: 8px 16px;
  margin: var(--space-m) 0 0;
}
.open-pill[hidden] { display: none; }
.open-pill .pill-dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--color-accent); flex-shrink: 0; }
.open-pill .pill-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid rgba(0, 72, 96, 0.4);
  animation: pill-pulse 2.4s ease-out infinite;
}
@keyframes pill-pulse {
  0% { transform: scale(0.6); opacity: 1; }
  70%, 100% { transform: scale(1.5); opacity: 0; }
}
/* Punkt nur im geschlossenen Zustand — offen braucht die Pille + der Text
   kein zusaetzliches Signal, und auf dem dunklen Hero-Grund (Startseite,
   Praxis) war der teal-auf-teal-Punkt kaum zu erkennen (Daniel, 2026-08-18). */
.open-pill:not(.is-closed) .pill-dot { display: none; }
/* Geschlossen: Ghost-Pille statt Vollton — der Zustand ist eine Nebeninfo
   (naechste Oeffnungszeit), keine, die dieselbe optische Wucht wie "jetzt
   geoeffnet" verdient. */
.open-pill.is-closed {
  background: transparent;
  border-color: var(--color-line);
  color: var(--color-text-soft);
}
.open-pill.is-closed .pill-text { color: var(--color-text-soft); }
.page-home .hero .open-pill.is-closed {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.32);
}
.page-home .hero .open-pill.is-closed .pill-text { color: rgba(255, 255, 255, 0.68); }

/* ---------- Marquee: weiche Kanten + Pause außerhalb des Viewports ---------- */

.marquee {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee.is-off .marquee-track { animation-play-state: paused; }

/* ---------- Touch-Targets: dichte Link-Cluster entschärfen ---------- */

.card-links { gap: 2px 18px; }
.card-links a { display: inline-block; padding-block: 6px; }
/* [MESS] 40px hoch bei 8px (F5, feinschliff-pilot 2026-08-13) — auf 10px gezogen, damit das Ziel ueber 44px liegt. */
.footer-bottom a { display: inline-block; padding-block: 10px; }
.stat-card .arrow-link { font-size: var(--text-caption); }

/* ---------- Footer: Social Media ---------- */

.footer-social { display: flex; align-items: center; gap: var(--space-xs); }
.footer-social a { padding: 13px; }
.footer-social svg { display: block; }

/* ---------- Statement: Wörter füllen sich beim Scrollen ---------- */

.statement-fill .w { opacity: 0.16; transition: opacity 0.4s ease; }
.statement-fill .w.on { opacity: 1; }

/* ---------- Leistungskarten: Icon zeichnet sich beim Hover ---------- */
/* JS setzt pathLength="1" auf die Icon-Pfade */

html.js .card-flip:hover .card-icon :is(path, circle) {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: icon-draw 0.9s var(--ease-out) forwards;
}
@keyframes icon-draw { to { stroke-dashoffset: 0; } }

/* ---------- Journey: Schritte leuchten beim Scrollen auf ---------- */

.journey { position: relative; overflow: hidden; }
.journey::after {
  content: "";
  position: absolute;
  width: 640px; height: 640px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 50%;
  right: -240px; bottom: -300px;
  pointer-events: none;
}
.journey-grid { position: relative; z-index: 1; }
html.js .page-home .journey-steps li::before { transition: color 0.6s, -webkit-text-stroke-color 0.6s; }
html.js .page-home .journey-steps li.is-active::before { color: #fff; -webkit-text-stroke-color: #fff; }

/* ---------- Showcase: Bild entfaltet sich aus dem Bogen ---------- */
/* JS treibt --exp von 0 (Bogen-Karte) auf 1 (Full-Bleed) */

html.js .page-home .showcase-img {
  --exp: 0;
  clip-path: inset(
    0
    calc((1 - var(--exp)) * clamp(20px, 7vw, 110px))
    round
    calc((1 - var(--exp)) * var(--radius-arch))
    calc((1 - var(--exp)) * var(--radius-arch))
    0 0
  );
}

/* Duotone-Filter entfernt (Daniel, 2026-08-18: "sieht bei Personenbildern
   aus, als wären sie krank" — und der Sprung auf volle Sättigung beim Hover
   war derselbe Effekt wie am Praxis-Team-Showcase, siehe .ts-photo). Fotos
   bleiben durchgehend farbig. */

/* ---------- CTA-Band (Finale) ---------- */

.cta-band .eyebrow { color: rgba(255, 255, 255, 0.65); justify-content: center; }
.cta-band .lead { color: rgba(255, 255, 255, 0.85); max-width: 44ch; }

/* ---------- Footer-Vorhang: Seite gibt den Footer frei ---------- */

@media (min-width: 981px) {
  html.js .page-home main,
  html.js .page-detail main {
    position: relative;
    z-index: 2;
    background: var(--color-bg);
    margin-bottom: var(--footer-h, 0px);
    box-shadow: 0 40px 80px -40px rgba(0, 55, 75, 0.4);
  }
  html.js .page-home .site-footer,
  html.js .page-detail .site-footer {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 1;
  }
}

/* ---------- Reduced Motion: alles sofort sichtbar, nichts bewegt sich ---------- */

@media (prefers-reduced-motion: reduce) {
  html.js .page-home .hero h1 .line-inner,
  html.js .page-home .hero .hero-sub,
  html.js .page-home .hero .hero-claim,
  html.js .page-home .hero .hero-actions,
  html.js .page-home .hero-media,
  html.js .page-home .hero-media .arch-img {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .page-home .hero-badge { animation: none; }
  .open-pill .pill-dot::after { animation: none; }
  html.js .card-flip:hover .card-icon :is(path, circle) { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
  html.js .page-home .showcase-img { clip-path: none; }
  html.js .page-home .journey-steps li::before { transition: none; }
  .statement-fill .w { opacity: 1; }
}

/* ============================================================
   Unterseiten · Detail-Vorlage — WOW-Pass v3 (2026-07-07)
   Hebt die Leistungs-Detailseiten auf das Niveau der Startseite:
   Intro-Choreografie im Kopf, Bogen-Motiv mit Echo-Rahmen und
   schwebender Zusage, Prozess-Ziffern die beim Scrollen aufleuchten,
   ein immersiver Dark-Teal-Moment (Ergebnis), ruhiges Finale.
   Bewusst zurückhaltender als die Startseite: ein Eyecatcher pro
   Viewport-Höhe. Scoping: body.page-detail + html.js — greift nur
   auf Seiten, die sich per Body-Klasse anmelden. No-JS und
   prefers-reduced-motion sehen alles sofort. 1:1 nach Kadence.
   ============================================================ */

/* ---------- Detail-Kopf: mehr Luft, Bogen-Bild mit Echo ---------- */

.page-detail .page-hero { position: relative; overflow: hidden; padding-block: clamp(64px, 9vw, 116px) var(--space-xl); }
.page-detail .page-hero .split { align-items: center; }
/* weiche Beige-Aura wie im Startseiten-Hero, dezenter */
.page-detail .page-hero::before {
  content: "";
  position: absolute;
  width: 54vw; height: 54vw;
  max-width: 760px; max-height: 760px;
  border-radius: 50%;
  left: -20vw; top: -24vw;
  background: radial-gradient(circle, rgba(203, 196, 188, 0.38), transparent 66%);
  pointer-events: none;
}
.page-detail .page-hero > .container { position: relative; }
.page-detail .page-hero .subline { margin-top: 0; }
.page-detail .page-hero .hero-cta { margin-top: var(--space-m); }
.page-detail .page-hero .claim-line { margin-top: var(--space-m); }

/* Bogen-Bild + dünner Echo-Bogen + schwebende Zusage-Pille */
.arch-frame { position: relative; }
.arch-frame .arch-img { position: relative; z-index: 1; min-height: clamp(360px, 52vh, 560px); box-shadow: 0 40px 80px -40px rgba(0, 55, 75, 0.45); }
.arch-frame::before {
  content: "";
  position: absolute;
  inset: -20px 20px 20px -20px;
  border: 1px solid rgba(0, 72, 96, 0.22);
  border-radius: var(--radius-arch) var(--radius-arch) var(--radius) var(--radius);
  pointer-events: none;
  z-index: 0;
}
.arch-pill {
  position: absolute;
  z-index: 2;
  left: -22px;
  bottom: 40px;
  max-width: 80%;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--color-surface);
  border: 1px solid var(--color-line-soft);
  border-radius: 999px;
  box-shadow: 0 24px 48px -24px rgba(0, 55, 75, 0.35);
  padding: 12px 18px;
  font-size: var(--text-caption);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-accent);
}
.arch-pill .pill-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-accent); flex-shrink: 0; }
@media (max-width: 900px) { .arch-pill { left: 12px; bottom: 16px; max-width: calc(100% - 24px); } }

/* ---------- Detail-Kopf: Intro-Choreografie (gestaffelt) ---------- */

html.js .page-detail .page-hero .page-hero-text > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}
html.js .page-detail .page-hero .page-hero-text > :nth-child(1) { transition-delay: 0.05s; }
html.js .page-detail .page-hero .page-hero-text > :nth-child(2) { transition-delay: 0.12s; }
html.js .page-detail .page-hero .page-hero-text > :nth-child(3) { transition-delay: 0.19s; }
html.js .page-detail .page-hero .page-hero-text > :nth-child(4) { transition-delay: 0.26s; }
html.js .page-detail .page-hero .page-hero-text > :nth-child(5) { transition-delay: 0.33s; }
html.js .page-detail .page-hero .page-hero-text > :nth-child(6) { transition-delay: 0.40s; }
html.js .page-detail .page-hero .page-hero-text > :nth-child(7) { transition-delay: 0.47s; }
html.js .page-detail .page-hero .arch-frame {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s var(--ease-out) 0.15s, transform 0.9s var(--ease-out) 0.15s;
}
html.js .page-detail .page-hero .arch-frame .arch-img { transform: scale(1.03); transition: transform 1.2s var(--ease-out) 0.2s; }
html.js .page-detail.is-loaded .page-hero .page-hero-text > *,
html.js .page-detail.is-loaded .page-hero .arch-frame { opacity: 1; transform: none; }
html.js .page-detail.is-loaded .page-hero .arch-frame .arch-img { transform: none; }

/* ---------- „Für wen ist das?" — Situationen als Stimmen, keine Karten ----------
   Ersetzt 2026-08-19 die Kärtchen-Fassung (Box mit Hintergrund, Rahmen und
   farbigem linkem Strich) — genau das Bauteil, das ein generisches
   „KI-Feature-Card"-Muster ist: eine Box-Familie, die auf dieser Seite sonst
   nirgends vorkommt. Ersatz nutzt vorhandenes Signatur-Material: dasselbe
   Ghost-Anfuehrungszeichen wie `.quote-band` (nur klein und inline statt riesig
   im Hintergrund) und denselben Haarstrich-Trenner wie `.term-band`/
   `.card-links`. Kein Karten-Hintergrund, kein Rahmen, kein Eck-Radius: die
   vier Stimmen stehen als Liste, nicht als Rasterobjekte nebeneinander.
   Fließtext bewusst in `--font-body`, NICHT `--font-callout`: Daniel,
   2026-08-19 — Playfair ist als Akzent gedacht, nicht als Flaeche, und
   verliert seine Wirkung bei vier ganzen Saetzen am Stueck. Der eine
   Akzent-Einsatz sitzt jetzt am Absatzschluss (`.situations-close em`, teilt
   sich die Regel mit `.statement-line em`). Die literalen „…"-Anfuehrungs-
   zeichen sind aus dem Text selbst entfernt — das Ghost-Zeichen traegt die
   Geste allein, dieselbe Logik wie beim Zitatband (Daniel, 2026-08-16). */
.situation {
  position: relative;
  margin: 0;
  max-width: none;
  padding: var(--space-s) 0 var(--space-s) 38px;
  font-family: var(--font-body);
  font-size: 1.08rem;
  line-height: 1.5;
  color: var(--color-text);
}
.situation-list .situation + .situation { border-top: 1px solid var(--color-line-soft); }
.situation::before {
  content: "„";
  position: absolute;
  left: 0;
  top: 0.2em;
  font-style: normal;
  font-size: 2.1rem;
  line-height: 1;
  color: rgba(0, 72, 96, 0.32);
}
.situations-close { margin-top: var(--space-l); font-size: var(--text-lead); max-width: 62ch; }

/* ---------- „So läuft's ab" — Ziffern leuchten beim Scrollen auf ---------- */

html.js .process-steps li::before { transition: color 0.6s var(--ease-out), -webkit-text-stroke-color 0.6s var(--ease-out); }
html.js .process-steps li.is-active::before { color: var(--color-accent); -webkit-text-stroke-color: var(--color-accent); }

/* ---------- „Was sich ändert" — immersiver Dark-Teal-Höhepunkt ---------- */

.outcome {
  position: relative;
  background:
    radial-gradient(900px 460px at 82% 6%, rgba(203, 196, 188, 0.10), transparent 62%),
    linear-gradient(160deg, #0B4C63 0%, #004860 52%, #00303F 100%);
  color: #fff;
  text-align: center;
  padding-block: var(--space-xxl);
  overflow: hidden;
}
.outcome::before {
  content: "";
  position: absolute;
  width: 560px; height: 560px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 50%;
  left: -220px; bottom: -280px;
  pointer-events: none;
}
.outcome .container-narrow { position: relative; z-index: 1; }
.outcome .eyebrow { color: rgba(255, 255, 255, 0.65); justify-content: center; }
.outcome .statement-line {
  color: #fff;
  max-width: 26ch;
  margin: 0 auto;
  text-align: center;
  font-size: clamp(1.9rem, 4vw, 3rem);
}
/* Beige bleibt hier (Daniel, 2026-08-19: passt in den dunklen Sektionen besser
   als Graphite) — nur Semibold statt Regular ergaenzt, damit sich das
   Akzentwort gegen das kraeftige Weiss der Umgebung behauptet. Siehe
   `.statement-line em` oben fuer die helle Gegenstelle desselben Fixes. */
.outcome .statement-line em { color: var(--color-panel); font-weight: 600; }

/* SITEWIDE seit 2026-08-19 (Pilot an Prophylaxe gehärtet, dann freigegeben:
   "kann das so einmal auf alles ausgespielt werden") — dieselbe Diagonale
   wie `.page-home .statement-line .satz-2` (Zeile ~3010), auf Outcome-Maßstab
   herunterskaliert. Linksbündig statt zentriert — die zentrierte Textwand ist
   selbst ein generisches Muster, die Diagonale ist Signatur-Sprache der Seite
   (F5.3b). `container-narrow` bleibt zentriert im Abschnitt, nur der Text
   darin richtet sich links aus — der Radial-Verlauf (>=0,80 Deckung, Zeile
   ~1610) deckt dort weiterhin ab, gemessen nicht angenommen (siehe
   pruef-seite-Läufe in der Arbeitsnotiz, jede Seite einzeln geprüft). Bleibt
   eine Modifier-Klasse statt der Basisregel — nicht jede `.outcome
   .statement-line` traegt sie zwingend (z. B. falls eine Seite mal keinen
   zweisaetzigen Bruch hergibt), aber sie ist jetzt der Standardfall auf allen
   Outcome-Sektionen, nicht mehr Einzelfall. */
/* Erster Anlauf ging auf 5rem/780px-Container — zerfiel in eine Wort-Treppe
   (10 Zeilen), weil der Prophylaxe-Satz mehr Woerter traegt als die
   Homepage-Fragmente, denen die Skala urspruenglich abgemessen wurde. Statt
   die Schrift wieder einzudampfen: dem Text mehr Zeile geben, wie die
   Homepage-Statement-Flaeche selbst keinen schmalen Container nutzt. */
.outcome .container-narrow:has(.outcome-diagonal) { max-width: var(--container-max); }
.outcome .statement-line.outcome-diagonal {
  text-align: left;
  margin: 0;
  max-width: none;
  /* Ruecknahme (Daniel, 2026-08-19): 500 zurueck auf sitewide 600, dafuer
     die Groesse hochgezogen — 70px am Desktop (aus der Hand kalibriert,
     "sieht ganz gut aus"), lehnt sich damit staerker an die Homepage-Skala
     an (dort bis 131px, aber deren Zeilen sind auch deutlich kuerzer). Poppins
     500 bleibt im Font-Link geladen (harmlos ungenutzt), falls das Gewicht
     nochmal gebraucht wird — kein Grund, den Link wieder zu verkleinern. */
  font-size: clamp(2.2rem, 5.6vw, 4.375rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 600;
}
.outcome .statement-line.outcome-diagonal .satz-2 {
  display: block;
  padding-left: clamp(32px, 9vw, 128px);
  margin-top: clamp(10px, 2.4vw, 28px);
}
/* Sitewide auf jeder `.outcome-diagonal` (Hub-Finale wie alle 14 Detailseiten,
   siehe Kommentar oben) — Daniel, 2026-08-25: der zweite Satz soll auf dem
   Telefon komplett linksbuendig stehen. Die Staffelung ist ein Desktop-
   Signaturzug mit Platz zu verschenken; auf schmalem Bildschirm frisst der
   minimale Rest (32px) noch Zeile, ohne dass die Diagonale als Geste ankommt. */
@media (max-width: 620px) {
  .outcome .statement-line.outcome-diagonal .satz-2 { padding-left: 0; }
}
/* Akzentwort etwas groesser als der Umtext (Daniel, 2026-08-19: "Zeit vielleicht
   etwas groesser", am Pilot Prophylaxe entwickelt, jetzt sitewide auf jeder
   `.outcome-diagonal`) — zusaetzlich zu Farbe/Gewicht jetzt auch Maßstab als
   drittes Betonungsmittel. Bewusst nur innerhalb `.outcome-diagonal`, nicht an
   `.statement-line em` allgemein (dort, z. B. auf der Startseite, sitzt der
   Akzent oft mitten im Satz statt als Schlusspointe). line-height eigens auf
   0.93 statt der
   geerbten 1.1 gesetzt: unitless line-height skaliert mit der EIGENEN
   Schriftgroesse jedes Elements — bei 1.18em Groesse haette „Zeit" sonst einen
   groesseren Zeilenkasten aufgespannt als der Rest der Zeile, genau der
   Effekt, den Daniel als "Zeilenabstand im zweiten Satz wirkt groesser"
   bemerkt hat. 1.1 / 1.18 ≈ 0.93 gleicht das rechnerisch aus, bleibt aber
   Verhaeltnis statt Pixelwert — funktioniert auf jeder Fensterbreite. */
.outcome .statement-line.outcome-diagonal em { font-size: 1.18em; line-height: 0.93; }

/* ---------- Kosten — ruhige Zusicherungs-Karte ---------- */

/* F4, feinschliff-pilot 2026-08-13: ein farbiger Rand ueber 1px ist auf Karten/
   Listen/Callouts nirgends im design-guide verankert — ein Standardgriff, der
   sich als Entscheidung tarnte. Betonung wandert vom Rand auf die Flaeche;
   traegt auf Detailseiten mit Beige-Kosten-Feld die Trennung, die vorher der
   Balken behaupten sollte. */
.assurance {
  background: var(--color-surface);
  border: 1px solid var(--color-line-soft);
  border-left: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: clamp(28px, 4.4vw, 44px);
  margin-top: var(--space-m);
}
.assurance p { max-width: 64ch; }

/* ---------- Detail: Bild-Rhythmus — bricht die Textwand ---------- */

/* Bild-Text-Split: Bogen-Bild neben Text, Seiten wechseln sich ab */
.media-split { align-items: center; }
.media-split .arch-frame { margin: 0; }
.media-split .arch-frame .arch-img { min-height: clamp(340px, 42vw, 500px); }

/* Situationen als vertikale Liste in der Textspalte */
.situation-list { display: grid; margin-top: var(--space-s); }
.situation-list .situation { margin: 0; }

/* Bild schwebt neben langen Textstrecken mit (FAQ) */
@media (min-width: 981px) {
  .media-sticky { position: sticky; top: calc(var(--header-h) + 40px); align-self: start; }
}

/* „Symbolbild"-Marke für Voll-Bild-Flächen ohne .ph-Automatik */
.stock-tag {
  position: absolute;
  z-index: 2;
  left: 12px; bottom: 12px;
  background: rgba(0, 55, 75, 0.72);
  color: rgba(255, 255, 255, 0.92);
  font-size: var(--text-legal);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: var(--radius);
  pointer-events: none;
}

/* Outcome mit Hintergrundbild + Teal-Scrim — das Bild trägt den Höhepunkt */
.outcome .outcome-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
  will-change: background-position;
}
.outcome.has-image::before { display: none; }
.outcome.has-image::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(160deg, rgba(11, 76, 99, 0.86) 0%, rgba(0, 72, 96, 0.80) 52%, rgba(0, 48, 63, 0.92) 100%);
}
.outcome .container-narrow { position: relative; z-index: 2; }

/* ---------- Detail-Finale ---------- */

.page-detail .cta-band .eyebrow { color: rgba(255, 255, 255, 0.65); justify-content: center; }

/* ---------- Reduced Motion: Detail-Vorlage sofort sichtbar ---------- */

@media (prefers-reduced-motion: reduce) {
  html.js .page-detail .page-hero .page-hero-text > *,
  html.js .page-detail .page-hero .arch-frame,
  html.js .page-detail .page-hero .arch-frame .arch-img {
    opacity: 1;
    transform: none;
    transition: none;
  }
  html.js .process-steps li::before,
  html.js .process-steps li.is-active::before { transition: none; }
}

/* ============================================================
   Hub-Seiten · Signatur v3.3 (2026-07-12)
   Projekt 1.1 — leistungen.html („Der Index als Bühne") und
   praxis.html („Die Begegnungs-Seite"). Eigene Signatur-Momente:
   Ghost-Backdrop im Hero, Kapitel-Dramaturgie mit Scrollspy-Tabs
   (gleitender Indikator), Editorial-Index-Zeilen statt Karten,
   Team-Showcase mit gekoppelter Foto/Namen-Interaktion,
   Slot-Ziffern (rollende Zahlen), Bogen-Entfaltung, rotierendes
   Claim-Siegel entlang einer Kreisbahn.
   Scoping: body.page-hub (+ page-hub-leistungen / page-hub-praxis),
   html.js für Bewegung. No-JS und prefers-reduced-motion sehen
   alles sofort. Nur CI-Farben/-Fonts — 1:1 nach Kadence.
   ============================================================ */

/* ---------- Hub-Hero: Großtypografie + Ghost-Backdrop ---------- */

.page-hub .page-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(72px, 10vw, 148px) var(--space-xl);
}
.page-hub .page-hero::before {
  content: "";
  position: absolute;
  width: 54vw; height: 54vw;
  max-width: 760px; max-height: 760px;
  border-radius: 50%;
  left: -20vw; top: -24vw;
  background: radial-gradient(circle, rgba(203, 196, 188, 0.38), transparent 66%);
  pointer-events: none;
}
.page-hub .page-hero > .container { position: relative; }
.page-hub .page-hero h1 {
  font-size: var(--text-display);
  line-height: 1.04;
  max-width: 14ch;
}
.page-hub .page-hero .lead { position: relative; }
.page-hub .page-hero .claim-line { margin-top: var(--space-m); }

/* riesige Outline-Zahl als Backdrop (z. B. „13" Leistungen) */
.hub-ghost {
  position: absolute;
  right: calc(var(--gutter) * -0.5);
  top: 50%;
  transform: translateY(-52%);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(7rem, 28vw, 24rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.16);
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.hub-ghost small {
  display: block;
  font-size: 0.09em;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: right;
  color: var(--color-text-soft);
  -webkit-text-stroke: 0;
  margin-top: 0.2em;
}
@media (max-width: 900px) { .hub-ghost { opacity: 0.55; top: 38%; } }
/* Auf dem Telefon liegen Titel und Subheadline ueber der Ziffer, kein
   Mehrwert im engen Raum (Daniel, 2026-08-25). Ersatzlos aus statt neu zu
   positionieren, statt die 900px-Zwischenstufe oben anzufassen. */
@media (max-width: 620px) { .hub-ghost { display: none; } }

/* Hub-Intro-Choreografie (gleiche Sprache wie die Detail-Vorlage) */
html.js .page-hub .page-hero .page-hero-text > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}
html.js .page-hub .page-hero .page-hero-text > :nth-child(1) { transition-delay: 0.05s; }
html.js .page-hub .page-hero .page-hero-text > :nth-child(2) { transition-delay: 0.12s; }
html.js .page-hub .page-hero .page-hero-text > :nth-child(3) { transition-delay: 0.19s; }
html.js .page-hub .page-hero .page-hero-text > :nth-child(4) { transition-delay: 0.26s; }
html.js .page-hub .page-hero .page-hero-text > :nth-child(5) { transition-delay: 0.33s; }
html.js .page-hub .page-hero .hub-ghost,
html.js .page-hub .page-hero .ring-badge {
  opacity: 0;
  transition: opacity 1.1s var(--ease-out) 0.3s;
}
html.js .page-hub.is-loaded .page-hero .page-hero-text > * { opacity: 1; transform: none; }
html.js .page-hub.is-loaded .page-hero .hub-ghost,
html.js .page-hub.is-loaded .page-hero .ring-badge { opacity: 1; }
@media (max-width: 900px) {
  html.js .page-hub.is-loaded .page-hero .hub-ghost { opacity: 0.55; }
}

/* ---------- Kapitel-Navigation: Tabs mit gleitendem Indikator ---------- */

.hub-nav {
  position: sticky;
  top: var(--header-h);
  z-index: 40;
  background: rgba(246, 246, 246, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-block: 1px solid var(--color-line-soft);
}
.hub-nav-inner {
  position: relative;
  display: flex;
  gap: clamp(4px, 1.5vw, 10px);
  overflow-x: auto;
  padding-block: 8px;
  scrollbar-width: none;
  /* weiche Kante signalisiert: rechts liegen weitere Tabs */
  -webkit-mask-image: linear-gradient(90deg, #000 92%, transparent);
  mask-image: linear-gradient(90deg, #000 92%, transparent);
}
.hub-nav-inner::-webkit-scrollbar { display: none; }
.hub-nav a {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
  padding: 13px 20px; /* ≥44px Touch-Target */
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--color-text);
  text-decoration: none;
  transition: color 0.35s;
}
.hub-nav a .num {
  font-family: var(--font-heading);
  font-size: 0.8em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.45);
  transition: -webkit-text-stroke-color 0.35s;
}
.hub-nav a.is-active { color: var(--color-on-accent); }
.hub-nav a.is-active .num { -webkit-text-stroke-color: rgba(255, 255, 255, 0.7); }
.hub-nav a:hover:not(.is-active) { color: var(--color-accent); }
.hub-indicator {
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 0;
  width: 0;
  background: var(--color-accent);
  border-radius: 999px;
  transition: transform 0.5s var(--ease-spring), width 0.5s var(--ease-spring), opacity 0.3s;
  opacity: 0;
}
.hub-indicator.is-on { opacity: 1; }

/* ---------- Kapitel: sticky Kopf links, Editorial-Index rechts ---------- */

.hub-chapter {
  padding-block: clamp(56px, 8vw, 104px);
  scroll-margin-top: calc(var(--header-h) + 76px);
}
.hub-chapter + .hub-chapter { border-top: 1px solid var(--color-line-soft); }
.chapter-grid { display: grid; gap: var(--space-l); }
@media (min-width: 981px) {
  .chapter-grid { grid-template-columns: 5fr 7fr; gap: clamp(48px, 6vw, 110px); }
  .chapter-head { position: sticky; top: calc(var(--header-h) + 108px); align-self: start; }
}
.chapter-num {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(4.4rem, 9vw, 7.5rem);
  line-height: 0.9;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.3);
  margin-bottom: var(--space-s);
  transition: color 0.7s var(--ease-out), -webkit-text-stroke-color 0.7s var(--ease-out);
}
html.js .hub-chapter.is-active .chapter-num { color: var(--color-accent); -webkit-text-stroke-color: var(--color-accent); }
.chapter-head h2 { font-size: clamp(1.9rem, 3.4vw, 2.8rem); max-width: 14ch; }
.chapter-head .chapter-lead { font-size: 1.05rem; color: var(--color-text-soft); max-width: 38ch; }
.chapter-head .arch-frame { margin-top: var(--space-m); max-width: 340px; }
.chapter-head .arch-frame .arch-img { min-height: clamp(240px, 24vw, 320px); }
@media (max-width: 980px) { .chapter-head .arch-frame { max-width: 280px; } }

/* Editorial-Index: Leistungen als große Zeilen statt Karten */
.index-rows { list-style: none; margin: 0; padding: 0; }
.index-rows li { margin: 0; }
.index-row {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(16px, 3vw, 36px);
  padding-block: clamp(22px, 3vw, 32px);
  /* Daniel, 2026-08-25: Nummer und Pfeil standen beim Hover direkt am Rand der
     Hervorhebung. Die Flaeche (`.index-row::before`, inset:0) fuellt weiterhin
     die volle Zeilenbreite bis an border-top/-bottom, nur der Inhalt rueckt
     jetzt ein, border-box macht das ohne die Zeile selbst schmaler zu machen. */
  padding-inline: clamp(14px, 2vw, 24px);
  border-top: 1px solid var(--color-line);
  text-decoration: none;
}
.index-rows li:last-child .index-row { border-bottom: 1px solid var(--color-line); }
/* sanfter Flächen-Sweep hinter der Zeile — Breite = Zeilenbreite (Daniel,
   2026-08-18: der Sweep lief vorher per negativem Inset in den Rand hinein
   und war dadurch breiter als der Trennstrich derselben Zeile). */
.index-row::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-surface);
  opacity: 0;
  transition: opacity 0.4s;
}
.index-row > * { position: relative; }
.index-row:hover::before, .index-row:focus-visible::before { opacity: 1; }
.index-row .row-num {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.05rem;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.4);
  transition: color 0.4s, -webkit-text-stroke-color 0.4s;
  min-width: 2.4em;
}
.index-row:hover .row-num { color: var(--color-accent); -webkit-text-stroke-color: var(--color-accent); }
.index-row .row-name {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--color-accent);
  transition: transform 0.45s var(--ease-out);
}
.index-row .row-desc {
  font-size: 0.97rem;
  color: var(--color-text-soft);
  max-width: 56ch;
  margin: 6px 0 0;
}
.index-row .row-arrow {
  width: 46px; height: 46px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border: 1px solid rgba(0, 72, 96, 0.3);
  border-radius: 50%;
  color: var(--color-accent);
  font-size: 1.1rem;
  transition: background-color 0.35s, color 0.35s, border-color 0.35s, transform 0.45s var(--ease-spring);
}
.index-row:hover .row-name, .index-row:focus-visible .row-name { transform: translateX(10px); }
.index-row:hover .row-arrow, .index-row:focus-visible .row-arrow {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #fff;
  transform: translateX(6px);
}
@media (max-width: 620px) {
  /* Nummer bleibt (roter Faden 01–13), der redundante Pfeil weicht —
     die ganze Zeile ist ohnehin der Link */
  .index-row { grid-template-columns: auto 1fr; }
  .index-row .row-num { min-width: 1.8em; }
  .index-row .row-arrow { display: none; }
}

/* Volle Fensterbreite unterhalb der Zweispalten-Schwelle (981px, F6.4) —
   Daniel, 2026-08-25: "kein grauer Rand mehr links und rechts" auf dem
   Telefon. Die Liste bricht per negativem Margin aus dem Container-Gutter
   aus, `.index-row` bekommt genau diesen Gutter als eigenes Innenpolster
   zurueck (statt des schmalen Hover-Abstands oben) — Hintergrund und
   Trennlinien der Zeile laufen bis an den Bildschirmrand, "01 Prophylaxe"
   bleibt links buendig mit der Kapitelueberschrift darueber. */
@media (max-width: 980px) {
  .page-hub .index-rows { margin-inline: calc(var(--gutter) * -1); }
  .page-hub .index-row { padding-inline: var(--gutter); }
}

/* ---------- Job-Zeilen (Karriere) — Kreuzung aus .ts-row (Bild, Titel, Rolle,
   Kurztext) und .index-row (Hover-Sweep, Pfeil-Kreis), Daniel 2026-08-21,
   nachgeschärft 2026-08-21: Bildformat 1:1 von .ts-portrait übernommen (erster
   Versuch mit kompaktem 160-200px-Thumb "passte visuell nicht") — nur der
   Hover-Sweep und der Pfeil-Kreis kommen von .index-row, keine Ghost-Ziffer
   mehr (Daniel: fest ins HTML geschriebene Nummern muessten bei jeder
   Stellenänderung von Hand nachgezogen werden, nicht den Aufwand wert für ein
   rein dekoratives Element). Bild zeigt bewusst Arbeitsumgebung/Atmosphäre
   statt Portrait — bei einer offenen Stelle steht die Person, die sie
   besetzt, noch nicht fest. Bogen-Echo-Ring kommt gratis aus .arch-frame mit.
   .row-arrow-Optik hier dupliziert statt mit .index-row geteilt, damit die
   13 bestehenden Leistungs-Zeilen unangetastet bleiben. Breakpoint 820px
   bewusst identisch zu .ts-row (821px), damit beide Bild-Zeilen-Bauteile im
   selben Moment umbrechen. */
.job-rows { list-style: none; margin: 0; padding: 0; }
.job-rows li { margin: 0; border-top: 1px solid var(--color-line); }
.job-rows li:last-child { border-bottom: 1px solid var(--color-line); }
.job-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(240px, 340px) 1fr auto;
  align-items: center;
  gap: clamp(24px, 4vw, 56px);
  padding: clamp(32px, 4.5vw, 56px) 28px;
  text-decoration: none;
}
.job-row::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-surface);
  opacity: 0;
  transition: opacity 0.4s;
}
.job-row > * { position: relative; }
.job-row:hover::before, .job-row:focus-visible::before { opacity: 1; }
.job-row .job-thumb { margin: 0; }
.job-row .job-thumb .arch-img { min-height: 0; aspect-ratio: 380 / 470; }
.job-row .job-title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(1.3rem, 2vw, 1.6rem);
  letter-spacing: -0.01em;
  color: var(--color-accent);
  margin: 0 0 6px;
  transition: transform 0.45s var(--ease-out);
}
.job-row .job-meta {
  font-size: var(--text-caption);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-soft);
  margin: 0 0 8px;
}
.job-row .job-desc { font-size: 0.97rem; color: var(--color-text-soft); max-width: 48ch; margin: 0; }
.job-row:hover .job-title, .job-row:focus-visible .job-title { transform: translateX(8px); }
.job-row .row-arrow {
  width: 46px; height: 46px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border: 1px solid rgba(0, 72, 96, 0.3);
  border-radius: 50%;
  color: var(--color-accent);
  font-size: 1.1rem;
  transition: background-color 0.35s, color 0.35s, border-color 0.35s, transform 0.45s var(--ease-spring);
}
.job-row:hover .row-arrow, .job-row:focus-visible .row-arrow {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #fff;
  transform: translateX(6px);
}
@media (max-width: 820px) {
  .job-row { grid-template-columns: 1fr; }
  .job-row .job-thumb { max-width: 340px; }
  .job-row .row-arrow { display: none; }
}

/* ---------- Stat-Band: Kennzahlen mit rollenden Slot-Ziffern ---------- */

.stat-band {
  background: var(--color-surface);
  border-block: 1px solid var(--color-line-soft);
}
.stat-band-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-m);
  padding-block: clamp(36px, 5vw, 56px);
}
@media (max-width: 900px) { .stat-band-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-l) var(--space-m); } }
/* Zahl zentriert ueber dem Text (Daniel, 2026-08-18: linksbuendig wirkte
   "funky" und liess ungleich breite Zahlen wie 5,0★/13 optisch weit
   auseinanderstehen, obwohl die Spalten gleich breit sind). */
.stat-item { text-align: center; }
.stat-item .stat-num {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 4px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(2.4rem, 4.6vw, 3.8rem);
  line-height: 1;
  color: var(--color-accent);
  margin-bottom: 10px;
}
.stat-item .stat-suffix { font-size: 0.55em; }
.stat-item .stat-label { display: block; margin-inline: auto; font-size: var(--text-caption); color: var(--color-text-soft); max-width: 22ch; }
/* Slot-Mechanik: jede Ziffer sitzt in einer geclippten Zelle und rollt zur Zielziffer */
.slot { display: inline-flex; overflow: hidden; height: 1em; }
.slot .slot-cell { display: inline-block; height: 1em; overflow: hidden; }
.slot .slot-reel {
  display: block;
  transform: translateY(0);
  transition: transform 1.15s var(--ease-out);
}
.slot .slot-reel span { display: block; height: 1em; line-height: 1; }

/* ---------- Team-Showcase: drei Begegnungen in einer Reihe ---------- */
/* Neufassung 2026-08-19. Die gekoppelte Portrait-Collage ist nach drei
   Anlaeufen an derselben Stelle gefallen (Graustufen→Farbe: "sieht aus, als
   waeren sie krank" · diagonale Kaskade: Kopplung unsichtbar · Deckkraft +
   Plakette: "gefaellt mir gar nicht", alle Daniel 08/2026). Drei gleiche
   Einwaende sind ein Befund ueber das Bauteil, nicht ueber die Ausfuehrung:
   Die Collage war das einzige Element der Website mit gestapelten,
   interaktiv gekoppelten Fotos — ein Konstrukt ohne Vorbild auf der Seite.
   Jetzt spricht die Sektion die vorhandene Sprache: Bogen-Portrait mit
   Echo-Rahmen (.arch-frame, wie Hero und Detailseiten) im Hochformat
   380/470 ≈ 0,81 — die gemessene Invariante aus rollout-spec §0, nie nur
   eine Seite des Verhaeltnisses aendern. Bilder wechseln die Seite
   (Detail-Vorlage #6: "Bilder abwechselnd links/rechts, Boegen runden,
   echte Gesichter waermen"). Keine Kopplung, kein Hover-Zustand, kein JS:
   alle drei Gesichter stehen immer voll sichtbar da. */

.ts-rows { list-style: none; margin: 0; padding: 0; }
.ts-rows li { margin: 0; border-top: 1px solid var(--color-line); }
.ts-rows li:last-child { border-bottom: 1px solid var(--color-line); }
.ts-row {
  display: grid;
  gap: clamp(24px, 4vw, 64px);
  padding-block: clamp(32px, 4.5vw, 64px);
}
.ts-portrait { width: min(100%, 300px); margin: 0; }
.ts-portrait .arch-img {
  min-height: 0;
  aspect-ratio: 380 / 470; /* Hochformat 0,81 — Breite und Hoehe nur gemeinsam aendern */
}
.ts-row h3 {
  display: flex;
  align-items: baseline;
  gap: 16px;
  font-size: clamp(1.8rem, 3.2vw, 2.7rem);
  letter-spacing: -0.015em;
  margin-bottom: 6px;
}
.ts-row .ts-num {
  font-size: 0.55em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.4);
}
.ts-row .ts-role {
  font-size: var(--text-caption);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-soft);
  margin-bottom: 10px;
}
.ts-row p { font-size: 0.98rem; max-width: 52ch; }
@media (min-width: 821px) {
  .ts-row { grid-template-columns: minmax(240px, 340px) minmax(0, 1fr); align-items: center; }
  .ts-portrait { width: 100%; }
  /* Jede zweite Begegnung spiegelt: Portrait rechts, Text haelt die linke
     Lesekante — derselbe Wechsel wie die Bild-Text-Splits der Detailseiten */
  .ts-rows li:nth-child(even) .ts-row { grid-template-columns: minmax(0, 1fr) minmax(240px, 340px); }
  .ts-rows li:nth-child(even) .ts-portrait { order: 2; }
  .ts-rows li:nth-child(even) .ts-body { order: 1; }
}

/* ---------- Direction-Aware Hover (Team-Grid, Räume) ---------- */
/* JS setzt --ox/--oy auf die Eintritts-/Austrittsseite des Cursors */

/* Richtungsabhaengiger Hover entfernt (Daniel, 2026-08-18: "ein wenig much",
   einziger Ort der Seite mit diesem Effekt — Simplicity). Die Bildunterschrift
   steht jetzt immer da, kein Ein-/Ausgleiten mehr. */
.dah { position: relative; overflow: hidden; }
.dah .dah-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4px;
  padding: 20px;
  background: linear-gradient(180deg, rgba(0, 55, 75, 0) 55%, rgba(0, 55, 75, 0.8) 100%);
  color: #fff;
}
.dah .dah-overlay strong { font-family: var(--font-heading); font-size: 1.05rem; }
.dah .dah-overlay span { font-size: var(--text-caption); color: rgba(255, 255, 255, 0.8); }

/* ---------- Claim-Siegel: Text läuft auf einer Kreisbahn ---------- */

.ring-badge {
  position: absolute;
  right: max(var(--gutter), 5vw);
  top: 50%;
  transform: translateY(-50%);
  width: clamp(130px, 15vw, 180px);
  aspect-ratio: 1;
  pointer-events: none;
  z-index: 1;
}
.ring-badge svg { width: 100%; height: 100%; overflow: visible; animation: ring-spin 32s linear infinite; }
.ring-badge.is-off svg { animation-play-state: paused; } /* außerhalb des Viewports (Akku) */
@keyframes ring-spin { to { transform: rotate(1turn); } }
.ring-badge text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  fill: var(--color-accent-80);
}
.ring-badge .ring-center {
  font-size: 26px;
  letter-spacing: 0;
  fill: rgba(0, 72, 96, 0.45);
  animation: none;
}
@media (max-width: 760px) { .ring-badge { display: none; } }

/* ---------- Praxis-Hero: Flächen-Durchgang (Etappe 6, 2026-08-18) ----------
   Praxis ist eine Buehnenseite mit eigenem Inhalt — bekommt anders als die 14
   Leistungsseiten (typogetragener Detail-Kopf, Etappe 1) denselben Flächen-
   Sprung wie die Startseite (F4): Foto wird die Fläche, Text liegt AUF ihr.
   Rohbau-Regel (Daniel, 2026-08-18): fehlendes Bildmaterial ist kein Bau-Stopp
   — `praxisraum-weit.jpg` läuft als Platzhalter bis zum echten Shooting, dann
   Bildtausch ohne Strukturänderung. Ersetzt das getrennte `.showcase`-Band,
   das vorher direkt unter dem hellen Hero lag — beides hintereinander wäre
   dieselbe Fläche zweimal. */
.page-hub-praxis .page-hero {
  position: relative;
  overflow: hidden;
  display: grid;
  align-content: end;
  min-height: clamp(560px, 78vh, 820px);
  padding-block: var(--space-xl) var(--space-xxl);
}
/* Grid statt Flex bewusst: ein Flex-Item ohne eigenes `width:100%` schrumpft
   auf Inhaltsbreite (Flex-Basis „auto" wertet die Breite, nicht den
   verfügbaren Raum) — `.container` landete dadurch zentriert bei 633px statt
   auf der 1176px-Kante. Grid-Items strecken sich in der Inline-Achse per
   Default; nur die Block-Achse wird über `align-content: end` ans Ende gelegt.
   Gemessen mit check-kanten.mjs (siehe .temp/meisterklasse-Notiz). */
.page-hub-praxis .page-hero::before { display: none; } /* Ghost-Backdrop-Kreis entfällt auf dem Foto */
.page-hub-praxis .page-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
}
/* Verlauf, kein Vorhang (F4.4-Lehre): unten dicht unter dem Text, oben frei —
   Boden ≥0,80 Deckung im Textbereich (§0² der Rollout-Spec). */
.page-hub-praxis .page-hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgba(0, 48, 63, 0.94) 0%,
    rgba(0, 48, 63, 0.88) 30%,
    rgba(0, 55, 75, 0.58) 62%,
    rgba(0, 55, 75, 0.28) 100%);
}
/* `width: 100%` ist Pflicht: `.container` hat kein eigenes `width`, nur
   `max-width` + `margin-inline: auto` (style.css:122). Im normalen Blockfluss
   fuellt `width:auto` erst auf max-width, dann zentrieren die Auto-Margins —
   im Grid dagegen gewinnen Auto-Margins gegen `stretch` und der Container
   schrumpft auf Inhaltsbreite (gemessen: 686px statt 1176px, zentriert bei
   377px statt an der 132px-Kante der Seite). Mit `width:100%` bleibt die
   gemeinsame linke Kante erhalten. */
.page-hub-praxis .page-hero > .container { position: relative; z-index: 2; width: 100%; }
.page-hub-praxis .page-hero h1,
.page-hub-praxis .page-hero .eyebrow,
.page-hub-praxis .page-hero .lead { color: var(--color-on-accent); }
.page-hub-praxis .page-hero .eyebrow { color: rgba(255, 255, 255, 0.72); }
.page-hub-praxis .page-hero .lead { color: rgba(255, 255, 255, 0.86); }
.page-hub-praxis .ring-badge text { fill: rgba(255, 255, 255, 0.55); }
.page-hub-praxis .ring-badge .ring-center { fill: rgba(255, 255, 255, 0.7); }
@media (max-width: 900px) {
  .page-hub-praxis .page-hero { min-height: clamp(440px, 70vh, 620px); }
  .page-hub-praxis .page-hero-media::after {
    background: linear-gradient(to top,
      rgba(0, 48, 63, 0.95) 0%,
      rgba(0, 48, 63, 0.90) 45%,
      rgba(0, 55, 75, 0.62) 100%);
  }
}

/* ---------- Unterseiten-Kopf, dunkel — nur die Essenz (Etappe 7, 2026-08-18) ----------
   Kontakt/Termin sind Funktionsseiten und bekommen laut rollout-spec §10
   Etappe 7 ausdrücklich KEINEN Flächen-Sprung — nur das Kopf-Muster aus
   Etappe 1 übernommen, auf seine Essenz reduziert (Grund, Schrift, Maßstab).
   Ohne Bogen-Bild/Split-Grid/Begriffsband — die hängen am Leistungsseiten-
   Skelett (§0 der Rollout-Spec) und haben auf einer Funktionsseite keinen
   Gegenstand. */
.page-hero.head-dark {
  background: var(--color-accent-deep);
  color: var(--color-on-accent);
}
.page-hero.head-dark::before { display: none; }
.page-hero.head-dark h1 {
  font-size: clamp(2.4rem, 5vw, 3.8rem);
  /* 1.18 (erster Versuch) reichte nicht — Daniel sah die Klammer bei
     "(m/w/d)" noch in die Zeile darüber ragen. Der Stellentitel ist der mit
     Abstand längste im System und bricht selbst bei 7fr-Spalte auf drei
     Zeilen; 1.3 gibt jeder Zeile spürbar Luft, statt nochmal auf Verdacht
     nachzujustieren. */
  line-height: 1.3;
  color: var(--color-on-accent);
}
.page-hero.head-dark .eyebrow { color: rgba(255, 255, 255, 0.72); }
.page-hero.head-dark .lead { color: rgba(255, 255, 255, 0.84); }
/* Subline + Absatz erst 2026-08-21 dazugekommen (karriere-zfa.html) — auf
   termin.html/kontakt.html wirkungslos, die haben kein `.page-hero-text`
   und kein `.subline`. */
.page-hero.head-dark .subline { color: var(--color-panel); }
.page-hero.head-dark .page-hero-text > p { color: rgba(255, 255, 255, 0.78); }

/* Job-Detailseiten (z. B. karriere-zfa.html, Daniel 2026-08-21): dieselbe
   Kopf-Grammatik wie eine Leistungsseite — Split-Grid, Bogen-Bild, hero-cta
   mit Telefonnummer. Der Hub (karriere.html) bleibt bewusst ohne Bild (siehe
   Kommentar oben, Funktionsseite ohne Gegenstand fuers Foto); nur die
   Stellenanzeige selbst verkauft etwas und bekommt das Buehnenbild, exakt
   die gleiche Aufteilung wie Hub/Detail bei den Leistungsseiten
   (leistungen.html ohne Bild, leistungen-*.html mit). Bewusst NICHT ueber
   `.page-detail.is-built` gemacht — dieses Body-Klassen-Paket haette
   sitewide Nebenwirkungen (Footer-Vorhang, Container-Breiten,
   Begriffsband-Optik) auf Sektionen, die niemand angefasst haben wollte
   (Intro-Text, "So bewerben Sie sich" laufen ueber `.container-narrow`,
   das unter `.page-detail.is-built` das Zentrieren verliert). `.head-dark`
   selbst traegt auch termin.html/kontakt.html (samt EN-Pendants) — die
   Regeln unten bleiben dort wirkungslos, weil deren Hero kein `.arch-frame`,
   `.btn-primary` oder `.hero-phone` enthaelt (nur eyebrow/h1/lead).
   Die Farben/Werte hier sind identisch zu `.page-detail.is-built .page-hero`
   (Zeile ~2617) und `.page-home .hero` (Zeile ~2957) — dasselbe Muster
   "heller Button/Telefon auf dunklem Bogen-Hero", nur schmaler skaliert.
   NACHTRAG (Daniel, 2026-08-21, zweite Runde): Genau dieses Herauslösen
   aus `.page-detail.is-built` hat zwei Werte verschluckt, die dort
   mitgeliefert werden und hier von Hand nachgezogen werden mussten —
   `hero-cta`-Abstand zum Text und die Bildbreiten-Deckelung (siehe unten,
   Klasse `.page-career-detail`). Gleiche Zahlen wie auf den
   Leistungsseiten, nicht neu erfunden — nur nicht automatisch mitgekommen,
   weil sie an `.page-detail.is-built` haengen und dieser Hero bewusst
   daran vorbeigebaut ist. */
.page-hero.head-dark .arch-frame::before { border-color: rgba(255, 255, 255, 0.26); }
.page-hero.head-dark .arch-frame .arch-img {
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14), 0 40px 80px -40px rgba(0, 0, 0, 0.55);
}
.page-hero.head-dark .hero-phone { color: #fff; border-bottom-color: rgba(255, 255, 255, 0.5); }
.page-hero.head-dark .btn-primary { background: var(--color-on-accent); color: var(--color-accent); }
.page-hero.head-dark .btn-primary:hover { background: var(--color-bg); color: var(--color-accent-deep); }
/* Fehlte komplett: auf Leistungsseiten haengt der Abstand an
   `.page-detail .page-hero .hero-cta` (Zeile ~1371), hier ohne diese Klasse
   nirgends gesetzt — der Button klebte direkt am Absatz. */
.page-hero.head-dark .hero-cta { margin-top: var(--space-m); }

/* ---- Bildbreiten-Deckel fuer Job-Detailseiten (Daniel, 2026-08-21,
   zweite Runde: "die Bilder in den Sektionen sind deutlich breiter als in
   den Sektionen auf den Leistungsseiten") ----
   Ursache: `.page-detail.is-built .arch-frame { width: min(100%, 380px) }`
   und die Hero-Variante `width: min(100%, 460px)` (Zeile ~2732) deckeln das
   Bild auf allen 14 Leistungsseiten schmaler als seine Grid-Spalte. Ohne
   `.page-detail.is-built` (bewusste Entscheidung, siehe Kommentar oben)
   fehlte dieser Deckel komplett — das Bild lief auf volle Spaltenbreite
   (~580–620px) statt der vorgesehenen 380/460px. Dieselben Zahlen wie dort,
   nur unter dem eigenen, schmal geschnittenen Klassennamen dieser Seite
   nachgezogen, damit Intro-Text und "So bewerben Sie sich" NICHT über
   `.page-detail.is-built` mitgezogen werden (siehe Kommentar oben). */
@media (min-width: 901px) {
  .page-career-detail .section-tight .arch-frame { width: min(100%, 380px); justify-self: center; }
  .page-career-detail .section-tight .media-split .arch-frame .arch-img { min-height: 470px; }
  .page-career-detail .page-hero.head-dark .arch-frame { width: min(100%, 460px); }
  .page-career-detail .page-hero.head-dark .arch-frame .arch-img { min-height: 570px; }
}
/* Textspalte breiter als der Standard-Split 1fr/1fr (Daniel, 2026-08-21:
   Zeilen kollidierten) — "Zahnmedizinische Fachangestellte (m/w/d)" ist
   laenger als jeder Leistungstitel und presste bei 1fr/1fr auf drei enge
   Zeilen. 7fr/5fr wie bei `.page-detail.is-built .page-hero .split`
   (Zeile ~2606), min-width:0 aus demselben Grund wie dort (Grid-Items
   wachsen sonst auf max-content und brechen nie um). */
@media (min-width: 901px) {
  .page-hero.head-dark .split { grid-template-columns: 7fr 5fr; }
  .page-hero.head-dark .split > * { min-width: 0; }
}

/* ---------- Finale-CTA im dunklen Zusage-Band ---------- */

.outcome .hero-cta { justify-content: center; margin-top: var(--space-l); }
.outcome .hero-phone { color: #fff; }

/* ---------- Porträt-Kacheln (Hub-Grids) ---------- */

.tile-portrait { min-height: 360px; }

/* ---------- Räume: ein breites Bild + zwei kleine (Layout-Varianz) ---------- */

.room-grid { display: grid; gap: var(--space-s); }
.room-grid .ph { min-height: 280px; }
.room-grid .room-wide { grid-column: 1 / -1; min-height: clamp(260px, 38vw, 460px); }
@media (min-width: 621px) { .room-grid { grid-template-columns: 1fr 1fr; } }

/* ---------- Bogen-Entfaltung auf Hub-Seiten (wie Startseite) ---------- */

html.js .page-hub .showcase-img {
  --exp: 0;
  clip-path: inset(
    0
    calc((1 - var(--exp)) * clamp(20px, 7vw, 110px))
    round
    calc((1 - var(--exp)) * var(--radius-arch))
    calc((1 - var(--exp)) * var(--radius-arch))
    0 0
  );
}

/* Journey-Ziffern leuchten auch auf Hub-Seiten */
html.js .page-hub .journey-steps li::before { transition: color 0.6s, -webkit-text-stroke-color 0.6s; }
html.js .page-hub .journey-steps li.is-active::before { color: #fff; -webkit-text-stroke-color: #fff; }

/* Footer-Vorhang gilt auch für Hub-Seiten */
@media (min-width: 981px) {
  html.js .page-hub main {
    position: relative;
    z-index: 2;
    background: var(--color-bg);
    margin-bottom: var(--footer-h, 0px);
    box-shadow: 0 40px 80px -40px rgba(0, 55, 75, 0.4);
  }
  html.js .page-hub .site-footer {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 1;
  }
}

/* ---------- FAQ: weiches Auf-/Zuklappen (progressive enhancement) ---------- */
/* Greift in Browsern mit interpolate-size; überall sonst klappt es wie bisher */

@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    :root { interpolate-size: allow-keywords; }
    .faq details::details-content {
      block-size: 0;
      overflow-y: clip;
      transition: block-size 0.4s var(--ease-out), content-visibility 0.4s allow-discrete;
    }
    .faq details[open]::details-content { block-size: auto; }
  }
}

/* ---------- Reduced Motion: Hub-Schicht sofort sichtbar & ruhig ---------- */

@media (prefers-reduced-motion: reduce) {
  html.js .page-hub .page-hero .page-hero-text > *,
  html.js .page-hub .page-hero .hub-ghost,
  html.js .page-hub .page-hero .ring-badge {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .hub-indicator { transition: none; }
  .chapter-num, .index-row .row-name, .index-row .row-arrow { transition: none; }
  .slot .slot-reel { transition: none; }
  .ring-badge svg { animation: none; }
  html.js .page-hub .showcase-img { clip-path: none; }
}

/* ============================================================
   Detailseiten · System-Faden v3.4 (2026-07-13) — additive Schicht
   Die 01–13-Nummernwelt des Leistungs-Hubs läuft auf den Detail-
   seiten weiter: das Eyebrow wird zum verlinkten Rückweg ins
   Hub-Kapitel (mit Outline-Index), nach dem Finale führt ein
   ruhiges Vor/Zurück-Band durch die Reihe. Gescoped auf
   body.page-detail — alle anderen Seiten unberührt.
   ============================================================ */

/* Eyebrow als Rückweg: Outline-Index + Kapitelname, verlinkt */
.page-detail a.eyebrow { text-decoration: none; transition: color 0.35s; }
.page-detail a.eyebrow:hover,
.page-detail a.eyebrow:focus-visible { color: var(--color-accent); }
.eyebrow-num {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.6em;
  letter-spacing: 0.02em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.45);
  transition: color 0.35s, -webkit-text-stroke-color 0.35s;
}
.page-detail a.eyebrow:hover .eyebrow-num,
.page-detail a.eyebrow:focus-visible .eyebrow-num { color: var(--color-accent); -webkit-text-stroke-color: var(--color-accent); }

/* Vor/Zurück in der Reihe — helles Zwischenband nach dem dunklen Finale */
.detail-nextnav { background: var(--color-surface); border-top: 1px solid var(--color-line-soft); }
.nextnav-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(16px, 3vw, 40px);
  padding-block: clamp(30px, 4vw, 48px);
}
/* Press-Feedback beim Klick (F1/F2, feinschliff-pilot 2026-08-13, [EMIL 3+4]):
   scale statt Verschiebung, zieht die Beschriftung mit und liest als Druck. */
.nextnav-item { display: inline-flex; align-items: center; gap: 16px; text-decoration: none; min-height: 44px; transition: transform 160ms var(--ease-out); }
.nextnav-item:active { transform: scale(0.985); }
.nextnav-item.prev { justify-self: start; }
.nextnav-item.next { justify-self: end; text-align: right; }
.nextnav-item.is-empty { visibility: hidden; }
.nextnav-item.all {
  justify-self: center;
  font-size: var(--text-caption);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-soft);
  padding: 12px 20px;
  border: 1px solid var(--color-line);
  border-radius: 999px;
  transition: color 0.35s, border-color 0.35s, background-color 0.35s;
}
.nextnav-item.all:hover,
.nextnav-item.all:focus-visible { color: var(--color-on-accent); background: var(--color-accent); border-color: var(--color-accent); }
.nn-body { display: flex; align-items: baseline; gap: 12px; }
.nextnav-item.next .nn-body { flex-direction: row-reverse; }
.nn-num {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.95rem;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.4);
  transition: color 0.4s, -webkit-text-stroke-color 0.4s, transform 0.45s var(--ease-out);
}
.nn-name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(1.05rem, 1.8vw, 1.35rem);
  line-height: 1.2;
  color: var(--color-accent);
  transition: transform 0.45s var(--ease-out);
}
.nn-arrow { color: var(--color-accent); font-size: 1.05rem; transition: transform 0.45s var(--ease-spring); }
/* Zahl war von der Verschiebung ausgenommen — Name+Pfeil rutschten,
   die Zahl blieb stehen, die Zeile fiel beim Hover sichtbar auseinander. */
.nextnav-item.prev:hover .nn-name, .nextnav-item.prev:hover .nn-num, .nextnav-item.prev:focus-visible .nn-name, .nextnav-item.prev:focus-visible .nn-num { transform: translateX(-8px); }
.nextnav-item.next:hover .nn-name, .nextnav-item.next:hover .nn-num, .nextnav-item.next:focus-visible .nn-name, .nextnav-item.next:focus-visible .nn-num { transform: translateX(8px); }
.nextnav-item.prev:hover .nn-arrow { transform: translateX(-6px); }
.nextnav-item.next:hover .nn-arrow { transform: translateX(6px); }
.nextnav-item:hover .nn-num,
.nextnav-item:focus-visible .nn-num { color: var(--color-accent); -webkit-text-stroke-color: var(--color-accent); }
/* Mobil: Vor/Zurück nebeneinander, „Alle Leistungen" darunter — Nummern bleiben (roter Faden) */
@media (max-width: 720px) {
  .nextnav-grid { grid-template-columns: 1fr 1fr; }
  .nextnav-item.all { grid-column: 1 / -1; order: 3; }
  .nn-name { font-size: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .nn-name, .nn-arrow, .eyebrow-num, .nn-num { transition: none; }
}

/* ---------- Gestufte Leistungsseite: Vertiefungsblock + Vergleichs-Kacheln (v3.5, Pilot Veneers) ---------- */
/* Der Vertiefungsblock erbt die FAQ-Akkordeon-Optik (.faq), traegt aber breite Inhalte.
   HARTE AUFLAGE: Der Inhalt steht IMMER vollstaendig im ausgelieferten HTML —
   <details> klappt nur visuell ein, nie per JavaScript nachladen (seo-strategie.md 4.7). */
.deepdive details > div { max-width: none; padding-bottom: var(--space-m); }
.deepdive details > div > p { max-width: 72ch; }
.deepdive-lead { margin-bottom: var(--space-s); }

/* Vergleichs-Kacheln: reine Informationsflaechen, keine Links — deshalb kein Hover-Lift,
   sonst liest sich die Kachel als klickbar.
   Bewusst OHNE Rangfolge-Signale (keine Index-Ziffer, keine hervorgehobene Kachel):
   Der Praeparationsgrad ist fachlich kein Qualitaetsgefaelle — das Layout darf das nicht behaupten. */
.card-static { gap: 6px; }
.card-static:hover { transform: none; border-color: var(--color-line-soft); box-shadow: none; }
.card-static h3 { font-size: 1.1rem; margin-bottom: 0; }
.card-static .tile-role { font-size: var(--text-caption); color: var(--color-text-soft); margin: 0 0 10px; }
/* R2-B, feinschliff-pilot 2026-08-13: [MESS] Abstand Label->Wert 2px, Gruppe->
   Gruppe 9px — die drei Paare banden schon zu einem Block. Auf 20px gezogen,
   damit die Gruppen selbst sich trennen ("tight groups, generous separation").
   Das Label war zudem kleiner UND heller als sein Wert — bleibt klein/Versalien,
   bekommt aber die Akzentfarbe, damit es die Zeile anfuehrt statt untertitelt. */
.tile-spec { margin: 0; display: grid; gap: 20px; }
.tile-spec dt { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent-80); font-weight: 600; }
.tile-spec dd { margin: 3px 0 0; font-size: 0.94rem; line-height: 1.45; }
/* Begleitsatz unter der Statement-Zeile bzw. ueber dem CTA: ruhiger als die Hauptzeile,
   in der Breite begrenzt, damit er auf dem dunklen Band nicht als zweite Headline liest. */
.outcome .container-narrow > p:not(.statement-line),
.cta-band p {
  max-width: 62ch;
  margin-inline: auto;
  margin-top: var(--space-s);
  font-size: 1rem;
  color: rgba(255, 255, 255, 0.86);
}
/* Absaetze direkt unter der Prozess-Box — abgesetzt, damit sie nicht als sechster Schritt lesen. */
.panel-after { margin-top: var(--space-m); }
.panel-after p + p { margin-top: var(--space-s); }


/* ============================================================
   DETAILSEITEN-VORLAGE — ueberfuehrt aus feinschliff-pilot.css,
   Etappe 3 des Detailseiten-Rollouts, 2026-08-17.
   Quelle und Belege: rollout-spec-detailseiten.md, Etappen 1-2;
   .temp/meisterklasse/2026-08-16-detailseiten-rollout.md.
   Gebaut am Piloten (leistungen-veneers-pilot.html), bewiesen am
   zweiten, maximal ungueltigen Fall (leistungen-kinderzahnheilkunde.html).

   NACHTRAG, noch am 2026-08-17 im Regressionscheck gefunden: Alles hier
   war urspruenglich unter `.page-detail` allein gefasst — das reichte
   in feinschliff-pilot.css, weil nur die zwei gebauten Seiten die Datei
   ueberhaupt LADEN. Als eigener Block in style.css greift `.page-detail`
   dagegen auf ALLEN 19 Seiten mit dieser Body-Klasse, auch den elf noch
   nicht umgebauten Detailseiten UND der als Gegenprobe unberuehrt zu
   haltenden `leistungen-veneers.html` — deren Kopf lief schon dunkel,
   ihr Zitatband schon riesig, ihre Bogen-Bilder schon umskaliert, bevor
   das hier repariert wurde. Zusaetzliches Body-Flag `.is-built` auf den
   zwei tatsaechlich umgebauten Seiten macht die alte Datei-Lade-Grenze
   als Klasse explizit nach. Nur Regeln, die auf bereits eindeutig neuen,
   im Bestand ungenutzten Klassennamen sitzen (.term-band, .cta-mid,
   .reason-list, .section-costs/-alternatives/-ways) waeren fuer sich
   harmlos gewesen — trotzdem einheitlich mitgegated, damit dieser
   Block als Ganzes eine klare Bedingung traegt statt zwei Klassen von
   Selektoren zu mischen. */
.page-detail.is-built section:not(.outcome) > .container-narrow > *,
.page-detail.is-built .ways-text > p,
.page-detail.is-built .section-alternatives > .container > p,
.page-detail.is-built .section-qa .faq details > div > p,
.page-detail.is-built .section-qa .faq details > div > ul {
  max-width: 78ch;
}
/* `.container-narrow` hoert auf zu zentrieren — die linke Kante liegt auf
   132px wie ueberall sonst. Ausdruecklich NICHT fuer `.outcome`: die teilt
   sich mit `.cta-band` eine gemeinsame, bewusst zentrierte Buehnenflaeche. */
.page-detail.is-built section:not(.outcome) > .container-narrow {
  max-width: var(--container-max);
}
.page-detail.is-built .ways-text > p + p { margin-top: var(--space-s); }
/* Frageblock einspaltig auf voller Containerbreite (R12-A). ZWEI Anlaeufe
   noetig: "dieselbe Breite wie der Titel" meinte den Split als Ganzes
   (Text+Bild = Containerbreite), nicht nur die Kopf-Textspalte. */
.page-detail.is-built .section-qa .container > h2,
.page-detail.is-built .section-qa .container > .faq {
  max-width: none;
}
.page-detail.is-built .section-qa .faq details > div { max-width: none; }
.page-detail.is-built .section-alternatives > .container > .alt-close { margin-top: var(--space-l); }

/* ---- Ablaufbox: Mittelpuls-Zeile (R8-A, 2026-08-15) ----
   CTA-Block zwischen Kopf und Finale, IST `.hero-cta` — dasselbe Bauteil,
   keine Sonderform. Zeile bekommt Luft nach oben (space-l trennt sie vom
   Vorherigen), Block klebt eng an ihr (space-xs) — tight group, generous
   separation zur Nachbarschaft. */
.page-detail.is-built .cta-mid-line {
  font-size: var(--text-lead);
  margin-top: var(--space-l);
  margin-bottom: 0;
}
.page-detail.is-built .cta-mid { margin-top: var(--space-xs); }
.page-detail.is-built .reason-list > li { margin-bottom: var(--space-xs); }
.page-detail.is-built .reason-list > li:last-child { margin-bottom: 0; }

/* ---- Kosten/Alternativen-Feld (R2-C/R9, 2026-08-15/16) ----
   Farbfolge: dunkle Aufloesung -> Beige (Kosten) -> hell (Alternativen) ->
   Beige (Zitat) -> hell (Vertiefung). Zwei Beige-Flaechen, nie zwei
   nebeneinander — nach JEDER Sektions-Umstellung neu ablesen, nicht als
   an einer Sektion haengende Regel fuer gesetzt halten (pruef-seite.mjs
   Abschnitt 4 misst das je Seite). */
.page-detail.is-built .section-costs { background: var(--color-panel-softer); }
.page-detail.is-built .section-alternatives .card-static > p:last-child { margin-bottom: 0; }
.page-detail.is-built .section-alternatives .card-static .tile-role { margin-bottom: var(--space-xs); }
@media (min-width: 901px) {
  .page-detail.is-built .section-alternatives .card-grid.grid-3 { grid-template-rows: auto auto auto; }
  .page-detail.is-built .section-alternatives .card-grid.grid-3 > .card-static {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
    row-gap: 0;
  }
}

/* ---- Begriffsband (R6-A/R7, 2026-08-15/16) ----
   Uebersetzt die Wirkung des Startseiten-Laufbands (Schwelle, kein Inhalt)
   auf die Detailseite: dasselbe Material wie `.quote-band` an der zweiten
   Schwelle. Traegt nur zwei Metadaten — wo man ist, wie die Sache sonst
   heisst — keine Definition (die steht im Kopf). */
.page-detail.is-built .term-band {
  background: var(--color-surface);
  border-block: 1px solid var(--color-line-soft);
  padding-block: clamp(26px, 3vw, 40px);
  text-align: center;
}
.page-detail.is-built .term-label { margin-bottom: clamp(14px, 1.6vw, 20px); }
/* Haarlinie hinter dem Label 2026-08-20 entfernt statt zentriert - Rest einer
   frueheren Vorher/Nachher-Strich-Fassung; ohne die Nachher gehoerte gestrichene
   Gegenseite haengt sie sich ohne display:block direkt an den Text und liest
   sich wie ein Bindestrich (Daniel: "Ueberbleibsel von damals"). Deckt sich mit
   der KI-Tell-Bereinigung vom 19.08. (Zeile ~127), die die Eyebrow-Haarlinie
   sitewide entfernt hatte - dieser Selektor war damals kein `.eyebrow`, ist
   dem entgangen. */
/* Outline-Schrift wie `.eyebrow-num`/`.hub-ghost`. [MESS] Strichdeckkraft
   0.5 mass 2,67:1 gegen Weiss (unter 3:1 fuer Grosstext) — auf 0.62 gehoben,
   3,42:1. Die Ghost-ZIFFERN duerfen niedriger, sie sind aria-hidden Dekor;
   diese Woerter sind Inhalt und werden gelesen. */
.page-detail.is-built .term-words {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  row-gap: 0.15em;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--text-h2);
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.62);
  margin-bottom: 0;
}
.page-detail.is-built .term-words span { hyphens: auto; overflow-wrap: break-word; max-width: 100%; }
.page-detail.is-built .term-words span:not(:last-child)::after {
  content: "·";
  color: var(--color-accent-80);
  -webkit-text-stroke: 0;
  margin-inline: 0.5em;
}
@media (max-width: 720px) {
  .page-detail.is-built .term-words {
    flex-direction: column;
    align-items: center;
    line-height: 1.2;
    row-gap: 0.05em;
  }
  .page-detail.is-built .term-words span:not(:last-child)::after { content: none; }
}

/* ---- Detail-Kopf (Etappe 1, Gate 1/2 2026-08-16) ----
   Nicht bildgetragen (13 Seiten waeren eine Fotoseite, Leseseite ist keine
   Buehne, das Bogen-Motiv ist Marken-Kern) — typogetragen, Massstab und
   Schichtung sind die brachen Dimensionen. Dunkler Grund wie im
   Startseiten-Hero seit v3.6 (Dark Teal ist tragende Farbe, keine neue). */
.page-detail.is-built .page-hero { background: var(--color-accent-deep); }
.page-detail.is-built .page-hero::before { display: none; }
/* 54,4px -> 78,4px bei 1440. Bewusst UNTER dem Buehnen-Hero (83px) und UEBER
   dem Hub-Kapiteltitel (62px) — Hierarchie in beide Richtungen. Zeilenhoehe
   1,06 stammt aus der ersten Rollout-Runde (R6-B) und ist von hier nicht
   neu gesetzt worden, gilt unveraendert weiter. */
.page-detail.is-built .page-hero h1 {
  font-size: clamp(2.6rem, 5.6vw, 4.9rem);
  line-height: 1.06;
  overflow-wrap: break-word;
  hyphens: manual;
  color: var(--color-on-accent);
}
@media (min-width: 901px) {
  /* 1fr/1fr = 545px je Spalte. "Kinderzahnheilkunde" braucht bei 78px rund
     832px ungetrennt, mit weicher Trennung an der Wortfuge ~570px. 7fr/5fr
     gibt 636px — passt mit Reserve, das Bogen-Bild verliert nur 91px. */
  .page-detail.is-built .page-hero .split { grid-template-columns: 7fr 5fr; }
  /* Ohne diese Zeile bricht kein Titel, egal wie viele weiche Trennstellen im
     Markup stehen: Grid-Items tragen min-width:auto, die Spur waechst auf
     max-content und wird nie schmaler als das laengste Wort. */
  .page-detail.is-built .page-hero .split > * { min-width: 0; }
}
.page-detail.is-built .page-hero .subline { color: var(--color-panel); }
.page-detail.is-built .page-hero .page-hero-text > p { color: rgba(255, 255, 255, 0.78); }
.page-detail.is-built .page-hero .eyebrow { color: rgba(255, 255, 255, 0.72); }
.page-detail.is-built .page-hero .eyebrow-num { color: var(--color-panel); }
.page-detail.is-built .page-hero .eyebrow::before { background: rgba(255, 255, 255, 0.4); }
/* Der site-weite Hover (Zeile ~2078) zielt auf --color-accent — auf hellem
   Grund ein Hervorheben, auf diesem dunklen Hero fast derselbe Ton wie der
   Grund selbst (--color-accent-deep). Hier auf Weiss angehoben, damit Hover
   heller statt fast unsichtbar wird (Daniel, 2026-08-17). */
.page-detail.is-built .page-hero .eyebrow:hover,
.page-detail.is-built .page-hero .eyebrow:focus-visible { color: var(--color-on-accent); }
.page-detail.is-built .page-hero .eyebrow:hover .eyebrow-num,
.page-detail.is-built .page-hero .eyebrow:focus-visible .eyebrow-num { color: var(--color-on-accent); -webkit-text-stroke-color: var(--color-on-accent); }
.page-detail.is-built .page-hero .hero-phone { color: #fff; border-bottom-color: rgba(255, 255, 255, 0.5); }
.page-detail.is-built .page-hero .btn-primary { background: var(--color-on-accent); color: var(--color-accent); }
.page-detail.is-built .page-hero .btn-primary:hover { background: var(--color-bg); color: var(--color-accent-deep); }
.page-detail.is-built .page-hero .arch-pill { background: var(--color-on-accent); color: var(--color-accent-deep); }
/* Echo-Bogen: `.arch-frame::before` traegt eine dunkle Haarlinie, die auf
   hellem Grund den Bogen zeichnet und auf dunklem Grund verschwindet — nur
   im Bild aufgefallen, von keiner Messung gemeldet. Ohne sie liest das Foto
   als abgerundete Flaeche statt als Bogen, und der Bogen war das
   Hauptargument gegen ein Vollflaechen-Foto. */
.page-detail.is-built .page-hero .arch-frame::before { border-color: rgba(255, 255, 255, 0.26); }
/* Der Schlagschatten des Bogens ist teal auf teal und damit wirkungslos —
   wird zur schmalen hellen Kante, dieselbe Aufgabe, anderer Wert. */
.page-detail.is-built .page-hero .arch-frame .arch-img {
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14), 0 40px 80px -40px rgba(0, 0, 0, 0.55);
}

/* ---- Auflösung: Verlauf statt Vorhang (D11, Etappe 1b) ----
   `.outcome.has-image` trug ein randloses Vollbild unter einem
   GLEICHMAESSIGEN Schleier — las als Farbband mit Textur, nicht als Foto.
   Verlauf oeffnet nach aussen (Text zentriert, 26ch): dichte Platte in der
   Mitte, Ecken zeigen das Bild. Boden statt Messung: hinter dem Text liegt
   garantiert >=0,80 Deckung Dark Teal — selbst bei reinweissem Foto ergibt
   das >8:1 gegen weisse Schrift, noetig 3:1. Der Kontrast haengt damit NICHT
   am Motiv, alle Bilder sind heute Platzhalter. Die dichte Zone ist an der
   breitesten Textzeile bemessen (Fliesstext), nicht an der Schlagzeile —
   die ist am auffaelligsten und am unkritischsten. */
.page-detail.is-built .outcome.has-image::after {
  background:
    radial-gradient(ellipse 78% 88% at 50% 50%,
      rgba(0, 72, 96, 0.82) 0%,
      rgba(0, 72, 96, 0.80) 52%,
      rgba(0, 60, 80, 0.46) 80%,
      rgba(0, 48, 63, 0.18) 100%),
    linear-gradient(160deg, rgba(11, 76, 99, 0.16) 0%, rgba(0, 48, 63, 0.22) 100%);
}
/* Der Echo-Kreis (.outcome::before) bleibt unter .has-image abgeschaltet —
   auf einem sichtbaren Foto waere ein zweiter Kreis ein Gegenstand zu viel.
   Bewusst nicht eingeschaltet, hier notiert, damit es niemand als Versehen
   zurueckbaut. */
.page-detail.is-built .outcome.has-image::before { display: none; }

/* ---- Zitatband auf Detailseiten (F-Block, 2026-08-13/16) ----
   `.page-detail.is-built` davor, weil die Startseite dieselbe Klasse fuer
   die Patientenstimme nutzt — die bleibt unberuehrt, und die noch nicht
   umgebauten Detailseiten samt der Gegenprobe behalten ihr kleines Zitat.
   Traegt hier den SEKUNDAER-CLAIM der Praxis, nicht ein Zitat. Ohne
   Anfuehrungszeichen im Text — das Ghost-Zeichen im Hintergrund traegt
   die Geste allein. */
.page-detail.is-built .quote-band blockquote {
  font-size: clamp(2rem, 5.2vw, 4.6rem);
  line-height: 1.18;
}
.page-detail.is-built .quote-band { padding-block: clamp(120px, 29vh, 280px); }
/* Ghost-Anfuehrungszeichen haengt an top:-0.40em statt -0.18em — bei 73,6px
   Schrift auf einem 696px-Band liegt der alte Wert mitten in der ersten
   Zeile (ein absolut gesetztes Hintergrundelement haelt seinen Abstand zur
   Sektionskante, nicht zum Text; wer den Text vergroessert, schiebt ihn
   unter das Element). */
.page-detail.is-built .quote-band::before { top: -0.40em; }

/* ---- Bogen-Bilder Kopf und Rumpf (R6-C, 2026-08-15) ----
   Kopf- und Rumpfbild waren auf 420x520 exakt dasselbe Bauteil, nur
   gespiegelt. Korrigiert ueber die GROESSE, nicht die Form: Hochformat 0.81
   bleibt auf beiden erhalten (460/570=0.807, 380/470=0.809), das
   Deckblatt-Bild ist 1,21x groesser — Rangfolge statt Zwillinge. BINDEND
   fuer den Rollout (§0 Fussnote 3): kein zweiter Anlauf am Verhaeltnis 0,81. */
@media (min-width: 901px) {
  .page-detail.is-built .arch-frame { width: min(100%, 380px); justify-self: center; }
  .page-detail.is-built .arch-frame .arch-img,
  .page-detail.is-built .media-split .arch-frame .arch-img { min-height: 470px; }
  .page-detail.is-built .page-hero .arch-frame { width: min(100%, 460px); }
  .page-detail.is-built .page-hero .arch-frame .arch-img { min-height: 570px; }
}

/* ---- Veneers-spezifisch: "Die vier Wege" (R2-B zweiter Teil, 2026-08-13) ----
   NICHT Serien-Vorlage — vier Material-Optionen sind Veneers-exklusiver
   Inhalt, keine andere Detailseite hat diesen Abschnitt. Subgrid bindet
   Haken/Rolle/Merkmale ueber alle vier Kacheln auf dieselbe Zeilenhoehe. */
@media (min-width: 901px) {
  .page-detail.is-built .section-ways .card-grid.grid-4 { grid-template-rows: auto auto auto auto auto; }
  .page-detail.is-built .section-ways .card-grid.grid-4 > .card-static {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 5;
    row-gap: 0;
  }
  .page-detail.is-built .section-ways .card-static .tile-spec {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
    row-gap: 0;
  }
  .page-detail.is-built .section-ways .card-static .tile-spec > div { padding-top: 20px; }
  .page-detail.is-built .section-ways .card-static .tile-spec > div:first-child { padding-top: 0; }
}

/* UEBERFUEHRT 2026-08-16 - Flaechen-Sprung (F1-F5.3b, .page-home) und Hub-Verzeichnis (F6.1-F6.8, .page-hub). Ehemals flaechen-experiment.css und hub-experiment.css, Reihenfolge unveraendert. Etappe 0 des Detailseiten-Rollouts, siehe rollout-spec-detailseiten.md Paragraf 10. */

/* ============================================================
   Flächen-Experiment · 2026-08-16
   NUR von index-flaechen.html geladen. style.css bleibt unberührt,
   index.html bleibt Vergleichsgrundlage — dieselbe Bauweise wie beim
   Veneers-Piloten (rollout-spec §6).

   Anlass — Daniel, 16.08.: „Wir haben ja auf der Startseite ein Bild,
   das so bisschen in die Richtung Full Bleed geht … aber das ist so
   schmal gehalten und so klein, dass es nicht wirklich trägt."

   Gemessener Ausgangsbefund (mess-bildflaeche.mjs, 1440×900):
   Showcase-Bild 1440×320px. Seitenverhältnis 4,5:1.
   Die tragenden Flächen der Referenzseiten: 900–1350px hoch
   (die-praxis 1440×900 · heart 1440×1139 · getblue 1440×1280).
   ============================================================ */

/* ------------------------------------------------------------
   F1 · Die Ursache: eine Kollision, keine Gestaltungsentscheidung.

   Vom Browser bestätigt (check-regel.mjs .showcase-img min-height
   index.html):

     .showcase-img  →  min-height: clamp(360px, 68vh, 640px)   (Zeile 618)
     .ph            →  min-height: 320px                        (Zeile 820)
     computed       →  320px

   Beide Selektoren haben Spezifität (0,1,0). `.ph` steht 202 Zeilen
   später und gewinnt deshalb. Das Showcase-Bild war also von Anfang an
   auf bis zu 640px ausgelegt und ist seit dem Bau still auf die Hälfte
   gedeckelt. Der Entwurf war nie das Problem.

   Geprüft, ob das systematisch ist: Alle 17 min-height-Deklarationen in
   style.css durchgegangen. `.showcase-img` ist der EINZIGE Fall — alle
   anderen stehen entweder nach Zeile 820 (.ph-tall, .ph-wide, .room-grid
   .ph) oder haben höhere Spezifität (.hero-media .arch-img, .arch-frame
   .arch-img). Ein Einzelfall, kein Muster.

   Reparatur bewusst NICHT über `!important` und nicht durch Verschieben
   von `.ph` — beides würde 19 Seiten treffen. Hier reicht die höhere
   Spezifität über die Seitenklasse.
   ------------------------------------------------------------ */

/* ------------------------------------------------------------
   F2 · Die Fläche trägt erst ab einer Höhe.

   Arbeitsregel aus dem Referenzvergleich:
   Eine tragende Fläche ist mindestens 70 % der Fensterhöhe.
   Darunter ist sie ein Band und zählt nicht als Bildmoment.

   Hier bewusst 86vh statt der ursprünglich gemeinten 68vh:
   68vh (= 612px bei 900px Fenster) repariert nur die Kollision und
   landet exakt auf der Schwelle. 86vh (= 774px) liegt im Bereich der
   Referenzen und lässt unten trotzdem einen Streifen der nächsten
   Sektion stehen — die Orientierung beim Scrollen bleibt erhalten,
   anders als bei einer 100vh-Fläche, die den Anschluss verdeckt.

   Der Deckel bei 900px verhindert, dass die Fläche auf sehr hohen
   Fenstern ins Absurde wächst; die Untergrenze 480px hält sie auf
   kleinen Fenstern über der Bandgrenze.
   ------------------------------------------------------------ */
.page-home .showcase-img {
  min-height: clamp(480px, 86vh, 900px);
}

/* ============================================================
   F4 · DER SPRUNG — Schichtung statt Sequenz
   ============================================================

   Daniel, 16.08.: „gefühlt geht da noch mehr … wir brauchen noch mal
   genau denselben Sprung wie v1 auf v2 … ich suche die boldness im
   Ausdruck, nicht in den UI-UX-Elementen."

   Der Skill sagt für genau diesen Moment: „Zu brav / mehr Mut heißt nie
   dasselbe lauter. Es heißt: eine Dimension öffnen, die der Entwurf noch
   gar nicht bespielt." F1–F3 waren dasselbe lauter — ein Element größer.
   Deshalb reichte es nicht.

   Welche Dimension liegt brach? Gemessen (mess-dynamik.mjs, zeig-baender.mjs):
   - Die Bänder sind NICHT gleich groß (Spanne 12,8x) — Hypothese widerlegt.
   - Der Hero ist mit 820px NICHT zu klein — das ist 100vh minus Header.
   - Nur drei Bänder liegen wirklich unter einem Bildschirm.
   Padding auf drei Sektionen wäre also wieder nur „lauter".

   Was die Seite dagegen NIE tut: etwas übereinanderlegen. Der gesamte
   Aufbau ist strikt sequenziell — Band, Band, Band. Text steht immer
   NEBEN dem Bild, nie DARAUF. Die einzige Ausnahme auf 19 Seiten ist die
   5,0-Karte am Showcase.

   Die Referenzen tun durchgehend das Gegenteil: die-praxis legt die Marke
   auf ein bildschirmfüllendes Foto, heart und getblue setzen Text in die
   Fläche. Deshalb wirken sie großflächig — nicht weil ihre Bilder größer
   sind, sondern weil die Fläche BEWOHNT ist.

   Signatur-Treue (Prinzip „Signatur aus dem eigenen Material"): Die
   Überlappung ist kein Import, sie ist Signatur-Element #6 des eigenen
   Guides („Elemente dürfen Sektionsgrenzen brechen"). Sie existierte
   bisher nur als Detail (Badge, Karte) — hier wird sie zum Bauprinzip
   der Sektion. Kein neues Element, ein vorhandenes ernst genommen.

   Gebunden geblieben: keine neue Farbe (Dark Teal + Weiß sind gesetzt),
   kein Textwort geändert, keine Markup-Änderung, KEINE neue Bewegung
   (R8-Obergrenze unberührt). Der Mut liegt ausschließlich in Fläche,
   Maßstab und Schichtung.
   ------------------------------------------------------------ */

/* F4.1 · Dunkler Grund ZUERST.
   Die Intro-Choreografie startet `.hero-media` auf opacity 0
   (style.css:1030). Ohne dunklen Grund stünde die weiße Schrift in der
   ersten halben Sekunde — und ohne JS dauerhaft — unsichtbar auf Hell.
   Der Grund ist die Absicherung, nicht die Dekoration. */
.page-home .hero {
  background: var(--color-accent-deep);
  color: var(--color-on-accent);
}

/* F4.2 · Die Beige-Aura entfällt.
   Sie ist die Dekoration eines hellen Heros und würde als milchiger
   Fleck über dem Foto liegen. */
.page-home .hero::before { display: none; }

/* F4.3 · Das Foto wird die Fläche, nicht die Beilage.
   Vorher: 454x504px in der rechten Spalte = 18 % der Fensterfläche.
   Nachher: die gesamte Herofläche. */
/* `.hero-inner` trägt in style.css:298 ein `position: relative`. Solange das
   steht, bezieht sich `inset: 0` unten auf den CONTAINER (1176px, mittig,
   Höhe = Inhaltshöhe) statt auf den Hero — das Foto sitzt dann eingerückt und
   liegt zugleich ÜBER dem Schleier, weil es im z-index-2-Kontext des Containers
   steckt. Genau so war der erste Schuss: Foto eingerückt, Schleier weg, weiße
   Schrift unsichtbar auf hellem Foto. Der Bezugsrahmen wird deshalb aufgelöst;
   die Textspalte bekommt ihre Stapelposition stattdessen selbst (F4.5). */
.page-home .hero-inner { position: static; }

.page-home .hero-media {
  position: absolute;
  inset: 0;
  margin: 0;
  z-index: 0;
}
.page-home .hero-media::before { display: none; }   /* Echo-Bogen ergibt auf Vollfläche keinen Sinn */
.page-home .hero-media .arch-img {
  border-radius: 0;
  min-height: 100%;
  height: 100%;
  box-shadow: none;
}
.page-home .hero-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* F4.4 · Der Schleier ist ein Verlauf, kein Vorhang.
   Lehre aus der `.outcome`-Sektion: ein flächiger 86-%-Scrim macht aus
   dem Foto eine Textur und verschenkt die Fläche. Hier trägt die linke
   Seite den Text (kräftig), die rechte bleibt Foto (fast frei).

   Der Schleier hängt an `.hero-media`, NICHT an `.hero`. Grund: `.hero-media`
   ist mit `z-index: 0` ein eigener Stapelkontext — ein Schleier auf `.hero`
   (z-index 1) läge zwar über dem Foto, aber auch über der 5,0-Karte und der
   Öffnungs-Pille, die beide im Markup INNERHALB von `.hero-media` stehen.
   Genau so war es im zweiten Schuss: beide milchig überzogen und unlesbar.
   Innerhalb von `.hero-media` lässt sich die Karte dagegen sauber über den
   Schleier heben (F4.9). */
.page-home .hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(100deg,
      rgba(0, 48, 63, 0.96) 0%,
      rgba(0, 48, 63, 0.93) 40%,
      rgba(0, 55, 75, 0.84) 52%,
      rgba(0, 72, 96, 0.34) 76%,
      rgba(0, 72, 96, 0.10) 100%),
    linear-gradient(to top, rgba(0, 48, 63, 0.45) 0%, transparent 38%);
}
/* Erste Fassung hatte den Wendepunkt bei 32 %/58 % — die Textspalte endet aber
   bei 47 % (680px von 1440px), dort lag der Schleier nur noch bei rund 0,63.
   Über einem sehr hellen Praxisfoto ergab das gemessene 1,74:1 für die
   Schlagzeile (nötig 3:1 für große Schrift). Der Deckungsbereich reicht jetzt
   bis 52 %, also über die ganze Textspalte; ab 76 % bleibt das Foto frei.
   Gemessen mit pruef-seite.mjs an echten Pixeln — der Endwert eines Verlaufs
   über einem Foto steht in keinem Stylesheet. */

/* F4.5 · Der Text zieht in die Fläche ein.
   Einspaltig statt 7fr/5fr — die zweite Spalte ist jetzt der Grund.
   Die Textbreite wird gedeckelt, damit die Zeile nicht über das ganze
   Foto läuft; rechts bleibt bewusst Bild stehen. */
.page-home .hero-inner {
  grid-template-columns: minmax(0, 1fr);
}
/* Die Stapelposition sitzt an der Textspalte, nicht am Container — sonst
   entstünde wieder der Bezugsrahmen, der F4.3 kaputtgemacht hat. */
.page-home .hero-inner > div:first-child {
  position: relative;
  z-index: 2;
  max-width: min(48vw, 680px);
}
/* `20ch` stand hier zuerst und war der zweite Fehler dieses Blocks: `ch`
   bezieht sich auf die Schriftgröße DES ELEMENTS, nicht auf die der
   Schlagzeile darin. Auf einem 1rem-Container sind 20ch rund 180px — die
   Schlagzeile lief über und wurde von der Intro-Maske (`.line`,
   `overflow: hidden`) zu „Ihr Zahr für" abgeschnitten. Lehre: `ch` nur dort,
   wo die Schriftgröße auch am selben Element steht. */
@media (max-width: 980px) { .page-home .hero-inner > div:first-child { max-width: none; } }

/* F4.6 · Maßstab: die Schlagzeile bekommt die Fläche, die sie jetzt hat.
   Vorher bis 4,2rem auf halber Breite. Auf voller Fläche darf sie
   größer — das ist Signatur #1 („die Headline darf die Bühne haben"),
   die auf der halben Spalte nie ausgereizt werden konnte. */
.page-home .hero h1 { font-size: clamp(2.6rem, 5.4vw, 5.2rem); }
/* 4,2rem → 5,2rem (+24 %). Nicht weiter: bei 6rem passt „Oststeinbek" nicht
   mehr neben das Foto, ohne die Spalte so breit zu machen, dass die Fläche
   wieder verdeckt ist. Gemessen, nicht geschätzt. */

/* F4.7 · Schriftfarben auf dunklem Grund.
   Keine neue Farbe — Weiß und die gesetzten Weiß-Transparenzen sind
   dieselben, die `.outcome` und `.cta-band` schon tragen. */
.page-home .hero h1,
.page-home .hero .hero-sub { color: var(--color-on-accent); }
/* Claim ist hier Signatur, kein Versprechen mehr (das übernimmt .hero-sub) —
   dieselbe gedämpfte Weiß-Transparenz wie .journey-intro p, keine neue Farbe. */
.page-home .hero .hero-claim { color: rgba(255, 255, 255, 0.75); }
/* Das kursive Rotationswort trägt hell dasselbe Beige, das `.outcome` seinem
   Playfair-Akzent auf Dark Teal schon gibt (style.css: `.outcome
   .statement-line em`). Keine neue Farbe, ein vorhandenes Paar. Semibold
   ergaenzt 2026-08-19 aus demselben Grund wie dort: gegen das kraeftige
   Weiss des restlichen H1 behauptet sich Regular-Gewicht nicht. */
.page-home .hero h1 .rotator { color: var(--color-panel); font-weight: 600; }
.page-home .hero h1 .h1-static { color: rgba(255, 255, 255, 0.82); }
.page-home .hero .eyebrow,
.page-home .hero .cta-hint { color: rgba(255, 255, 255, 0.72); }
.page-home .hero .hero-phone { color: #fff; border-bottom-color: rgba(255, 255, 255, 0.5); }

/* F4.8 · Der Haupt-Button wird invers.
   `.btn-primary` ist Dark Teal auf Dark Teal — unsichtbar. `.btn-inverse`
   (weiß auf Teal) ist die vorhandene CI-Lösung für dunklen Grund, sie
   trägt schon das CTA-Band. Nur die Optik wird geliehen, das Markup
   bleibt unangetastet. */
.page-home .hero .btn-primary { background: var(--color-on-accent); color: var(--color-accent); }
.page-home .hero .btn-primary:hover { background: var(--color-bg); color: var(--color-accent-deep); }

/* F4.9 · Die 5,0-Karte bleibt hell — sie IST die Schichtung.
   Eine helle Karte auf dunklem Foto ist der sichtbare Beweis des
   Prinzips. Sie wandert nach unten rechts, wo das Foto frei liegt. */
@media (min-width: 981px) {
  .page-home .hero-badge {
    left: auto;
    right: clamp(24px, 4vw, 72px);
    bottom: 64px;
    z-index: 2;              /* über den Schleier, siehe F4.4 */
    background: var(--color-surface);
  }
}
/* Die Öffnungs-Pille steht ebenfalls auf dunklem Grund und trug ihre
   Hell-Farben — dunkles Teal auf dunklem Teal, praktisch unlesbar. */
.page-home .hero .open-pill {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.28);
  color: #fff;
}
.page-home .hero .open-pill .pill-text { color: #fff; }
@media (max-width: 980px) {
  .page-home .hero-badge { position: static; margin-top: var(--space-m); display: inline-flex; }
}

/* F4.10 · Mobil trägt der Verlauf von unten, nicht von links.
   Auf 390px steht der Text über der vollen Breite; ein Seitenverlauf
   würde die rechte Hälfte der Zeile unlesbar machen. */
@media (max-width: 980px) {
  .page-home .hero::after {
    background: linear-gradient(to bottom,
      rgba(0, 48, 63, 0.80) 0%,
      rgba(0, 55, 75, 0.88) 55%,
      rgba(0, 48, 63, 0.95) 100%);
  }
}

/* ============================================================
   F5 · DER SATZ WIRD DIE FLÄCHE — Schichtung ohne Foto
   ============================================================

   Warum diese Sektion und warum als Nächstes: F4 hat Schichtung an einer
   FOTOfläche bewiesen. Wenn das Prinzip nur dort trägt, ist es ein
   Fototrick und gehört nicht als Bauprinzip in den Guide — dann hingen
   19 Seiten an Bildmaterial, das es noch gar nicht gibt (alles Stock).
   Diese Sektion hat kein Bild und bekommt keins. Sie ist der Beweis.

   Ausgangslage, gemessen (zeig-baender.mjs index-flaechen.html):
   613px = 0,68 Bildschirme. Damit liegt sie UNTER der eigenen Arbeitsregel
   („eine tragende Fläche ist mindestens 70 % der Fensterhöhe") — formal
   ein Band. Und sie trägt den Satz, der von allen am meisten behauptet.

   Zwei harte Randbedingungen, die den Lösungsraum vorab beschneiden:
   1. Sie darf NICHT dunkel werden — der Hero ist seit F4 dunkel, dazwischen
      liegt nur der 99px-Marquee. Zwei dunkle Töne in Folge ist genau der
      Defekt, den R3 behoben hat. Beige geht auch nicht: das Zitatband
      direkt danach ist beige. Farbe scheidet als Mittel damit aus.
   2. Die Oberkante bleibt unangetastet. Daniel hat von sich aus gelobt,
      wie sich der Absatz gegen das Wortbanner absetzt.

   Welche Dimension lag brach: Die Seite lässt NIE einen Textblock das
   visuelle Ereignis sein. Jede Sektion hat ein Bild oder ein Farbband, das
   die Arbeit macht; Text ist immer die Bildunterschrift. Die einzige
   Großtypografie ist die Ghost-Ziffer (26rem) — Dekoration HINTER dem
   Inhalt, nie der Inhalt selbst. Das ist die zweite Familie der Messtabelle:
   increase.com trägt mit 1,2 % Bildanteil und steht trotzdem auf Daniels
   Liste. Bold ohne Fotografie, über Maßstab und Fläche.

   VERWORFEN, weil an der Messung gescheitert: Der erste Entwurf wollte die
   Prosa in die Kerbe ziehen, die die kürzere zweite Zeile freilässt — wie
   die 5,0-Karte am Showcase. Nachgezählt: „Wir hören zu, bevor wir planen."
   hat 31 Zeichen, „Wir erklären, bevor wir handeln." hat 32. Es GIBT keine
   Kerbe, die beiden Zeilen sind gleich lang. Eine Schichtung dort
   hineinzukonstruieren wäre genau das „Verkünsteln", vor dem rollout-spec
   §2b nach drei verworfenen Anläufen warnt. Der Zug ist stattdessen
   Maßstabskontrast und Kantenbindung — die Mittel, die die typogetragene
   Familie tatsächlich benutzt.

   Gebunden geblieben: keine neue Farbe, keine neue Bewegung (`reveal` und
   `statement-fill` bleiben unangetastet, R8-Obergrenze unberührt), kein
   Textwort geändert, kein neues Bauteil, kein Full-Bleed (der Hero ist
   randlos; ein zweites randloses Band direkt danach nähme ihm den Auftritt).
   Einziger Markup-Eingriff: zwei zusätzliche <br>, begründet im HTML.
   ------------------------------------------------------------ */

/* F5.1 · Aus dem Band wird eine Fläche.
   Die Höhe kommt NICHT aus mehr Polsterung — das wäre „dasselbe lauter"
   und die widerlegte Hypothese aus F4. Sie kommt daher, dass der Satz
   den Raum tatsächlich einnimmt; die Mindesthöhe hält nur die Untergrenze.
   Die Polsterung wird deshalb sogar reduziert (xxl → xl), sonst käme die
   Sektion auf über 1,1 Bildschirme und würde den Hero überstimmen. */
.page-home .section:has(.statement-line) {
  min-height: clamp(560px, 80vh, 880px);
  padding-bottom: var(--space-xl);
}
/* Die OBERE Polsterung bleibt bei `--space-xxl` (160px bei 1440) — sie wird
   hier bewusst NICHT angefasst. Ein Zwischenstand hatte `padding-block:
   var(--space-l)` und damit auch oben auf 48px gekürzt; im Bild stand die
   Schlagzeile dann fast am Marquee und die Eyebrow-Zeile verschwand hinter dem
   klebenden Header. Genau der Abstand, den Daniel von sich aus gelobt hat
   („wie sich das gegeneinander absetzt und wirklich einen Strich darunter
   zieht"). Gekürzt wird nur unten, wo nichts daran hängt.
   Lehre: Wer eine Sektion höher macht, greift zuerst zur Polsterung — und
   fasst damit als Erstes die Naht an, die schon funktioniert hat. */
/* ZWEIMAL VERWORFEN, beide Male von der Messung überführt — hier notiert, damit
   es niemand ein drittes Mal versucht:

   Versuch 1: `display: grid; align-content: center`, um den Satz senkrecht zu
   zentrieren. Folge: Die implizite Spur sizet auf max-content, der Container
   schrumpfte von 1240px auf 993px (= breiteste Zeile + 2×32 Polsterung).
   Versuch 2: zusätzlich `grid-template-columns: minmax(0, 1fr)`. Half nicht —
   `.container` trägt `margin-inline: auto`, und auto-Margins schalten das
   Strecken eines Grid-Items ab. Der Container blieb fit-content, jetzt 1176px.
   `check-kanten.mjs` zeigte darauf: **linke Kante 164px statt 132px** — die
   Sektion stand als einzige der Seite neben der gemeinsamen Linie.

   Beide Male sah das Ergebnis im Bild wie eine ruhig zentrierte Sektion aus.
   Genau der 230px-Kantenversatz aus R11 in klein: eine Nebenwirkung des
   Layoutmodells, die keine senkrechte Einzelprüfung sucht.

   Die Auflösung ist die einfachste: kein eigenes Layoutmodell. Die Höhe kommt
   vom Satz selbst (gemessen 917px bei 1440), `min-height` ist nur ein Boden für
   sehr hohe Fenster. Damit verhält sich der Container wie in jeder anderen
   Sektion — und die senkrechte Zentrierung, für die das Grid da war, wird gar
   nicht gebraucht, weil der Inhalt die Fläche ohnehin ausfüllt. */

/* F5.2 · Die zweite Spalte war das Problem, nicht die Lösung.
   Vorher: 1fr/1fr — Behauptung links, Erklärung rechts, beide gleich
   schwer, beide mittelgroß. Genau die Gleichwertigkeit, die Daniel schon
   am Deckblatt der Detailseite als fehlende Abstufung benannt hat. */
@media (min-width: 901px) {
  .page-home .section:has(.statement-line) > .split {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--space-l);
  }
}

/* F5.3 · Der Maßstabssprung.
   46,4px → 131px (+182 %). Die Obergrenze ist GEMESSEN, nicht gewählt:
   die längste Zeile („bevor wir handeln.") muss in den 1176px-Innenraum
   des Containers passen, sonst bricht sie ein fünftes Mal und die
   vierzeilige Form zerfällt. Der erste Versuch mit 7,6vw ergab 109px und
   929px Zeilenbreite — 247px blieben ungenutzt, also war er noch zu brav.
   9,1vw füllt die Zeile auf rund 1110px und lässt 64px Luft.
   `max-width: 24ch` aus style.css:421 muss dafür weg — der Deckel war für
   eine halbe Spalte gedacht.
   line-height von 1,25 auf 1,04: bei dieser Größe ist der Zeilenabstand
   das, was den Block als FLÄCHE zusammenhält statt als vier Zeilen. */
.page-home .statement-line {
  max-width: none;
  font-size: clamp(2.2rem, 8.6vw, 7.8rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  margin-bottom: 0;
  text-wrap: wrap;
}
/* `text-wrap: balance` (style.css:423) muss hier aus: Es würde die vom
   Markup gesetzten Umbrüche gegen eigene, „ausgewogenere" austauschen und
   damit die Anapher zerreißen. Die Zeilen sind gesetzt, nicht berechnet.
   Bewusst `wrap` und nicht `nowrap`: Wenn der Font breiter rendert als
   gemessen, soll die Zeile umbrechen und nicht aus dem Fenster laufen.
   Ein Umbruch ist ein Schönheitsfehler, ein Überlauf ein Defekt. */

/* F5.3b · Der zweite Satz rückt ein — die Diagonale (Daniel, 16.08.).
   „dann ist optisch so eine Diagonale zu ‚Jede Behandlung beginnt damit…',
   das zeigt schon mal in die Richtung, dass es auch mitgenommen wird."
   Drei Haltepunkte auf einer Schräge: Satz 1 auf der Seitenkante (132px),
   Satz 2 eingerückt, die Anmerkung rechts unten. Der Blick bekommt eine
   Richtung statt zweier gestapelter Blöcke.

   Der Einzug ist NICHT frei wählbar — er wird von der längsten Zeile
   begrenzt. Gemessen: „bevor wir handeln." lief bei 9,1vw auf 1112px, im
   Container stehen 1176px. Ein Einzug von 95px hätte sie 30px über die
   rechte Kante geschoben. Deshalb geht der Maßstab um 5 % zurück
   (9,1vw → 8,6vw) und kauft damit den Platz für den Einzug frei.
   Ein sichtbarer Einzug ist hier mehr wert als 5 % Schriftgröße —
   die Fläche trägt auch bei 124px, die Diagonale gibt es nur so.

   `display: block` auf einem span: Der zweite Satz muss eine eigene
   Zeilenbox bekommen, ohne dass ein neues Element ins Markup kommt, das
   die Wort-Füllung (`site.js` wrapWords) anders behandeln würde — spans
   durchläuft sie, BR überspringt sie. */
.page-home .statement-line .satz-2 {
  display: block;
  padding-left: clamp(20px, 6.6vw, 96px);
}

/* F5.4 · Die Erklärung wird Anmerkung, nicht Gegenstück.
   Sie behält jedes Wort, verliert aber den Anspruch auf gleiche Fläche:
   kleiner, schmaler, an die rechte Kante gebunden — an dieselbe Kante,
   an der die längste Satzzeile endet. Zwei Größen, eine Kante: das ist
   der Kontrast, den die typogetragenen Referenzen benutzen, und der
   Ersatz für die Schichtung, die dieser Satz nicht hergibt. */
@media (min-width: 901px) {
  .page-home .section:has(.statement-line) > .split > div:last-child {
    max-width: 46ch;
    margin-left: auto;
    padding-top: var(--space-s);
    border-top: 1px solid var(--color-line-soft);
  }
  .page-home .section:has(.statement-line) .lead {
    font-size: 1.05rem;
    max-width: none;
    color: var(--color-accent-80);
  }
}
/* Der Haarstrich ist kein neues Bauteil: `--color-line-soft` trennt im
   System schon Karten und Klapp-Zeilen. Er markiert hier, dass die
   Anmerkung zum Satz gehört und nicht die nächste Sektion beginnt. */

/* F5.5 · Mobil bleibt die Sektion eine Leseflaeche.
   Bei 390px sind vier Zeilen à 18 Zeichen nicht darstellbar, ohne dass
   der Satz auf acht Zeilen zerfällt. Dort greift die untere Klammer des
   clamp (2,2rem), die Umbrüche des Markups bleiben und ergeben eine
   ruhige, vierzeilige Strophe. Die Mindesthöhe entfällt — eine erzwungene
   Fläche auf einem hohen, schmalen Fenster ist nur Leere. */
@media (max-width: 900px) {
  .page-home .section:has(.statement-line) { min-height: 0; }
  .page-home .statement-line { letter-spacing: -0.02em; line-height: 1.1; }
}

/* ------------------------------------------------------------
   F3 · Die Statement-Karte bleibt, wo sie war.

   Sie hängt mit `bottom: -64px` an der Unterkante des Bildes und
   wandert mit der Fläche automatisch mit — kein Eingriff nötig.
   Bewusst hier notiert, weil „mitgewandert, also unverändert lassen"
   sonst wie ein vergessener Posten aussieht.

   Ebenfalls unverändert: die Entfaltung aus dem Bogen (`--exp`,
   style.css:1176). Sie clippt seitlich und rundet die oberen Ecken,
   arbeitet also relativ zur Elementhöhe. Auf der größeren Fläche wird
   die Bewegung stärker — das ist der Zweck, keine Nebenwirkung, und
   es kommt KEINE Bewegung hinzu (R8-Obergrenze unberührt).
   ------------------------------------------------------------ */


/* ============================================================
   Flächen-Experiment F6 · Leistungs-Hub · 2026-08-16
   NUR von leistungen-flaechen.html geladen. style.css bleibt unberührt,
   leistungen.html bleibt Vergleichsgrundlage — dieselbe Bauweise wie
   beim Veneers-Piloten (rollout-spec §6) und wie F1–F5 auf der Startseite.

   Gemessener Ausgangsbefund (mess-hub.mjs, 1440×900):

     Kapitel      Zeilen   Sektion     Index-Zeilen   Breite   Luft darunter
     vorsorge       4      1440×941      636×733       44 %        76px
     aesthetik      3      1440×877      636×582       44 %       163px
     zahnersatz     2      1440×854      636×334       44 %       388px
     schienen       4      1440×929      636×647       44 %       149px

   Die eine Zahl: 44 %. Die 13 Leistungen — der einzige Grund, warum diese
   Seite existiert — leben in 44 Prozent der Seitenbreite. Die anderen 56 %
   sind eine sticky Beschriftungsspalte mit einem 340px-Stockfoto.
   Die Höhe fehlt nicht (0,95–1,05 Bildschirme). Die Fläche ist unbesetzt.

   Typo-Decke der Seite, gemessen: page-hero h1 = 83,2px, hub-ghost = 384px.
   Alles hier bleibt darunter — der Hero behält seinen Rang. Das ist der
   Merksatz aus v3.6: bei zwei konkurrierenden Flächen zuerst die Reihenfolge
   und den Rang prüfen, dann erst den Maßstab.

   Gebunden und deshalb hier NICHT angefasst: Farben, Fonts, Claims, Anrede,
   freigegebene Texte, WCAG-Kontraste — und Bewegung. Es kommt keine hinzu.
   ============================================================ */

/* ------------------------------------------------------------
   F6.1 · Das Kapitel wird eine Bühne statt zweier Spalten.

   Heute: grid-template-columns 5fr 7fr, 110px Rinne, kein Überlappen,
   nirgends. Das ist die reinste Form von "Text steht NEBEN der Fläche" —
   genau das Bauprinzip, das v3.6 abgelöst hat.

   Was mit dem freigegebenen Element v3.3 #15 passiert: Der Punkt von #15
   war "Kapitel-Dramaturgie statt Kartenfriedhof", also Editorial-Zeilen
   statt Karten-Grid. Die sticky linke Spalte war die Umsetzung, nicht der
   Punkt. Die Zeilen bleiben und bekommen mehr Raum, nicht weniger.

   Die einzige Leistung, die die sticky Spalte wirklich erbringt — zu
   wissen, in welchem Kapitel man gerade scrollt — erbringt das sticky
   .hub-nav-Band mit gleitendem Indikator bereits. Orientierung geht nicht
   verloren, sie war doppelt vorhanden.
   ------------------------------------------------------------ */

.page-hub .hub-chapter { position: relative; }

@media (min-width: 981px) {
  .page-hub .chapter-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(40px, 4vw, 64px);
  }
  /* sticky aus: in einer einspaltigen Bühne klebt nichts mehr neben etwas.
     `relative` statt `static` — und das ist keine Kosmetik, sondern die
     Reparatur eines echten Fehlers (Daniel, 16.08.: "die Geisterziffern
     verspringen nach links oben"):

     `.reveal` traegt `transform: translateY(32px)` und faellt nach der
     Animation auf `transform: none`. Ein transformierter Vorfahr ist der
     Bezugsrahmen fuer absolut positionierte Nachfahren — faellt der
     Transform weg, faellt der Bezugsrahmen weg. Gemessen: die Ziffer sprang
     von links 132 / oben 100 auf links 0 / oben -36, also 132px nach links
     und 136px nach oben, genau in dem Moment, in dem die Seite fertig
     eingeblendet ist.

     `position: relative` macht den Kopf in BEIDEN Zustaenden zum
     Bezugsrahmen. Damit haengt kein Layout mehr an einem Animationszustand.
     Verallgemeinert: Wer in diesem Prototyp absolut positioniert, verankert
     das ausdruecklich — ein geerbter Bezugsrahmen aus einem `transform` ist
     nur so lange da, wie die Animation laeuft.

     `top: auto` ist Pflicht und nicht Kosmetik: style.css setzt fuer den
     sticky Kopf `top: calc(var(--header-h) + 108px)` = 184px. Solange der
     Kopf `static` war, lag dieser Wert brach. Der Wechsel auf `relative` hat
     ihn scharf gestellt und den Kopf 188px nach unten geschoben — mitten in
     die erste Leistungszeile. Gemessen: Kopf bei 188..604 statt 0..416.
     Merksatz: Ein Wechsel von `static` auf `relative` aktiviert alle
     Versatzwerte, die vorher wirkungslos danebenlagen. */
  .page-hub .chapter-head { position: relative; top: auto; }
}

/* ------------------------------------------------------------
   F6.2 · Die Kapitelziffer wird der Grund, auf dem der Kopf steht.

   Heute ist sie ein 120px-Etikett in der linken Spalte. Der Hub-Hero
   dieser Seite macht mit der "13" bei 384px längst das Gegenteil — die
   Seite hat die Signatur selbst etabliert und für ihre eigenen Kapitel
   wieder fallengelassen. Signatur #3 (Ghost-Ziffern) plus #6
   (Überlappung), beides eigenes Material, kein Import.

   Bewusst unter 384px: der Hero bleibt die größte Ziffer der Seite.

   Aktiv-Zustand: In style.css füllt sich die Ziffer bei .is-active massiv
   in Dark Teal. Auf 120px ist das eine Rückmeldung, auf 200px wäre es der
   lauteste Gegenstand der Seite und würde H2 und Leistungszeilen
   überstimmen — derselbe Hierarchie-Defekt, den Daniel am Statement
   gefunden hat. Die Rückmeldung bleibt, sie wechselt nur das Mittel:
   Strichstärke und Deckkraft statt Füllung.
   ------------------------------------------------------------ */

.page-hub .chapter-num {
  position: absolute;
  left: 0;
  /* Bezugsrahmen ist .chapter-head, NICHT .hub-chapter — auch wenn der Kopf
     `position: static` trägt. Grund: `.reveal` setzt einen `transform`, und
     ein transformierter Vorfahr wird zum umgebenden Block für absolut
     positionierte Nachfahren. Gemessen: computed top = 136,8px, tatsächliche
     Position 274px unter der Sektionsoberkante — die Differenz war der Kopf.
     Das ist hier kein Ärgernis, sondern das gewünschte Verhalten: Die Ziffer
     gehört zum Titel und soll mit ihm liegen, nicht zur Sektionskante.
     Negativ, damit die Glyphen den Titel mittig hinterlegen: der sichtbare
     Ziffernkasten beginnt rund 77px unter der Elementoberkante (Poppins-
     Oberlänge bei line-height 0.82). */
  /* Weiter nach oben als im ersten Entwurf: Daniel, 16.08. — "der Abstand
     zwischen der Kapitelnummer und dem Kapiteltitel ist ein bisschen klein
     geraten". Die Ziffer bleibt Grund, rückt aber sichtbar hinter/über den
     Titel statt direkt an ihm zu kleben. */
  top: clamp(-88px, -5vw, -44px);
  z-index: 0;
  margin-bottom: 0;
  font-size: clamp(5.5rem, 14vw, 12.5rem);
  line-height: 0.82;
  letter-spacing: -0.02em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(0, 72, 96, 0.16);
  pointer-events: none;
  white-space: nowrap;
}

/* Aktiv: Strich wird kräftiger, nicht gefüllt */
html.js .page-hub .hub-chapter.is-active .chapter-num {
  color: transparent;
  -webkit-text-stroke-color: rgba(0, 72, 96, 0.38);
}

/* ------------------------------------------------------------
   F6.3 · Der Kopf: Text liegt AUF der Ziffer, Bild als Begleiter rechts.

   Das Bild bleibt in Maßstab und Rolle. Es zu vergrößern wäre der
   naheliegende Zug und der falsche: alle vier Kapitelbilder sind Stock,
   und "eine große Fläche verzeiht ein schwaches Foto nicht" ist an dieser
   Seitenfamilie zweimal belegt (Nachtrag 2 am Behandlungsraum, Nachtrag 7
   am Team-Teaser). Der Hub wird typogetragen — die increase-Familie,
   zweiter Beleg nach dem Statement.
   ------------------------------------------------------------ */

/* Kein Bild im Kapitelkopf — und der Grund ist NICHT, dass es Stockfotos sind.
   (Daniel, 16.08.: "Du solltest dich nicht daran stören, dass es Stockbilder
   sind … dann eher sagen, hier braucht es auf jeden Fall ein Bild, das so und
   so geartet ist." Meine frühere Begründung war damit falsch herum.)
   Der Grund ist die Größe: 340×320px neben einem 62px-Titel liest als
   Briefmarke auf einem Brief, egal wie gut das Foto ist. Vier davon
   hintereinander machen die Seite bildarm UND leer zugleich.
   Der Bildbedarf dieser Seite wird nicht gestrichen, er wird verlegt: EIN
   vollbreiter Moment, nicht vier Stempel — Anforderung in die Shooting-Liste. */
.page-hub .chapter-head .arch-frame { display: none; }

@media (min-width: 981px) {
  .page-hub .chapter-head {
    display: grid;
    /* Beschreibung nach rechts, wo vorher das Bild stand (Daniels Zug): Der
       Kopf wird dadurch halb so hoch, statt dass unter dem Titel eine dünn
       besiedelte Zone entsteht. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* align-items: end riss einen 110px-Krater zwischen Titel und Fließzeile.
       `align-items: start` allein hat ihn nur verschoben, nicht geschlossen:
       Das Bild spannt beide Zeilen und ist 320px hoch, also verteilt das Grid
       die Mehrhöhe auf BEIDE auto-Zeilen — je rund 96px, die als Loch zwischen
       Titel und Zeile sichtbar werden. Erst `auto 1fr` nimmt der zweiten Zeile
       diese Rolle ab: sie schluckt die Resthöhe, die Fließzeile bleibt oben.
       Verallgemeinert: Ein zeilenübergreifendes Element bemisst die Zeilen mit,
       die es überspannt — wer nur die Ausrichtung ändert, verschiebt das Loch. */
    align-items: end;
    column-gap: clamp(40px, 5vw, 80px);
    padding-top: clamp(52px, 5.6vw, 84px);
  }
  .page-hub .chapter-head h2 { grid-column: 1; position: relative; z-index: 1; }
  .page-hub .chapter-head .chapter-lead {
    grid-column: 2;
    position: relative;
    z-index: 1;
    margin: 0 0 0.35em;
  }
}

.page-hub .chapter-head h2 {
  /* 44,8px auf 1440 waren mittelgroß neben einem 83px-Hero und einer
     120px-Ziffer. Neu ~62px: deutlicher Sprung, bleibt aber klar unter
     dem Hero-h1 (83,2px), damit der Rang der Seite stimmt. */
  font-size: clamp(2.1rem, 4.3vw, 3.9rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

.page-hub .chapter-head .chapter-lead {
  font-size: 1.15rem;
  max-width: 48ch;
  margin-top: 0;
}

/* ------------------------------------------------------------
   F6.4 · Die Leistungszeilen bekommen die volle Breite — und eine
   zweite Spalte, statt die Beschreibung unter den Namen zu stapeln.

   Das ist der eigentliche Zug. Der Inhalt der Seite hört auf, in 44 %
   der Breite zu wohnen. Die Zeile wird ein echter Editorial-Index:
   Nummer | Name | Beschreibung | Pfeil.

   Kein Markup-Eingriff: Name und Beschreibung stecken im DOM in einem
   gemeinsamen namenlosen span (Kind 2 der Zeile). Genau der wird zum
   zweispaltigen Raster.
   ------------------------------------------------------------ */

@media (min-width: 981px) {
  .page-hub .index-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    /* Enger als der erste Entwurf. Grund ist ein echter Zusammenstoss, den
       Daniel gefunden hat: "Kinderzahnheilkunde" rendert 480px breit und
       stand in einer 432px-Spalte — der rechte Rand des Wortes beruehrte die
       Beschreibung auf 0px genau, und der Hover-Versatz von 10px schob es
       hinein. Seine eigene Diagnose war die richtige: der Abstand zwischen
       Ziffer und Begriff ist zu gross, und zwar generell, nicht nur dort. */
    column-gap: clamp(18px, 2.2vw, 32px);
    padding-block: clamp(30px, 3.4vw, 44px);
  }

  .page-hub .index-row > span:nth-child(2) {
    display: grid;
    /* minmax(0, …) ist Pflicht: ohne die Null-Untergrenze sizet eine
       Grid-Spur auf max-content und sprengt die Zeile. Derselbe Fehler
       hat F5 den Container von 1240 auf 993px geschrumpft.
       Halbe/halbe statt 7:8 — die Namensspalte muss den laengsten Begriff
       des Hauses tragen (Kinderzahnheilkunde, 480px) plus 10px Hover. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(18px, 2.2vw, 32px);
    align-items: start;
  }

  .page-hub .index-row .row-name {
    /* 45,6px waren zu laut (Daniel, 16.08.) und standen der Kapitelüberschrift
       zu nah. ~35px setzt die Leistung klar unter das Kapitel und bleibt
       trotzdem deutlich über den 33,6px des Ausgangszustands. */
    font-size: clamp(1.5rem, 2.4vw, 2.2rem);
    line-height: 1.12;
  }

  .page-hub .index-row .row-desc {
    font-size: 1.02rem;
    line-height: 1.6;
    max-width: none;
    margin: 0.35em 0 0;
  }

  .page-hub .index-row .row-arrow {
    width: 52px;
    height: 52px;
    margin-top: 0.15em;
  }

  /* Die Nummer bekommt Maßstab mit — sie ist der rote Faden 01–13.
     min-width von 2.6em auf 1.9em: die Spur war breiter als ihr Inhalt und
     hat den Platz gekostet, der dem laengsten Begriff fehlte. */
  .page-hub .index-row .row-num {
    font-size: 1.25rem;
    min-width: 1.9em;
    margin-top: 0.2em;
  }
}

/* ------------------------------------------------------------
   F6.6 · Die Kapitelnavigation bekommt Luft und steht mittig.

   Daniel, 16.08.: "sehr eng an dem Laufband. Eventuell da 'n bisschen mehr
   Luft, sowohl nach oben als auch nach unten. Und ich glaube, diese Optionen
   sollten zentriert dargestellt werden."

   Die Maske am rechten Rand bleibt, aber nur dort, wo sie etwas meldet: Sie
   signalisiert "rechts liegen weitere Tabs" und ist bei zentrierter Reihe auf
   Desktop, wo alle vier sichtbar sind, eine Aussage ueber nichts. Ab 981px
   deshalb aus, darunter unveraendert.
   ------------------------------------------------------------ */

@media (min-width: 981px) {
  .page-hub .hub-nav-inner {
    justify-content: center;
    /* Zurück auf die ursprüngliche Bandhöhe. Daniel, 16.08.: Das Band war
       höher geworden als das Hauptmenü und damit selbst ein optisches
       Element — es soll aber nur sagen, wo man ist. Die Luft gehört UM das
       Band herum, nicht IN das Band. */
    padding-block: 8px;
    -webkit-mask-image: none;
    mask-image: none;
    gap: clamp(10px, 2vw, 24px);
  }
}

/* Luft um das Band: zum Laufband darüber und zur Kapitelziffer darunter.
   Oben rund 10px zurückgenommen, unten deutlich erhöht (Daniel, 16.08.) —
   das Band rückt näher ans Laufband, die Kapitelziffer bekommt Anlauf. */
.page-hub .marquee + .hub-nav { margin-top: clamp(12px, 1.6vw, 23px); }
.page-hub .hub-nav + .hub-chapter { padding-top: clamp(76px, 8.6vw, 128px); }

/* ------------------------------------------------------------
   F6.7 · Die grauen Trennstriche fallen.

   Daniels Frage: gewollt oder CSS-Unfall? Gewollt — style.css setzt
   `border-block` am Kapitelband und `border-top` zwischen den Kapiteln.
   Sie stammen aus dem v3.3-Layout, in dem die Kapitel dicht aufeinander
   folgten und der Strich die einzige Grenze war.

   In diesem Aufbau sind sie funktionslos geworden: Jedes Kapitel beginnt
   jetzt mit einer bildschirmbreiten Ghost-Ziffer und einem 62px-Titel — die
   Grenze ist ohne Hilfslinie unübersehbar. Und das Band trägt einen eigenen
   Hintergrund mit Backdrop-Blur, trennt sich also im klebenden Zustand
   selbst vom durchlaufenden Inhalt.

   Ein Strich, der nichts mehr markiert, ist eine Behauptung von Struktur —
   genau das, was der Ruhe-Grundsatz meint. Sie fliegen.
   ------------------------------------------------------------ */

.page-hub .hub-nav { border-block: 0; }
.page-hub .hub-chapter + .hub-chapter { border-top: 0; }

/* ------------------------------------------------------------
   F6.8 · „13" und „LEISTUNGEN" im Hub-Kopf mittig übereinander.

   Ursache des Versatzes: `.hub-ghost` ist absolut positioniert ohne Breite,
   also schrumpft der Kasten auf den breitesten Inhalt — und das ist wegen
   der Sperrung von 0,22em das WORT, nicht die Ziffer. Die Ziffer stand
   dadurch linksbündig in einem zu breiten Kasten. Nicht das Wort stand zu
   weit rechts, die Zahl stand zu weit links.

   Dazu: die Zeile stand rund 65px unter der Ziffer, weil die Unterlänge
   einer 384px-Zeile den Abstand macht, nicht die Polsterung. Der negative
   Wert ist in em der Zeile gesetzt und skaliert deshalb mit der Ziffer mit.
   ------------------------------------------------------------ */

.page-hub .hub-ghost { text-align: center; }
.page-hub .hub-ghost small {
  text-align: center;
  margin-top: -1.25em;
  /* Die Sperrung setzt auch HINTER den letzten Buchstaben Luft; zentriert
     zieht das die Zeile optisch nach links. Der negative rechte Rand hebt
     genau diesen halben Betrag wieder auf. */
  margin-right: -0.22em;
}

/* ------------------------------------------------------------
   F6.5 · Mobil bleibt alles wie freigegeben.

   Unter 981px war das Layout ohnehin einspaltig gestapelt; dort gab es
   den 44-Prozent-Befund nie. Was hier begrenzt wird, ist allein die
   Ghost-Ziffer: absolut positioniert und bei 14vw würde sie auf 390px
   hinter dem Titel stehen, wo kein Platz für einen Grund ist.
   ------------------------------------------------------------ */

@media (max-width: 980px) {
  .page-hub .chapter-num {
    position: static;
    font-size: clamp(4.4rem, 13vw, 7rem);
    -webkit-text-stroke-color: rgba(0, 72, 96, 0.3);
    margin-bottom: var(--space-s);
  }
  html.js .page-hub .hub-chapter.is-active .chapter-num {
    color: var(--color-accent);
    -webkit-text-stroke-color: var(--color-accent);
  }
}

/* ------------------------------------------------------------
   F7 · Telefonnummer im Aktionsblock wird auf dem Telefon zum Button.

   Daniel, 2026-08-25: "die Telefonnummer mobil als Button gleich dem
   Termin-Button gestalten" — sitewide angefragt, nicht nur im Leistungen-
   Hub-Finale, wo der Punkt herkam. Betrifft jedes `.hero-cta`-Aktionspaar
   (Startseiten-Hero, Zitatband-CTA-Band-Journey-Finale, Detailseiten-Kopf
   und -Finale, Hub-Finale) — derselbe Baustein steht seitenweit gleich.

   currentColor traegt automatisch die je Sektion schon gesetzte Farbe mit
   (hell auf dem Seitengrund, weiss auf den dunklen Baendern) — kein
   Sonderfall pro Kontext noetig, bis auf border-bottom-color: vier Stellen
   ueberschreiben genau die eine Kante separat mit einer verblassten
   Deckkraft (die alte Unterstrich-Optik). Deren Selektoren sind spezifischer
   als `.hero-cta .hero-phone` unten, deshalb hier einzeln auf Volldeckkraft
   nachgezogen — sonst bliebe nur die untere Rahmenkante blasser als die
   drei anderen. */
@media (max-width: 620px) {
  .hero-cta .hero-phone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 19px 34px;
    border: 1px solid currentColor;
    border-radius: var(--radius);
  }
  .journey .hero-phone,
  .page-hero.head-dark .hero-phone,
  .page-detail.is-built .page-hero .hero-phone,
  .page-home .hero .hero-phone {
    border-bottom-color: currentColor;
  }
}

