/* ============================================================================
   ICKE-FAMILIE · Komponenten + Base — token-only (public/styles/tokens.css).
   Ziel-Layout: brandbook-v1/web-header-hero-mockup.html. Mobile-First.
   🔴 Keine Hardcode-Hexe: alle Farben/Maße aus Tokens → Spur-B-Flip bleibt Token-Wechsel.
   ============================================================================ */

/* ---- Reset / Base ---- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text-muted);
  font-family: var(--font-serif);           /* Fließtext = Serif (Board 03) */
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  /* 🔴 SCHRIFTZEICHNUNG — Nicos Entscheidung vom 31.08.2026, Fassung B.
     ANLASS, woertlich: „Die sehen sonst an den Raendern leicht verwaschen und unscharf aus.
     Gleiches gilt fuer die Raender von Buttons und auch die Texte auf den Buttons."

     ⚠️ ZUERST GEMESSEN, OB ES AM KONTRAST LIEGT — tut es nicht, ausser im Hero:
       40 von 40 Text-Farbkombinationen auf Flaechen ueber ihrer Schwelle (schlechtester 6,46
       gegen 4,5) · alle Knopfbeschriftungen ueber 6,2 · genau EIN Rahmen darunter
       (Einwilligungs-Banner, 1,22 -> in #340 repariert) · der Hero lag bei 1,01 (#337).
     🔴 UND: `-webkit-font-smoothing` stand vorher NIRGENDS. Die naheliegende Vermutung, jemand
     habe die Zeichnung umgestellt, war falsch.

     🔑 WARUM DAS UEBERHAUPT WIRKT: Der Bau ist ueberwiegend HELL AUF DUNKEL. Auf Apple-Geraeten
     zeichnet der Browser helle Schrift auf dunklem Grund dabei fetter, als sie gesetzt ist —
     der Buchstabe „laeuft zu". `antialiased` nimmt das zurueck. Das ist das uebliche Mittel
     gegen genau diesen Eindruck.

     ⚠️ WAS ES NICHT IST: eine Kontrastaenderung. Die Farben bleiben, nur die Kantenglaettung
     wechselt. Nachgemessen an den 15 Hero-Kombinationen: identische Werte.
     ⚠️ UND NICHT MESSBAR VON HIER: Wie das Ergebnis aussieht, entscheidet der Bildschirm.
     Der Browser, mit dem wir messen, glaettet ohnehin in Graustufen — eine Zahl dazu waere
     eine Aussage ueber das Werkzeug. Deshalb hat NICO entschieden, an drei Fassungen
     nebeneinander (A: so wie vorher · B: diese · C: mit Textschatten).
     🔑 Ein Textschatten war die naheliegende Idee und macht Schrift SCHWERER, nicht schaerfer.
     Auf dem Foto im Hero hilft er (dort hebt er den Kontrast oertlich an, siehe .hero-full);
     auf einer ruhigen Flaeche legt er einen weichen Saum um jeden Buchstaben. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--accent-ink); }
code { background: var(--surface); padding: .1em .35em; border-radius: var(--radius-xs); font-size: .9em; }

/* Überschriften: editoriale Serif-Display (Signal-Ton). Label-Headings (Card-Titel/Footer-H4) setzen Grotesk selbst. */
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--signal); line-height: var(--lh-snug); }

/* ---- Layout-Helfer ---- */
.wrap { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--gutter); }

/* ---- a11y ---- */
a, button, input, select, textarea, label, [role="button"], summary { min-height: var(--tap-min); }
button, [role="button"], input[type="submit"], input[type="button"], .btn {
  min-height: var(--tap-min); min-width: var(--tap-min); touch-action: manipulation;
}
:where(a, button, [role="button"]) { -webkit-tap-highlight-color: transparent; }
.skip-link {
  position: absolute; left: .5rem; top: -3rem; z-index: 100;
  background: var(--accent); color: var(--on-accent);
  padding: .5rem .9rem; border-radius: var(--radius-btn); text-decoration: none;
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: .5rem; }
:where(a, button, summary, [role="button"], input, select, textarea):focus-visible {
  outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 4px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-grotesk); font-weight: var(--fw-semibold); font-size: .95rem;
  border-radius: var(--radius-btn); padding: 12px 22px; text-decoration: none;
  border: 1px solid transparent; cursor: pointer; transition: filter var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.btn--primary { background: var(--accent-2); color: var(--on-accent-2); }    /* Akzent-2-Fill (Ocker ICKE / Grün AXT) — kontrastierender Text je Marke */
.btn--holz    { background: var(--cta);      color: var(--on-cta); border-color: var(--cta-border); } /* HAUPT-CTA = Neon-Pop (ICKE/AXT) bzw. Grün (Physio) */
.btn--ghost   { background: var(--cta2); border-color: transparent; color: var(--on-cta2); }  /* FOLLOW-CTA = Creme-Fill + Anthrazit-Text (Physio: Anthrazit-Fill) */
.btn--primary:hover, .btn--holz:hover, .btn--ghost:hover { filter: brightness(1.06); }

/* ---- Header ---- */
.site-header {
  position: sticky; top: 0; z-index: 40;
  border-bottom: var(--hairline);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: saturate(120%) blur(8px);
}
.site-header__inner {
  max-width: var(--content-max); margin-inline: auto;
  /* 🔴 Eigener Seitenabstand statt --gutter (28.08.): Der Kopf traegt in einer Zeile,
     was der Inhalt auf viele verteilt. Mit dem vollen --gutter (bis 64px je Seite) lief
     er quer. Der Inhalt darunter behaelt --gutter unveraendert. */
  padding: 14px clamp(1rem, 3vw, 2.5rem); display: flex; align-items: center; gap: var(--space-4);
}
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; }
/* Marken-Tick (Ocker ICKE / Grün AXT) — Wortmarken-Signatur statt Signet */
/* 20.09.2026, Nico an zwei Logo-Ausschnitten (ICKE brauner Balken, AXT gruener): „Lass uns mal das gruen auch bei ICKE
   nehmen." NUR der Balken — deshalb ein eigener Token statt --accent-2 (der haengt an .btn--primary, .card .ic, ArtikelCTA-
   Rand, einer SVG und bleibt je Marke, wie er ist). --wortmarke-balken steht in tokens.css fuer beide Marken auf Gruen. */
.brand::before { content: ""; align-self: stretch; width: 5px; min-height: 1.35em; background: var(--wortmarke-balken, var(--accent-2)); border-radius: 2px; }
.site-footer__brand { position: relative; }
.logo-chip { background: var(--icke-creme); border-radius: var(--radius-chip); padding: 6px; display: inline-flex; }
.logo-chip img { width: 34px; height: 34px; }
.brand .wordmark {
  font-family: var(--font-grotesk); font-weight: var(--fw-black);
  font-size: 1.375rem; letter-spacing: .06em; color: var(--signal);
}
/* Mobile-Toggle: Burger (Label) + verstecktes Checkbox — Nav via :checked ~ nav.

   🔴 DAS CHECKBOX WAR `hidden`, UND DAMIT WAR DAS MENUE PER TASTATUR GAR NICHT ZU OEFFNEN.
   Gemeldet war „kein sichtbarer Fokus-Ring am Burger" (Site-Audit, 04.09.2026). Am Gegenstand
   gemessen ist es mehr: `hidden` erzeugt `display:none`, und ein solches Element nimmt keinen
   Fokus an — `nav-toggle.focus()` liess `document.activeElement` auf `BODY` stehen. Das Label
   ist ohnehin nicht fokussierbar (kein `tabindex`).
   🔑 Es fehlte also nicht der RING, sondern der FOKUS. Ein Ring auf einem Element, das nie
   fokussiert wird, waere die Erfuellung der Meldung und nicht die Behebung des Fehlers.

   👉 Bauform ohne JavaScript: das Checkbox bleibt im Tab-Fluss, ist aber unsichtbar geclippt;
   den Ring zeigt das LABEL, ueber `:focus-visible + .nav-burger`.
   ⚠️ `clip-path`/`opacity` halten den Fokus, `display:none` und `visibility:hidden` nehmen ihn.
   ⚠️ Ab dem Umschaltpunkt (seit 22.09.2026: 1260px, vorher 1120), wo der Burger `display:none` ist, wird auch das Checkbox ausgeblendet — sonst
   steht dort eine unsichtbare Station im Tab-Fluss, die nichts tut. */
.nav-burger { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; font-size: 1.5rem; color: var(--text); cursor: pointer; min-height: var(--tap-min); min-width: var(--tap-min); }
.nav-toggle { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; pointer-events: none; }
/* GEMESSEN, nicht angenommen: die Box wird 1x44 statt 1x1 — als absolut positioniertes
   Flex-Kind wird sie in der Querachse gestreckt und liegt damit ueber dem Wortmarken-Link.
   Sie faengt trotzdem keinen Klick ab: clip-path wirkt auch auf die Trefferpruefung,
   elementFromPoint in ihrer Mitte liefert .brand. Das pointer-events: none oben ist die
   zweite Sicherung fuer den Fall, dass jemand das Clipping spaeter anders loest — auf den
   Tastaturfokus hat es keine Wirkung. */
.nav-toggle:focus-visible + .nav-burger { outline: 3px solid currentColor; outline-offset: 2px; border-radius: 4px; }
.site-nav { display: none; }
.nav-toggle:checked ~ .site-nav {
  display: block; position: absolute; left: 0; right: 0; top: 100%;
  background: var(--bg); border-bottom: var(--hairline); padding: var(--gutter);
}
.site-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.site-nav a { font-family: var(--font-label); font-weight: var(--fw-semibold); font-size: .8rem; text-transform: uppercase; letter-spacing: .12em; color: var(--text-muted); text-decoration: none; }
.site-nav a:hover { color: var(--accent-ink); }
.site-header .headcta { display: none; }
/* Theme-Umschalter (Light/Dark) — immer sichtbar, token-basiert. Icon per effektivem Theme. */
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; margin-left: var(--space-3);
  min-height: var(--tap-min); min-width: var(--tap-min); padding: 0 .55rem;
  background: transparent; color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-btn);
  cursor: pointer; font-size: 1.05rem; line-height: 1; transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.theme-toggle:hover { color: var(--accent-ink); border-color: var(--accent-ink); }
.theme-toggle__icon::before { content: "\2600"; }                 /* ☀ — Default dunkel-first (icke/axt): „zu hell wechseln" */
[data-brand="physio"] .theme-toggle__icon::before,
[data-brand="spaetform"] .theme-toggle__icon::before { content: "\263E"; }  /* ☾ — Default creme */
[data-theme="light"] .theme-toggle__icon::before { content: "\263E"; }      /* ☾ — im Hellen: „zu dunkel wechseln" */
[data-theme="dark"]  .theme-toggle__icon::before { content: "\2600"; }      /* ☀ */
/* Gruppierte Nav (AXT) — CSS-only Dropdown, KEIN <details> (Paint-Falle). Mobile: Untermenü eingerückt, immer sichtbar. */
.site-nav .caret { font-size: .7em; opacity: .65; }
.subnav { list-style: none; margin: .35rem 0 0; padding: 0 0 0 .9rem; display: grid; gap: .5rem; border-left: 1px solid var(--border); }
.subnav a { font-size: .72rem; color: var(--text-faint); }
/* 🔴 1120, nicht 960 (28.08.2026). Bei 960 schaltete der Desktop-Nav an, BEVOR er
   hineinpasste — gemessen lief jede Seite quer:
       ICKE  960px 89px Ueberstand · 1000px 51px
       AXT   1060px 172px · 1200px 39px · 1280px 3px  ← auch auf 1280er-Laptops
   Zwei Aenderungen zusammen, einzeln reichte keine:
     (1) Der Kopf bekommt einen eigenen, schmaleren Seitenabstand (der Inhalt behaelt
         --gutter) und eine mitwachsende Nav-Luecke statt fester 32px.
     (2) Der Umschaltpunkt liegt jetzt dort, wo die BREITERE der beiden Marken passt.
   AXT traegt sieben Punkte mit 609px reiner Textbreite und passt ab 1120; ICKE haette
   ab ~1000 gereicht. Bewusst EINE Zahl fuer beide statt marken-eigener Umschaltpunkte:
   zwei Zahlen driften auseinander, und die zweite pflegt niemand mit.
   Nachgemessen ueber beide Marken: 375/768/900/1119 = Burger, 0 Ueberstand;
   1120/1200/1280/1440 = Desktop-Nav, 0 Ueberstand.
   🔵 22.09.2026 PARITAET B2 (web#1116): ICKE traegt jetzt NEUN Punkte (Personal Training als eigener Punkt wie bei
   AXT), AXT acht (Team). Dieselbe Regel, neu gemessen (scrollWidth gegen innerWidth, headless): ICKE ueberlaeuft
   bei 1120 um 81px, bei 1240 um 1px, passt ab 1260; AXT ueberlaeuft bei 1120 um 54px, passt ab 1200.
   Umschaltpunkt deshalb 1260 — dort, wo die BREITERE Marke passt; 1259 = Burger. */
@media (min-width: 1260px) {
  .nav-burger { display: none; }
  /* 🔴 MIT dem Burger verschwindet auch seine Station im Tab-Fluss. Ohne diese Zeile
     fokussiert die Tabulatortaste auf dem Desktop ein unsichtbares Bedienelement, das
     eine Navigation oeffnet, die dort ohnehin ausgeklappt ist. */
  .nav-toggle { display: none; }
  .site-nav { display: block; margin-left: var(--space-3); }
  /* Luecke mitwachsend statt fest 32px — AXT traegt sieben Punkte mit 609px reiner
     Textbreite und passte sonst erst ab ~1283px, also nicht einmal auf 1280er-Laptops. */
  .site-nav ul { display: flex; flex-wrap: nowrap; width: max-content; gap: clamp(1.1rem, 1.7vw, 2rem); }
  .site-header .headcta { display: inline-flex; margin-left: auto; }
  /* Desktop-Dropdown: nur bei :hover/:focus-within (fokussierbares Gruppen-Label = Keyboard-fähig). */
  .site-nav .has-sub { position: relative; }
  .site-nav .subnav {
    position: absolute; top: 100%; left: -.4rem; margin: 0; padding: .4rem; min-width: 14rem;
    display: none; grid-auto-flow: row; gap: 0; border-left: 0;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card);
    box-shadow: 0 14px 40px rgba(0,0,0,.30); z-index: 60;
  }
  .site-nav .has-sub:hover > .subnav, .site-nav .has-sub:focus-within > .subnav { display: grid; }
  .site-nav .subnav a { display: block; padding: .5rem .7rem; border-radius: 8px; color: var(--text-muted); white-space: nowrap; }
  .site-nav .subnav a:hover { color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 12%, transparent); }
}

/* ---- Hero ---- */
.hero {
  padding-block: clamp(3rem, 6vw, 6rem) clamp(3.5rem, 7vw, 6.5rem);
  /* Warmer Radial-Glow (Holz→Ocker) über der Anthrazit-Fläche — NICHT kalt-schwarz (C/K). */
  background: radial-gradient(120% 90% at 84% -10%, rgba(217,190,139,.16), rgba(154,86,34,.06) 30%, transparent 60%);
}
.hero__grid { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--gutter); display: grid; gap: var(--space-8); align-items: center; }
/* 🔴 Rasterkinder duerfen schrumpfen — siehe den Block bei `.hero h1`. Ohne dies setzt
   `min-width: auto` die Spalte auf die min-content-Breite des laengsten Wortes. */
.hero__grid > * { min-width: 0; }
.eyebrow { font-family: var(--font-grotesk); font-size: var(--fs-h2); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--accent-ink); font-weight: var(--fw-bold); }
/* Design-System: Eyebrows tragen --accent (Holz auf Anthrazit / Grün auf Physio-Creme — beide AA). */
/* 🔴 `overflow-wrap: break-word` — GEGEN EIN GEMESSENES LOCH, nicht vorsorglich.
   Auf /team-icke/ lief die Seite bei 375px Ansichtsbreite um 99px waagerecht ueber; die
   Ueberschrift war rechts abgeschnitten. Ursache: das Wort „Physiotherapeuten*Innen" ist in
   dieser Schriftgroesse 460px breit, verfuegbar sind 327px (375 minus 2x24 Innenabstand).
   Die Rasterspalte loest deshalb auf 450,25px auf: 450,25 + 24 = 474 = der gemessene scrollWidth.
   🔑 NICHT MEINS — mit ausgeblendetem Teamraster blieb der Ueberlauf unveraendert bei 99px.
      Und die Verursacherliste log: in einem ueberlaufenden Dokument wird JEDES vollbreite
      Element mitgezogen und sieht wie die Ursache aus. Erst „eine Groesse aendern" trennte das.
   🔴 MEINE ERSTE FASSUNG WAR `overflow-wrap: break-word` ALLEIN — UND SIE WIRKTE NICHT.
      Gemessen nach dem Bau: vorher 99, nachher 99. `break-word` verhindert den SICHTBAREN
      Ueberlauf innerhalb einer Box, veraendert aber die MIN-CONTENT-Breite nicht — und genau
      die bestimmt hier die Groesse der Rasterspalte. 🔑 Ohne die Messung haette ich eine
      wirkungslose Aenderung als Reparatur gemeldet; sie sieht im Diff genauso aus wie eine, die
      wirkt. Wo der erwartete Ausgang „keine Aenderung" waere, ist die Gegenprobe der einzige
      Beweis, dass ueberhaupt etwas passiert ist.
   👉 Die Ursache ist die automatische Mindestbreite von Rasterkindern (`min-width: auto` =
      min-content). `min-width: 0` hebt sie auf; `break-word` bricht dann das Wort, statt es
      ueberlaufen zu lassen. Beide zusammen, jedes fuer sich unvollstaendig.
   ⚠️ BEIDE Regeln sind wirkungslos, wo nichts zu breit ist — sie koennen keine Seite
      verschlechtern, die heute in Ordnung ist. Deshalb brauchte die Reparatur keine
      vollstaendige Zaehlung aller 160 Seiten vorab.
      ⚠️ Und die Zaehlung waere ohnehin danebengegangen: Ich hatte die laengsten h1-Woerter
      erhoben und die Top-Kandidaten geprueft — /ultraschalltherapie-…/, /datenschutzerklaerung/,
      /karpaltunnelsyndrom-uebungen/ haben gar kein `.hero h1`. Die Zeichenzahl war ein
      Stellvertretermerkmal fuer die Breite UND fuer das Layout, und in beidem falsch.
   👉 `hyphens: auto` kommt dazu, weil der Bruch sonst mitten im Wort steht („Physiotherapeute|
      n*Innen") und wie ein Tippfehler aussieht. Es setzt einen Trennstrich an einer erlaubten
      Stelle. ⚠️ Es wirkt NUR, weil das Dokument `lang="de"` traegt — gemessen im gebauten HTML,
      nicht angenommen. Ohne die Sprachauszeichnung waere die Regel still wirkungslos. */
.hero h1 { font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-display); line-height: var(--lh-tight); letter-spacing: -.01em; color: var(--signal); margin: 16px 0 0; overflow-wrap: break-word; }
/* 🔴 SILBENTRENNUNG NUR DORT, WO SIE GEBRAUCHT WIRD — Korrektur meiner eigenen Regression
   vom selben Tag. Ich hatte `hyphens: auto` ungefiltert auf alle Hero-Ueberschriften gesetzt,
   um den 99px-Ueberlauf auf /team-icke/ bei 375px lesbar zu machen.
   ⚠️ `hyphens: auto` trennt aber an JEDER Zeilenumbruchstelle, nicht nur wenn ein Wort sonst
   nicht passt. Folge, gesehen auf /physiotherapie/ bei 1280px: „Physiotherapie-Pra-xis in
   Berlin Schoene-berg" — dreimal getrennt, obwohl Platz da war.
   🔑 Ein Wort mitten durchgeschnitten liest sich als Fehler. Nico hat die Seite an dem Tag als
   „billig" bezeichnet; genau so entsteht dieser Eindruck, und ich hatte ihn selbst eingebaut.
   👉 Deshalb an die Breite gebunden: Der gemessene Ueberlauf trat bei 375px auf, bei 768px
   nicht. Unterhalb 700px wird getrennt, darueber nicht. `overflow-wrap: break-word` und
   `min-width: 0` bleiben unbeschraenkt — sie wirken nur im Notfall und veraendern sonst nichts.
   🔑 NACHGEMESSEN, und es praezisiert die Begruendung: Bei 375px ist der Ueberlauf AUCH OHNE
   Trennung 0 — `min-width: 0` und `overflow-wrap` allein tragen ihn. `hyphens` ist also
   REIN KOSMETISCH: es setzt einen Trennstrich, wo sonst ein Wort ohne Strich bricht
   („Physiotherapeute|n*Innen"). Damit ist die Begrenzung auf schmale Breiten auch strukturell
   unbedenklich — sie nimmt nichts weg, was einen Ueberlauf verhindert. */
@media (max-width: 700px) { .hero h1 { hyphens: auto; } }
/* Mockup-Signatur: letztes Wort als Holz-Kursiv-Akzent (per <em> im Markup). */
.hero h1 em { font-style: italic; font-weight: inherit; color: var(--accent-em); }  /* theme-abhängig: Holz (dunkel) / tiefes Ocker (hell) */
.hero .sub { font-family: var(--font-serif); font-size: 1.25rem; line-height: var(--lh-body); color: var(--text-muted); margin: 20px 0 0; max-width: 46ch; }
.hero .cta { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: 28px; }
.hero__note { font-size: .78rem; color: var(--text-faint); margin-top: 16px; }
/* Hero-Art = bewusst dunkle Foto-/Akzentfläche (auch im Creme-Register) — „dunkel nur als Akzent". */
/* Interim-Bildstrategie (bis Fotoproduktion, Board 7): warme BRAND-FLÄCHE statt leerer Gradient —
   Holz-Glow (oben-links) + feines diagonales Struktur-Raster über dem Anthrazit. Kein Stock, CSS-only.
   🔁 Drop-in: sobald echte (duotone-gegradete) Fotos da sind, hostet derselbe Rahmen das <img>. */
.hero__art {
  position: relative; border-radius: var(--radius-xl); overflow: hidden;
  border: 1px solid var(--icke-line); aspect-ratio: 4 / 3;
  background:
    repeating-linear-gradient(135deg, transparent 0 21px, rgba(217,190,139,.035) 21px 22px),
    radial-gradient(120% 90% at 18% 4%, rgba(217,190,139,.16), transparent 55%),
    linear-gradient(150deg, var(--icke-panel) 0%, var(--icke-anthrazit) 100%);
}
.hero__art img { width: 100%; height: 100%; object-fit: cover; filter: var(--bild-grade); }
.hero__art::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(35,40,43,.15) 30%, rgba(35,40,43,.78) 100%), linear-gradient(90deg, rgba(35,40,43,.35), transparent 40%); }
.hero__art .cap { position: absolute; left: 18px; bottom: 16px; z-index: 2; font-family: var(--font-grotesk); font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; color: var(--icke-cream-dim); }
@media (min-width: 960px) {
  .hero__grid { grid-template-columns: 1.15fr .85fr; gap: var(--space-10); }
}
/* Creme-Register (Physio/Spätform): Serif-geführte, klinisch-ruhige Headlines + warmer Art-Verlauf */
[data-brand="physio"] .hero h1,
[data-brand="spaetform"] .hero h1 { font-family: var(--font-serif); font-weight: var(--fw-semibold); letter-spacing: -.01em; }
[data-brand="physio"] .hero__art,
[data-brand="spaetform"] .hero__art { background: linear-gradient(150deg, var(--surface) 0%, var(--icke-holz) 80%, var(--icke-gruen) 140%); }
[data-brand="physio"] .hero .eyebrow,
[data-brand="spaetform"] .hero .eyebrow { color: var(--icke-gruen); }
[data-brand="physio"] .section__head h2,
[data-brand="physio"] .article h2 { font-family: var(--font-serif); font-weight: var(--fw-semibold); }

/* ---- Statband (dunkle Akzentfläche — ICKE-Energie; „dunkel nur als Akzent") ---- */
.statband { background: var(--accent); }  /* Holz-Band (warme Zweitfläche, Regler 26 %) */
.statband__inner { max-width: var(--content-max); margin-inline: auto; padding: var(--space-6) var(--gutter); display: grid; gap: var(--space-5); grid-template-columns: 1fr; }
.stat { display: flex; align-items: baseline; gap: .6rem; }
.stat b { font-family: var(--font-grotesk); font-weight: var(--fw-black); font-size: clamp(1.9rem, 4vw, 2.6rem); color: var(--health); line-height: 1; } /* Grün-Zahlen auf Holz-Band (großer Text, ≥3:1) */
/* 26.08.: „--icke-holz Mini-Touch" auf .stat:nth-child(2) b ENTFERNT — --accent ist bei icke UND axt =--icke-holz, die Zahl war holz-auf-holz = unsichtbar (Standorte-Kennzahl fehlte). Alle Zahlen bleiben --health (kontrastgeprüft). */
.stat span { font-family: var(--font-grotesk); font-size: .9rem; color: var(--on-accent); line-height: 1.2; }  /* Anthrazit-Labels auf Holz-Band */
@media (min-width: 720px) { .statband__inner { grid-template-columns: repeat(3, 1fr); } }

/* ---- Sektion / Eyebrow-Titel ---- */
.section { padding-block: var(--section-y); }
.section__head { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--gutter); margin-bottom: var(--space-6); }
.section__head h2 { font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: clamp(1.6rem, 3.2vw, 2.1rem); letter-spacing: -.01em; color: var(--signal); margin: 8px 0 0; }

/* ---- Feature 3-up ---- */
.cards { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--gutter); display: grid; gap: var(--space-5); grid-template-columns: 1fr; }
/* Variante C: Feature-Karten grün gefüllt · Holz-Icon-Kacheln · Creme-Text (Creme/Grün 5,8:1 AA). */
/* Design-System: Feature-Karten = Panel-Fläche + Border · Icon-Kacheln zyklen die 3 Akzente (Grün/Holz/Ocker). */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); padding: var(--space-6); color: var(--text); }
.card .ic { width: 46px; height: 46px; border-radius: var(--radius-md); background: var(--health); display: flex; align-items: center; justify-content: center; font-size: 1.35rem; color: var(--icke-neon); margin-bottom: var(--space-4); }
.card:nth-child(2) .ic { background: var(--accent); color: var(--on-accent); }      /* Holz-Kachel, Anthrazit-Glyph */
.card:nth-child(3) .ic { background: var(--accent-2); color: var(--on-accent-2); }    /* Ocker/Grün-Kachel */
.card h3 { font-family: var(--font-label); font-size: .95rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text); font-weight: var(--fw-black); margin: 0 0 8px; }  /* Inter 800 uppercase (C/K) */
.card p { font-family: var(--font-body); font-size: 17px; line-height: var(--lh-body); color: var(--text-muted); margin: 0; }  /* Newsreader 17px (C/K) */
@media (min-width: 640px) { .cards { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .cards { grid-template-columns: 1fr 1fr 1fr; } }

/* ---- Editorial-Band (Serif/Wissen-Brücke) ---- */
.band { background: var(--surface-2); border-block: var(--hairline); padding-block: var(--space-10); }
.band__grid { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--gutter); display: grid; gap: var(--space-8); align-items: center; }
.band .eyebrow { color: var(--accent-ink); }
.band h2 { font-family: var(--font-serif); font-weight: var(--fw-semibold); font-size: clamp(1.7rem, 3.5vw, 2.3rem); line-height: 1.12; color: var(--signal); margin: 14px 0 0; }
.band h2 em { font-style: italic; color: var(--accent-ink); }
.band p { font-family: var(--font-serif); font-size: 1.1rem; line-height: 1.55; color: var(--text-muted); margin-top: 16px; }
.band .quote { border-left: 2px solid var(--accent-ink); padding-left: var(--space-5); }
.band .quote p.q { font-size: 1.35rem; color: var(--text); font-family: var(--font-serif); }
.band .quote p.by { color: var(--text-faint); font-family: var(--font-grotesk); font-size: .82rem; letter-spacing: var(--tracking-wide); margin-top: 12px; }
@media (min-width: 800px) { .band__grid { grid-template-columns: 1fr 1fr; } }

/* ---- CTA-Band (dezenter Holz-Creme-Verlauf — creme-dominant, KEIN Ocker/keine dunkle Fläche) ---- */
/* Variante C: unteres CTA-Band = Holz-Fläche (Anthrazit/Holz 8:1), Grün-CTA poppt darauf. */
.cta-band { background: var(--band-cta); padding-block: var(--space-10); text-align: center; }
.cta-band h2 { font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: clamp(1.7rem, 3.5vw, 2.35rem); color: var(--on-band-cta); letter-spacing: -.01em; }
.cta-band p { font-family: var(--font-serif); font-size: 1.1rem; color: #3B4A3D; margin: 12px auto 24px; max-width: 46ch; }
/* Grün-CTA mit Creme-Kante — poppt auf der Holz-Fläche. */
/* Auf dem Holz-Band: dunkler Button (Anthrazit-Fill + Neon-Text) = dark-on-light-Pop. */
.cta-band .cta-knopf, .cta-band .btn--holz, .cta-band .btn--primary { background-color: var(--icke-anthrazit); color: var(--icke-neon); border-color: transparent; }
.cta-band .btn--ghost { color: var(--on-band-cta); border-color: rgba(35,40,43,.4); }

/* ---- Footer (Anthrazit-Struktur-Fläche — C/K-Rebalance: „Struktur-26"; data-register=dark → helle Schrift) ---- */
/* ============================================================================
   🔴 ABSTAND FUER SPRUNGZIELE — sonst landet das Ziel hinter der klebenden Kopfleiste.
   ANLASS (31.08.2026): Auf drei Seiten sprangen die Links korrekt und zeigten trotzdem
   die falsche Stelle. Gemessen am gerenderten Dokument: Kopfleiste 73 px, Ziel bei y = 0.
   🔑 Ein Sprung, der funktioniert und die falsche Stelle zeigt, ist kaum besser als keiner.

   WARUM ES DIE REGEL VORHER SCHON GAB UND SIE TROTZDEM FEHLTE: Sie stand nur in
   `src/components/Inhaltsverzeichnis.astro` als `:global(.article :is(h2,h3)[id])` —
   und Astro liefert die Stile einer Komponente nur dort aus, wo die Komponente BENUTZT
   wird. Die drei Seiten benutzen sie nicht, also gab es die Regel dort gar nicht.
   🔑 Eine Regel, die nur existiert, wo eine Komponente eingebunden ist, ist keine
   Seitenregel. Das gilt fuer JEDE Stilregel, die in einer Komponente abgelegt wird.

   ⚠️ `:target` statt einer Aufzaehlung von Tags: Das Sprungziel ist nicht immer eine
   Ueberschrift — auf /physiotherapie/ ist es ein Absatz (`p#leistungen`). `:target` trifft
   genau das Element, auf das die Adresse zeigt, und nichts sonst.
   🔵 Am gerenderten Dokument geprueft, nicht angenommen: Ueberschrift UND Absatz landen
   danach bei y = 80 gegen eine Kopfunterkante von 73. */
:target { scroll-margin-top: 5rem; }

.site-footer { background: var(--bg); border-top: 1px solid var(--border); padding: var(--space-10) 0 var(--space-6); color: var(--text-muted); }
.site-footer__cols { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--gutter); display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
.site-footer__brand .wordmark { display: block; font-family: var(--font-grotesk); font-weight: var(--fw-black); font-size: 1.25rem; letter-spacing: .06em; color: var(--signal); margin: 12px 0 8px; }
.site-footer__brand p { font-size: .82rem; line-height: 1.6; margin: 0; max-width: 34ch; }
/* 🔴 h2, NICHT h4 (31.08.2026). Die Fusszeile setzte `h4` direkt unter das `h2` bzw. `h1`
   der Seite und uebersprang damit eine Ebene — gemessen auf 99 von 161 Seiten (86x h2->h4,
   13x h1->h4). 🔑 Der Defekt lag in EINER Datei und erschien auf fast jeder Seite; kein
   Pruefer meldet so etwas, weil jede Seite fuer sich betrachtet in Ordnung aussieht.
   ⚠️ Das AUSSEHEN bleibt unveraendert — nur die Ebene wandert. Deshalb musste der Selektor
   mitwandern: Tag und Regel gehoeren zusammen, sonst verliert die Fusszeile ihre Form. */
.site-footer h2 { font-family: var(--font-grotesk); font-size: var(--fs-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-muted); margin: 0 0 12px; }
/* 🔴 TREFFERFLAECHE 44px (04.09.2026, Site-Audit + eigene Nachmessung bei 390px).
   Gemeldet war „12 von 24 eigenstaendigen Bedienelementen unter 44px auf der Startseite".
   Nachgemessen ueber fuenf Seitentypen: es sind NICHT zwoelf verstreute Stellen, sondern
   EINE Komponente — diese elf Links plus der Cookie-Knopf, alle 342x27 bzw. 141x27, und
   sie stehen auf JEDER Seite. Eine Regel behebt alle.

   ⚠️ `min-height: 0` STAND HIER UND WIRD UEBERSCHRIEBEN — mit Grund, weil keiner dabeistand.
   Es gibt keinen Test darauf und keinen Kommentar; die wahrscheinlichste Lesart ist ein
   Reset, damit der <button> „Cookie-Einstellungen" wie ein Link aussieht und keine
   Knopf-Mindesthoehe erbt. 🔑 Diese Absicht bleibt erfuellt: die Optik ist unveraendert
   (gleiche Schrift, gleiche Farbe, kein Rahmen) — nur die Trefferflaeche waechst.
   👉 Falls `min-height: 0` doch ein Beschluss war und nicht ein Reset: er stand nirgends,
   und diese Zeile ist der Ort, an dem er zu widersprechen ist.

   ⚠️ FOLGE, sichtbar und gewollt: die Fusszeile waechst auf 375px um rund 200px
   (12 Elemente x 17px). Das ist der Unterschied zwischen 27 und 44 — er laesst sich nicht
   wegbauen, nur verschweigen. */
.site-footer nav a, .site-footer .footer-consent-link {
  display: flex; align-items: center; color: var(--text-faint); text-decoration: none;
  font-family: var(--font-grotesk);
  font-size: .85rem; line-height: 2; background: none; border: 0; padding: 0; text-align: left;
  cursor: pointer; min-height: var(--tap-min);
}
.site-footer nav a:hover, .site-footer .footer-consent-link:hover { color: var(--accent-ink); }
.site-footer__base { max-width: var(--content-max); margin: var(--space-6) auto 0; padding: var(--space-4) var(--gutter) 0; border-top: var(--hairline); font-family: var(--font-grotesk); font-size: .78rem; display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: space-between; }
@media (min-width: 700px) { .site-footer__cols { grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: var(--space-8); } }

/* ---- Globaler sticky Probetraining-CTA (mobil, Funnel-Integrität) ---- */
.cta-knopf {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap-min); padding-inline: 1.1em;
  background: var(--cta); color: var(--on-cta);
  border: 1px solid var(--cta-border);
  border-radius: var(--radius-btn); font-family: var(--font-grotesk); font-weight: var(--fw-bold); text-decoration: none;
}
/* HOCHGLANZ-HAUPT-CTA -- Nico 31.08.2026: "Ein bisschen mehr Hochglanz darf es gerne
   sein. Insbesondere bei den CTAs." Aus der Gegenueberstellung hat er Fassung C gewaehlt:
   tieferer Grundton (--icke-gruen-tief) + heller Innenrand + weicher Schatten + leichter Verlauf.

   WARUM background-image und nicht background: Beide Knopfregeln setzen background als KURZFORM,
   und die loescht background-image mit. Diese Regel muss deshalb NACH beiden stehen -- und der
   Band-Knopf oben wurde von `background:` auf `background-color:` umgestellt, damit der Verlauf
   dort ueberlebt. Sonst haetten 491 Knoepfe den Glanz und einer nicht, ohne dass es auffaellt.

   WARUM auf beiden Klassen: Haupt-CTA heisst .btn--holz ODER .cta-knopf. Nur eine zu treffen
   waere in jeder Zaehlung ein Erfolg gewesen und auf der Haelfte der Seiten unsichtbar. */
.btn--holz, .cta-knopf {
  /* Verlauf NUR nach unten dunkler -- oben bleibt der Grundton unangetastet.
     Eine helle Lage OBEN haette den Knopf an seiner hellsten Stelle auf 5,91 gebracht;
     zugesagt und von Nico gewaehlt waren 7,24. Der helle Rand kommt vom inset-Schatten,
     der eine 1px-Kante ist und nicht hinter dem Text liegt. */
  background-image: linear-gradient(rgba(0,0,0,0), rgba(0,0,0,.20));
  box-shadow: inset 0 1px 0 rgba(244,241,230,.22),
              0 1px 2px rgba(35,40,43,.35),
              0 6px 16px -6px rgba(35,40,43,.55);
  transition: filter var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.btn--holz:hover, .cta-knopf:hover {
  box-shadow: inset 0 1px 0 rgba(244,241,230,.30),
              0 2px 4px rgba(35,40,43,.38),
              0 12px 24px -8px rgba(35,40,43,.60);
}
@media (prefers-reduced-motion: reduce) { .btn--holz, .cta-knopf { transition: none; } }

.cta-sticky {
  position: sticky; bottom: 0; z-index: 50; display: flex; justify-content: center;
  padding: .5rem; background: color-mix(in srgb, var(--bg) 88%, transparent);
  border-top: var(--hairline); backdrop-filter: saturate(120%) blur(6px);
}
.cta-sticky .cta-knopf { width: 100%; max-width: 36rem; }
@media (min-width: 960px) { .cta-sticky { position: static; background: none; border: 0; } }

/* ---- Artikel-/Content-Seiten (migrierte Kronjuwelen) ---- */
.article { max-width: 46rem; margin-inline: auto; padding: var(--section-y) var(--gutter); }
/* 🔴 KURSPLAN-SEITEN: Rahmen weit, Prosa schmal (29.08.2026, Befund von Nico).
   `.article` ist die LESESPALTE (46rem ≈ 70 Zeichen) — richtig für Fliesstext, falsch fuer
   eine Tabelle. Der Kursplan wird nicht gelesen, sondern abgesucht; er lag bis heute in der
   Lesespalte, weil die Seite frueher eine Textseite mit einem Fremdfenster darin war.
   Der Rahmen ist geblieben, als #195 den Inhalt tauschte.
   ⚠️ NICHT `article` von der Seite nehmen: die Klasse traegt h1, .brand und die
   Absatz-Typografie. Ohne sie waere die Seite unformatiert — das ist die naheliegende
   Reparatur, die eine zweite Baustelle aufmacht.
   Prosa bleibt schmal, weil `.article p, .article li` bereits auf 42rem deckelt; die
   Ueberschriften bekommen denselben Deckel, sonst laufen sie ueber die volle Breite. */
.article--breit { max-width: var(--content-max); }
.article--breit > h1, .article--breit > h2 { max-width: 42rem; }

/* ---- Content-Shell (BEISPIEL Content-Breite): Lesespalte + Sticky-Rail nutzen die volle Breite ----
   Nur aktiv, wenn eine Seite .content-shell verwendet (kein Eingriff in bestehende .article-Seiten). */
.content-shell { max-width: 1120px; margin-inline: auto; padding: var(--section-y) var(--gutter); display: grid; gap: var(--space-8); grid-template-columns: minmax(0, 1fr); }
.content-shell > .article { max-width: 68ch; margin: 0; padding: 0; }
.content-rail { }
.rail-card { background: var(--surface); border: var(--hairline); border-radius: var(--radius-card); padding: var(--space-5); }
.rail-eyebrow { font-family: var(--font-grotesk); font-size: var(--fs-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--accent-ink); font-weight: var(--fw-bold); margin: 0 0 .5rem; }
.rail-lead { font-size: var(--fs-small); color: var(--text-muted); line-height: var(--lh-body); margin: 0 0 var(--space-4); }
.rail-card .cta-knopf { width: 100%; margin-bottom: var(--space-4); }
.rail-links { list-style: none; margin: 0; padding: var(--space-4) 0 0; border-top: var(--hairline); display: grid; gap: .55rem; }
.rail-links a { color: var(--text); text-decoration: none; font-family: var(--font-grotesk); font-size: var(--fs-small); }
.rail-links a:hover { color: var(--accent-ink); }
@media (min-width: 980px) {
  .content-shell { grid-template-columns: minmax(0, 1fr) 20rem; }
  .content-rail { position: sticky; top: var(--space-6); align-self: start; }
}
.article .brand { letter-spacing: .18em; text-transform: uppercase; color: var(--text-faint); font-size: var(--fs-label); font-family: var(--font-grotesk); display: block; }
.article h1 { font-size: clamp(2rem, 4vw, 2.6rem); line-height: 1.12; margin: .2em 0 .5em; }
.article h2 { font-size: clamp(1.4rem, 2.6vw, 1.8rem); margin: 1.5em 0 .4em; }
.article h3 { font-size: 1.25rem; margin: 1.3em 0 .3em; }
.article h4 { font-size: 1.05rem; margin: 1.2em 0 .3em; }

/* ============================================================================
   🔴 WAAGERECHTER UEBERLAUF BEI 375 PX — gemessen, nicht vermutet (31.08.2026).
   Alle 161 gebauten Seiten bei 375 px abgefragt: 14 schoben sich seitlich weg.
   Zwei Ursachen, beide im Fliesstext:
     · ungebrochene Links und URLs   /wwid-stretching-sinn-unsinn/ 839px (ein Link mit 815px)
                                     /datenschutzerklaerung/ 529px · /widerrufbelehrung/ 678px
     · Tabellen breiter als das Fenster  /supplemente-crossfitter/ 581px (Tabelle 557px)
                                         /fettabbau-crossfit/ 491px
   🔑 Breiter Inhalt soll in seinem EIGENEN Kasten scrollen — nie der Seitenkoerper.

   ⚠️ `overflow-wrap: anywhere`, NICHT `break-word`: Der Unterschied ist an derselben Datei
   schon einmal teuer geworden (siehe die Anmerkung zu `.hero h1`). `break-word` verhindert
   den sichtbaren Ueberlauf INNERHALB einer Box, aendert die min-content-Breite aber nicht —
   und die bestimmt, wie breit der Kasten selbst wird. `anywhere` aendert beides.

   ⚠️ Die Regeln sind wirkungslos, wo nichts zu breit ist: sie koennen keine Seite
   verschlechtern, die heute in Ordnung ist. Belegt ist das trotzdem, nicht behauptet —
   alle 161 Seiten nach der Aenderung erneut bei 375 px gemessen. */
.article :is(p, li, dd, dt, figcaption) { overflow-wrap: anywhere; }
/* 🔴 TABELLENZELLEN AUSDRUECKLICH NICHT — und das ist an der Sichtpruefung aufgefallen,
   nicht am Messwert. Mit `anywhere` in `td`/`th` schrumpft die Tabelle, bis sie passt:
   der Ueberlauf verschwindet, und die Spalten stehen als Buchstabensalat da
   („Om ega- 3-Fett säur en"). 🔑 Die Zahl war gruen und das Ergebnis unlesbar.
   👉 Ohne die Regel behaelt die Tabelle ihre Mindestbreite und scrollt in ihrem eigenen
   Kasten — das ist der Zweck der Regel darunter. */
/* 🔴 Ueberschriften gehoeren dazu — gefunden erst NACH der ersten Fassung:
   `/axt/agb/` lief weiter um 20px ueber, und der Verursacher war ein h2
   („7. Vertragslaufzeit/Vertragsbeendigung", 371px bei 327px Platz).
   🔑 Meine erste Regel zaehlte Fliesstext-Tags auf — die Ueberschrift war nicht dabei,
   weil ich an Absaetze und Links gedacht hatte. Gefunden hat es die Gegenmessung, nicht
   das Nachdenken: 14 wurden zu 1, und die 1 hatte eine andere Ursache als die 13.
   ⚠️ KEIN `hyphens: auto` hier: das trennt an JEDER Umbruchstelle, nicht nur wenn es
   noetig ist — es wuerde saemtliche Artikel-Ueberschriften veraendern. `anywhere` tut
   nichts, solange alles passt. */
.article :is(h1, h2, h3, h4, h5, h6) { overflow-wrap: anywhere; }
.article table { display: block; max-width: 100%; overflow-x: auto; }
.article p, .article li { max-width: 42rem; }
.article ul, .article ol { padding-left: 1.4em; }
.article li { margin-block: .3em; }
/* 🔴 Nur echte Fließtext-Links einfärben. Button-/CTA-Anker (.btn*, .cta-knopf) MÜSSEN ihre
   Komponenten-Textfarbe behalten — sonst überschreibt diese Regel (0,1,1) den Button-Text (grün/neon-auf-Fill unsichtbar). */
.article a:not([class~="btn"]):not(.cta-knopf) { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }

/* 🔴 Tabellen-Umbruch GLOBAL, nicht seiten-skopiert (27.08.).
   Vorher stand diese Regel nur im <style>-Block von crossfit-girl-workouts. Astro
   skopiert Seiten-Styles: die Regel wurde zu `.table-scroll[data-astro-cid-…]`.
   Auf makronaehrstoffe wurde derselbe Wrapper kopiert — ohne das Attribut, also
   OHNE WIRKUNG (gemessen: `overflow-x` kam auf der ganzen Seite 0× vor).
   🔑 Ein Wrapper, der beim Kopieren seine Wirkung verliert und dabei gleich aussieht.
   Global gilt sie fuer jede Seite, die den Wrapper benutzt — auch fuer die naechste. */
.table-scroll { overflow-x: auto; margin: 1.5rem 0; -webkit-overflow-scrolling: touch; }
.article-hero { width: 100%; border-radius: var(--radius-card); margin-block: .5em 1.2em; aspect-ratio: 4 / 3; object-fit: cover; }

/* ---- Artikel-Bildfigur (S1-Möbel; konsolidiert 26.08.2026) ----
   War 21× in Seiten-eigenen <style>-Blöcken dupliziert (12 Seiten, 7 Schreibweisen) —
   img/figcaption/--portrait waren bis auf Leerzeichen IDENTISCH, .article-figure
   unterschied sich AUSSCHLIESSLICH in max-width (15× 34rem, dazu 38/30/28/26/22rem).
   Hier steht der gemeinsame Stand mit dem häufigsten Wert; die sechs abweichenden Seiten
   behalten eine EINZEILIGE max-width-Überschreibung in ihrem scoped <style> (Astro-scoped
   schlägt global) — damit ändert sich das Aussehen KEINER Seite, aber Form und Farbe
   sind ab jetzt an einer Stelle änderbar. */
.article-figure { max-width: 34rem; margin-block: 1em; }
.article-figure img { width: 100%; height: auto; border-radius: var(--radius); }
/* 🔴 EINE GEZEICHNETE ERKLAERUNG IST EIN `svg`, KEIN `img` — und deshalb braucht sie hier
   eine eigene Zeile. Der Grund ist nicht Kosmetik: ein ueber `<img src>` geladenes SVG sieht
   die Custom-Properties dieser Seite NICHT (gemessen 05.09.2026: Token kommt inline an,
   ueber `<img>` greift der Fallback). Zeichnungen liegen deshalb INLINE im Markup, und die
   Groessenregel oben trifft sie nicht.
   ⚠️ Der Foto-Grade (`.article img`) trifft sie ebenfalls nicht, und das ist richtig — er ist
   die Voreinstellung fuer FOTOS, `.grafik` die benannte Ausnahme davon. Eine Zeichnung ist
   von Haus aus die Ausnahme, sie muss sie nicht beantragen. */
.article-figure svg { display: block; width: 100%; height: auto; }

/* ---- EINHEITLICHER BILD-LOOK (Nico, 31.08.2026) --------------------------------------
   Alle FOTOS im Artikelrumpf bekommen dieselbe Behandlung wie die Hero-Bilder: leichte
   Entsaettigung, minimal mehr Kontrast, dazu Radius und Haarlinie wie bei den Karten.
   🔑 Bis heute waren Inhaltsbilder die einzigen Bilder OHNE Behandlung — die Heros hatten
   sie seit dem Design-Sprint. Der Look wird also durchgezogen, nicht erfunden.

   🔴 LOGOS UND MARKEN SIND AUSGENOMMEN, und das ist keine Kosmetik: Die Bezahl-Logos von
   Visa, Mastercard und PayPal sind fremde Marken. Sie zu entsaettigen waere eine
   Veraenderung einer fremden Marke — und sie saehe zudem nach Fehler aus, nicht nach Stil.
   Dasselbe gilt fuer das eigene Logo im Kopf.
   ⚠️ Ausnahme ueber die KLASSE, nicht ueber den Dateinamen: ein Dateiname ist kein Merkmal.
   -------------------------------------------------------------------------------------- */
/* ⚠️ BEWUSST OHNE :not() — der erste Anlauf schrieb
   `.article img:not(.bezahloptionen img):not(.logo-chip img)`. `:not()` uebernimmt die
   Spezifitaet seines ARGUMENTS: (0,3,3) gegen (0,2,1) der Ausnahmeregel — die Ausnahme
   verlor, die Klasse `grafik` stand im Markup und wirkte nicht.
   🔑 Aufgefallen ist es nur beim Nachsehen im Browser (`getComputedStyle`), nicht im Bau:
   Ein Test haette gesagt „die Klasse ist gesetzt", und sie WAR gesetzt. */
.article img {
  filter: var(--bild-grade);
  border-radius: var(--radius);
  border: 1px solid var(--icke-line);
}
/* 🔴 GRAFIKEN SIND KEINE FOTOS — und der Grund ist BEDEUTUNG, nicht Geschmack.
   `PAL-Wert-Tabelle.png` ist eine farbcodierte Tabelle (blaue/gruene Spalten tragen die
   Struktur), `Lifelong-Learning.png` eine Konjugationstabelle mit gruen markierten Endungen.
   Ein Foto-Grade schwaecht dort eine FUNKTIONALE Unterscheidung, und Radius plus Rahmen um
   eine Datentabelle sehen nach Fehler aus, nicht nach Stil.
   ⚠️ Erkannt ueber ANSEHEN, nicht ueber die Dateiendung: `.png` war das Suchmittel, nicht
   das Merkmal. Gemessen: 173 Fotos gegen 14 Grafiken — deshalb ist die Foto-Behandlung die
   Voreinstellung und die Grafik die benannte Ausnahme, nicht umgekehrt. */
.article img.grafik, .bezahloptionen img, .logo-chip img { filter: none; border: 0; border-radius: 0; }
/* figcaption: Größe UNVERÄNDERT (--fs-small ist der Wert, auf den das alte `--step--1` auflöst).
   🔴 Farbe geändert, und zwar bewusst: Vorher stand `var(--muted, #6b7280)` — `--muted` ist in
   diesem Repo NICHT definiert, es galt also immer der hartkodierte Fallback. Der lag UNTER AA:
   3,08:1 auf dem dunklen ICKE-Grund, 4,10:1 auf Creme. `--text-faint` ist theme-abhängig und
   erfüllt AA in jedem Scope (4,58–4,62). Ein bare-Hex wäre hier ohnehin nicht erlaubt
   (Token-Disziplin-Guard) — der Umzug in die gemeinsame Datei erzwingt die Korrektur. */
.article-figure figcaption { font-size: var(--fs-small); color: var(--text-faint); margin-top: .35em; }
.article-figure--portrait { max-width: 22rem; }
/* 🔴 GEZEICHNETE ERKLAERUNG: eigene Breite, und der Grund ist LESBARKEIT, nicht Geschmack.
   Die Etiketten skalieren mit der Figur. Alle Zahlen im Browser gemessen (getScreenCTM x
   Schriftgrad), nicht gerechnet — der Fliesstext liegt bei 19 px auf allen drei Breiten:
       ohne Deckel, volle Spalte 544 px   Etikett 31,5 px = 1,66x Fliesstext
       mit 24rem-Deckel, 384 px           Etikett 22,2 px = 1,17x Fliesstext
       bei 375 px Fenster, Figur 247 px   Etikett 14,3 px = 0,75x Fliesstext
   ⚠️ Bei 375 px aendert die Regel NICHTS — der Deckel greift erst darueber. Dort ist das
   Etikett KLEINER als der Fliesstext; lesbar, aber es ist die enge Stelle. Wer ein Motiv mit
   mehr Etiketten baut, misst dort zuerst. */
.article-figure--zeichnung { max-width: 24rem; }
.bildnachweis { color: var(--text-faint); font-size: var(--fs-label); margin-top: 2em; }

/* ---- Vertrauensbeleg-Zeile (TrustBar, P1-4a) — statisch, kein Fremd-Load ---- */
.trustbar { background: var(--surface); border-block: 1px solid var(--border); }
.trustbar__inner {
  max-width: var(--content-max); margin-inline: auto; padding: .7rem var(--gutter);
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.4rem;
  font-family: var(--font-grotesk); font-size: .9rem; color: var(--text-muted);
}
.trustbar__rating { display: inline-flex; align-items: baseline; gap: .5rem; text-decoration: none; color: inherit; flex-wrap: wrap; }
.trustbar__rating:hover .trustbar__count { text-decoration: underline; text-underline-offset: 2px; }
.trustbar__stars {
  font-size: 1rem; letter-spacing: .08em; line-height: 1;
  background: linear-gradient(90deg, var(--icke-holz) var(--fill,100%), color-mix(in srgb, var(--text-faint) 55%, transparent) var(--fill,100%));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.trustbar__grade { font-weight: 700; color: var(--signal); font-variant-numeric: tabular-nums; }
.trustbar__of { font-weight: 500; color: var(--text-faint); }
.trustbar__label { color: var(--accent-em); font-weight: 600; }  /* theme-abhängig: Holz (dunkel) / tiefes Ocker (hell) */
.trustbar__count { color: var(--text-muted); }
.trustbar__facts { display: flex; flex-wrap: wrap; gap: .3rem 1.1rem; margin: 0; padding: 0; list-style: none; }
.trustbar__facts li { position: relative; }
.trustbar__facts li + li::before { content: "·"; position: absolute; left: -.7rem; color: var(--text-faint); }
.trustbar__stand { margin-left: auto; font-size: .74rem; color: var(--text-faint); }
@media (max-width: 640px) { .trustbar__stand { margin-left: 0; } }
/* 🔴 Echtheits-Hinweis IN der TrustBar: eine Information, kein Angebot — deshalb ein
   Verweis mit Unterstreichung und kein Knopf. Steht bewusst bei der Note, weil die
   Informationspflicht an die Zugaenglichmachung der Bewertungen knuepft. */
/* 🔴 PFLICHTINFORMATION — deshalb --text-muted und NICHT --text-faint (31.08.2026).
   Gemessen am 31.08.: mit `faint` lag dieser Hinweis bei 4.09 auf --surface, also UNTER AA.
   🔑 Eine Pflichtangabe im schwaechsten verfuegbaren Ton ist eine Gestaltungsentscheidung, die
   die Pflicht untergraebt: erfuellt dem Buchstaben nach, ihrem Zweck nach nicht.
   ⚠️ Und sie ist in genau dem PR entstanden, der die Pflicht erfuellen sollte (#283).
   Mit `muted`: 6.60 (dunkel) / 5.72 (hell) auf --surface. */
.trustbar__echtheit { font-size: .74rem; color: var(--text-muted); text-decoration: underline; text-underline-offset: .15em; }
.trustbar__echtheit:hover, .trustbar__echtheit:focus-visible { color: var(--text); text-decoration-thickness: 2px; }

/* ---- Vollflächiger Foto-Hero (S2: aus index.astro + axt/index.astro zusammengeführt) ----
   War 2× dupliziert — 8 dieser Regeln waren IDENTISCH, `.sub` unterschied sich nur in max-width
   (52ch/50ch → AXT behält einen Einzeiler). Was NICHT hierher kommt, weil es sich echt
   unterscheidet: `.hero-full` selbst (ICKE positioniert das Bild absolut mit min-height, AXT
   setzt die Höhe am Bild) und `.hero-full__img`/`__note`. Die bleiben in den beiden Seiten.
   🔴 Die Textfarben hier sind BEWUSST fix: Sie liegen auf einem Foto mit dunklem Scrim, nicht
   auf einer Theme-Fläche — sie dürfen mit hell/dunkel NICHT mitwandern, sonst verschwindet der
   Text auf dem Bild. Deshalb namentlich im Token-Disziplin-Guard befreit. */
.hero-full .eyebrow { color:var(--icke-creme); }
.hero-full h1 { font-family:var(--font-display);font-weight:var(--fw-semibold);font-size:clamp(2.3rem,5.2vw,3.9rem);line-height:1.02;letter-spacing:-.015em;color:#F4F1E6;margin:.3em 0 0;max-width:16ch;text-wrap:balance; }
.hero-full h1 em { font-style:italic;color:var(--icke-holz); }
/* 🔴 DAS BETONTE WORT WIRD NICHT GETRENNT (31.08.2026).
   Die Silbentrennung fuer schmale Schirme (weiter oben, <=700px) hat auf
   /crossfit-bodyweight/ bei 375px "Body-weight" erzeugt -- mitten im Wort, auf das
   der Blick fallen soll. 🔑 Gefunden durch ANSEHEN: kein Ueberlauf, zwei Zeilen,
   jede Zahl gruen. Der Akzent ist der Gegenstand der Auszeichnung; ihn zu zerlegen
   nimmt ihm genau die Wirkung, fuer die er da ist.
   ⚠️ Gefahrlos, weil Silbentrennung Ueberlauf ohnehin nicht verhindert (am
   31.08. gemessen) -- sie ist rein kosmetisch. */
.hero h1 em, .hero-full h1 em { hyphens: manual; -webkit-hyphens: manual; }
/* 🔴 TEXTSCHATTEN AUF DEM FOTO-HERO — Nico, 31.08.2026:
   „Ich finde allerdings das die Schrift in B am edelsten aussieht. Bekommen wir das
   irgendwie auch in E hin?" — und auf Rueckfrage: „die Schrift ist doch dieselbe.
   Aber durch den Schatten wirkt es edler und wertiger."
   Es ist also der SCHATTEN aus Fassung B, nicht eine andere Schrift.

   🔑 Der Schatten aendert den GEMESSENEN Kontrast um NICHTS: WCAG rechnet aus Vorder-
   und Hintergrundfarbe, Schatten kommen darin nicht vor. Er verbessert den EINDRUCK.
   ⚠️ Deshalb darf er NIE als Begruendung fuer eine zu schwache Farbkombination
   herhalten — wer sagt „da liegt ja ein Schatten drauf", irrt.

   Richtung geprueft, nicht erschlossen: beide Lagen sind DUNKEL (rgba(0,0,0,…)).
   Ein heller Halo haette die Lesbarkeit auf hellem Grund gesenkt, und zwar
   unsichtbar fuer jede Zahl. */
.hero-full .eyebrow,
.hero-full h1 { text-shadow: 0 1px 3px rgba(0,0,0,.55), 0 0 12px rgba(0,0,0,.35); }


.hero-full .sub { font-family:var(--font-serif);font-size:1.15rem;line-height:1.5;color:rgba(244,241,230,.88);margin:.7rem 0 0;max-width:52ch; }
.hero-full .cta { display:flex;flex-wrap:wrap;gap:var(--space-3);margin-top:1.5rem; }
.hero-full__box { max-width:var(--content-max);width:100%;margin-inline:auto;padding:0 var(--gutter) clamp(2rem,4vw,3.5rem); }
.hero-full__inner { position:absolute;inset:0;display:flex;align-items:flex-end; }
/* 🔴 DER SCHLEIER IST AN DAS TEXTBAND GEKOPPELT, NICHT AN EINE PROZENTZAHL (31.08.2026).
   ANLASS: Der Vorgaenger (0,02 -> 0,10 -> 0,72 senkrecht) dunkelte nur den Fuss ab. Gemessen am
   gerenderten Dokument stand der Text aber bei 10-83 % der Hero-Hoehe. Ergebnis: Zeile 0 von 15
   ueber 4,5, Ueberschrift 2 von 15 ueber 3,0, schlechtester Wert 1,01. Belege in
   docs/hero-waerme-2026-08-31.md und docs/hero-kontrast-2026-08-31.md.

   🔑 DIE BEIDEN BAUFORMEN VERANKERN GEGENLAEUFIG, deshalb zwei Verlaeufe:
     Standard      `__inner` liegt absolut -> Text haengt UNTEN  -> oben bleibt Bild frei.
     --unterseite  `__inner` liegt im Fluss -> Text haengt EBENFALLS UNTEN
                   (`.hero-full--unterseite .hero-full__inner { align-items: flex-end }`)
                   -> die Entlastung kommt aus dem UMGEKEHRTEN Verlauf, nicht aus der
                   Textlage: oben 74 %, Abfall erst ab 82 %.
     🔴 KORRIGIERT 05.09.2026: hier stand `--unterseite ... Text haengt OBEN`. Das war seit dem
     04.09. widerlegt (Seitenbau-Sitzung, am gerenderten Dokument gemessen) und stand weit UEBER
     der Regel, die es widerlegt.
     🔑 Verwiesen wird hier bewusst ueber den SELEKTOR, nicht ueber eine Zeilennummer: eine
     Zeilennummer im Kommentar ist ein Verweis mit Verfallsdatum, und genau diese Klasse
     repariert dieser Eintrag. (Hinweis der PM-Suite am selben Tag.) 🔑 Ein Verweis auf `die Quelle` setzt voraus, dass die
     Quelle sich selbst nicht widerspricht -- `gestaltungsregeln-fundstellen.md` schickt jeden
     genau hierher, um die Regel nachzulesen.
   Ein einziger Verlauf muesste beide Enden abdunkeln und damit das ganze Bild.

   ⚠️ DIE MASKE IST IN PIXELN ANGEGEBEN, NICHT IN PROZENT — mit Absicht.
   Die Textbreite haengt an `max-width:16ch` / `52ch`, also an einer LAENGE. Gemessen enden die
   Buchstaben nach 348 px (bei 375), 553 px (bei 768) und 700 px (bei 1280). Eine Prozentangabe
   waere bei einer Breite richtig und bei den anderen falsch. Die 700 px sind das Maximum ueber
   alle 15 gemessenen Kombinationen — wer die Zahl senkt, muss neu messen.
   👉 WIRKUNG: erst ab etwa 1000 px Fensterbreite bleibt rechts Bild unangetastet. Bei 375 und
      768 wirkt die Maske NICHT; dort kommt die Entlastung allein aus dem senkrechten Verlauf.

   🔴 STEHENDE AUFLAGE AN JEDES KUENFTIGE HERO — DER SCHLEIER IST EIN PREIS, KEIN MERKMAL.
   Nico hat diese Fassung gewaehlt und dabei gesagt: „Die Farben der Bilder kommen aber
   natuerlich am schoensten in der linken Spalte zur Geltung" — also OHNE Schleier.
   🔑 Er nimmt den Verlust in Kauf; er haelt ihn nicht fuer geloest. Das ist der Unterschied
   zwischen einer akzeptierten und einer erledigten Sache.
   👉 Wo MOTIV oder AUSSCHNITT die noetige Deckung senken koennen, wird das geprueft, BEVOR
   Deckung addiert wird. Gemessen wird das mit dem Schleier AUS: die noetige Deckung an den
   Zeilen-Rechtecken des Textes, Maximum UND Median. Ein Median nahe 0 heisst Glanzlicht —
   dort hilft ein anderer Ausschnitt. Ein hoher Median heisst flaechig hell — dort hilft nur
   ein anderes Bild. (Verfahren und Zahlen: docs/hero-waerme-2026-08-31.md, Abschnitt ①.)

   🔵 Die Farbe ist warm (38,30,24) statt kuehl (35,40,43). Sie aendert am Kontrast NICHTS —
   nachgemessen: dieselbe Verlaufsform nur mit warmer Farbe ergibt weiterhin 0 von 15. Sie ist
   eine reine Anmutungsentscheidung und traegt keine Zahl. */
.hero-full__scrim { position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(38,30,24,.06) 0%,rgba(38,30,24,.14) 10%,rgba(38,30,24,.74) 20%,rgba(38,30,24,.74) 100%);
  -webkit-mask-image:linear-gradient(90deg,#000 0px,#000 700px,rgba(0,0,0,.10) 1020px);
          mask-image:linear-gradient(90deg,#000 0px,#000 700px,rgba(0,0,0,.10) 1020px); }
/* Text haengt oben -> volle Deckung bis 82 %, danach gibt das Bild wieder frei.
   82 % ist gemessen: der tiefste Punkt eines Vorspanns liegt bei 79 % (/hyrox-berlin/ 1280). */
.hero-full--unterseite .hero-full__scrim {
  background:linear-gradient(180deg,rgba(38,30,24,.74) 0%,rgba(38,30,24,.74) 82%,rgba(38,30,24,.30) 94%,rgba(38,30,24,.14) 100%); }

/* 🔴 SICHERHEITSHINWEIS (.hinweis) — sichtbar abgesetzt, aber KEIN Angebot.
   Anlass (27.08.): Auf den drei Schwangerschafts-/Rueckbildungsseiten trug diese Klasse
   den Hinweis auf Rueckbildungskurs und aerztliche Freigabe — und war UNGESTYLT, las sich
   also wie Fliesstext. Die Klasse zu entfernen haette die Schwaechung festgeschrieben:
   danach waere nicht mehr erkennbar, dass dort je eine Hervorhebung beabsichtigt war.

   🔴 BEWUSST NEUTRAL, NICHT die Bauform von .artikel-cta:
   Jene fuehrt --accent-2 als Linie und liest sich damit als Angebot. Ein Sicherheitshinweis
   endet auf der Sicherheitsaussage; das Angebot steht woanders (PM-Regel 26.08.). Hier
   deshalb kein Akzent, keine CTA-Farbe, kein Knopf — nur Flaeche, Linie, Abstand.

   GEMESSEN (guard/lib/token-kontrast.mjs, 3 Marken x 3 Themes):
     Text auf --surface            11,67-11,77:1   (AA 4,5 deutlich uebererfuellt)
     Linie --text-faint auf --bg    4,58-4,62:1
   🔑 Ein 1px-Rahmen in --border waere WIRKUNGSLOS gewesen: --border gegen --bg misst nur
     1,31-1,57:1. Und --surface gegen --bg misst 1,07-1,13:1 — eine Fuellung allein setzt
     hier NICHTS ab. Die Absetzung traegt allein die 3px-Linie. */
.hinweis {
  margin-block: var(--space-6);
  padding: var(--space-5) var(--space-6);
  background: var(--surface);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-card);
  color: var(--text);
  /* 🔴 KEIN max-width hier: `.article p, .article li { max-width: 42rem }` hat die hoehere
     Spezifitaet (0,1,1 gegen 0,1,0) und gewinnt ohnehin. Eine Deklaration, die nie greift,
     sieht beim Lesen nach Absicht aus — gemessen: computed max-width = 672px = 42rem. */
}

/* ============================================================================
   PREISSEITE (.preisliste) — Nico-Abnahme 27.08.2026: „Preise auf jeden Fall auf
   der Seite ausweisen" + „bitte schoen machen".

   Vorher trugen .preisliste/.preis-karte/.preis/.preis-hinweis/.preis-portal KEINE
   Regel: 23 Angebote stapelten sich als Fliesstext, „KOSTENLOS" und „100 Euro" in
   derselben Groesse wie der Absatz daneben. Die Seite war inhaltlich vollstaendig
   und trotzdem keine Preisdarstellung.

   🔴 GLOBAL, nicht im Seiten-<style>: eine seiten-skopierte Regel wird zu
   `.preis-karte[data-astro-cid-…]` und verliert beim Kopieren ihre Wirkung (#181).

   GEMESSEN (guard/lib/token-kontrast.mjs, 3 Marken x 3 Themes), schlechtester Wert
   jeweils ueber alle neun Kombinationen:
     Kartentitel  --signal     auf --surface   11,67
     Preis-Zahl   --accent-em  auf --surface    4,97   (zusaetzlich Grosstext)
     Kartentext   --text-muted auf --surface    5,72
   Alle ueber AA 4,5. --accent-em ist das einzige Paar davon, das der Guard schon
   fuehrt (PAIRS); die anderen sind hier ausdruecklich nachgerechnet.
   ============================================================================ */
.preisliste { max-width: 62rem; }

/* Zwei Spalten erst, wenn eine Karte darin noch atmen kann. Alles, was keine Karte
   ist (Zwischenueberschriften, Hinweise, Hero, CTA), spannt ueber beide Spalten —
   sonst zerreisst das Raster die Gliederung, die die Seite mitbringt. */
@media (min-width: 860px) {
  .preisliste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
                column-gap: var(--space-5); align-items: start; }
  .preisliste > *:not(.preis-karte) { grid-column: 1 / -1; }
}

.preis-karte {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  margin-block: var(--space-4) 0;
  display: flex; flex-direction: column;
}
.preis-karte h3 {
  font-family: var(--font-grotesk); font-size: var(--fs-h3); font-weight: var(--fw-bold);
  color: var(--signal); margin: 0 0 .3rem; line-height: var(--lh-snug);
}
/* Der Preis ist der Anker der Karte — Grotesk, schwer, Ziffern auf gleicher Breite,
   damit Betraege untereinander ausgerichtet bleiben. */
.preis {
  font-family: var(--font-grotesk); font-weight: var(--fw-black);
  font-size: clamp(1.55rem, 2.8vw, 1.95rem); line-height: 1;
  color: var(--accent-em); font-variant-numeric: tabular-nums;
  margin: 0 0 .55rem;
}
.preis-karte > p:not(.preis):not(.preis-portal) {
  font-family: var(--font-grotesk); font-size: var(--fs-small);
  color: var(--text-muted); margin: 0 0 .5rem; max-width: none;
}
.preis-karte ul { margin: auto 0 0; padding-left: 1.05rem; }
.preis-karte li {
  font-family: var(--font-grotesk); font-size: var(--fs-small);
  color: var(--text-muted); margin: .3rem 0; max-width: none;
}
.preis-karte li::marker { color: var(--text-faint); }
.preis-karte .cta-knopf { margin-top: var(--space-4); }

/* PAngV-Hinweis: sichtbar abgesetzt, aber ruhig — er ist eine Gueltigkeitsangabe,
   kein Angebot. Deshalb Linie statt Flaeche und kein Akzent. */
.preis-hinweis {
  border-left: 3px solid var(--text-faint);
  padding: .35rem 0 .35rem var(--space-4);
  font-family: var(--font-grotesk); font-size: var(--fs-small);
  color: var(--text-muted); font-style: normal;
  margin-block: var(--space-5);
}
/* Mitgliedschaften haben KEINEN festen Preis auf der Seite — sie stehen tagesaktuell
   im Portal. Der Verweis bekommt deshalb die Preis-Position, nicht eine Zahl. */
.preis-portal {
  font-family: var(--font-grotesk); font-size: var(--fs-small);
  color: var(--text); margin: 0 0 .25rem; max-width: none;
}


/* ============================================================================
   KURSPLAN (eigene Ansicht, 29.08.2026) — global, nicht im Seiten-<style>:
   Lehre aus #181/#191, Astro skopiert Seiten-Styles und sie verlieren beim Kopieren
   bzw. bei zur Laufzeit erzeugtem Markup ihre Wirkung.

   GEMESSEN (3 Marken x 3 Themes, schlechtester Wert je Paar):
     Datum/Programm  --signal     auf --surface   11,67
     Uhrzeit         --accent-ink auf --surface    4,97
     Nebentext       --text-muted auf --surface    5,72
   ============================================================================ */
.kursplan { margin-block: var(--space-6); }
.kursplan__stand {
  font-family: var(--font-grotesk); font-size: var(--fs-small);
  color: var(--text-muted); margin: 0 0 var(--space-5); max-width: none;
}
/* Spaltenzahl kommt aus der verfuegbaren Breite, nicht aus einer geratenen Schwelle:
   1 Spalte am Telefon, 2 am Tablet, 3 am Schreibtisch (--content-max 1200px).
   `min(100%, 19rem)` verhindert Ueberlauf, wenn die Spur schmaler als 19rem ist.
   🔴 19rem, NICHT 21rem: mit 21rem passten bei 768px zwei Spalten samt Abstand rechnerisch
   NICHT mehr (2×336px + gap > 688px Innenbreite) — das Raster fiel dort auf EINE Spalte
   zurueck, also schlechter als die feste 760px-Schwelle vorher. Gemessen, nicht geschaetzt:
   768px→2 · 1024px→2 · 1280px→3. Wer diesen Wert anfasst, misst bei 768 nach. */
.kursplan__tage {
  list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
}
.kursplan__tag {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-card); padding: var(--space-5); margin: 0; max-width: none;
}
.kursplan__datum {
  font-family: var(--font-grotesk); font-size: var(--fs-label); font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--signal); margin: 0 0 var(--space-4);
}
.kursplan__kurse { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.kursplan__kurs {
  /* 30.08.2026: dritte Spalte entfernt — sie trug die Belegungszahl, die nicht mehr
     gezeigt wird. Eine leere Spalte im Raster ist kein Rest, sie verschiebt den Namen. */
  display: grid; grid-template-columns: 4.2rem 1fr; gap: .6rem; align-items: baseline;
  font-family: var(--font-grotesk); font-size: var(--fs-small); margin: 0; max-width: none;
}
.kursplan__zeit { color: var(--accent-ink); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.kursplan__name { color: var(--signal); }
/* Open Gym als EINE Zeile — und mit dem Satz, der das Erwartungsproblem verhindert. */
.kursplan__opengym {
  margin: var(--space-4) 0 0; padding-top: var(--space-4); border-top: 1px solid var(--border);
  font-family: var(--font-grotesk); font-size: var(--fs-small); color: var(--text-muted); max-width: none;
}
.kursplan__opengym strong { display: block; color: var(--signal); font-variant-numeric: tabular-nums; }
/* Die Erklaerung ist die zweite Aussage, nicht die Fortsetzung der ersten. Als eigene Zeile
   statt per Gedankenstrich angehaengt: bei drei Spalten brach der zusammengezogene Satz auf
   VIER Zeilen und wog damit schwerer als die Kurszeilen darueber, die die Seite eigentlich
   zeigen soll. Der Wortlaut ist unveraendert — nur die Verbindung ist jetzt ein Umbruch
   statt eines Gedankenstrichs. */
/* Kein eigener Groessen-Token: die Zeile erbt --fs-small vom Elternteil. Ein Verweis auf
   ein NICHT existierendes `--fs-xsmall` haette ueber seinen Rueckfallwert funktioniert und
   waere als Phantom stehengeblieben — die Trennung leistet hier die Farbe, nicht die Groesse. */
.kursplan__opengym span { display: block; color: var(--text-faint); }
/* 🔴 Der ehrliche Zustand: keine Zeiten, sondern der Weg zur verbindlichen Quelle. */
.kursplan__alt {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-card); padding: var(--space-5) var(--space-6);
}
.kursplan__alt-titel { font-family: var(--font-grotesk); font-weight: var(--fw-bold); color: var(--signal); margin: 0 0 .5rem; }
.kursplan__alt p { color: var(--text-muted); margin: .4rem 0; max-width: none; }
.kursplan__alt .cta-knopf { margin-top: var(--space-4); }

/* 🔴 NÄCHSTE TERMINE (29.08.2026) — kompakte Terminliste eines Programms auf einer
   Inhaltsseite. Bewusst schmaler als der Kursplan: hier geht es um „wann kann ich
   kommen", nicht um den Wochenrhythmus. Zahlen tabellarisch, damit Uhrzeiten und
   Plätze untereinander stehen und der Blick springen kann. */
.termine { margin-block: var(--space-4); }
.termine__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); max-width: 32rem; }
.termine__zeile {
  /* 30.08.2026: dritte Spalte entfernt (Belegung). */
  display: grid; grid-template-columns: 7.5rem 1fr; align-items: baseline;
  gap: var(--space-3); padding: var(--space-3) var(--space-4); margin: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
}
.termine__datum { font-family: var(--font-grotesk); font-weight: var(--fw-bold); color: var(--text); }
.termine__zeit  { font-variant-numeric: tabular-nums; color: var(--signal); font-weight: var(--fw-semibold); }
.termine__stand { font-size: var(--fs-small); color: var(--text-faint); margin: var(--space-3) 0 0; max-width: none; }
.termine__alt   { font-size: var(--fs-small); color: var(--text-muted); }
@media (max-width: 30rem) {
  .termine__zeile { grid-template-columns: 6.5rem 1fr; }
}

/* Kursarten-Liste (/kursangebot/, 29.08.2026) — 15 kurze Einträge, zweispaltig ab Tablet.
   Bewusst als Liste und nicht als Bildkacheln: Die Bilder der Live-Seite tragen zu 86 %
   altes Branding und werden separat nachgezogen. Die Namen verlinken hier auf ihre
   Detailseiten — live waren es Kacheln ohne Textlink. */
.kursarten { list-style: none; margin: var(--space-5) 0 0; padding: 0; display: grid; gap: var(--space-4); }
@media (min-width: 46rem) { .kursarten { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kursart {
  margin: 0; padding: var(--space-4) var(--space-5); max-width: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card);
}
.kursart__name { font-size: 1.05rem; margin: 0 0 var(--space-2); }
.kursart__text { margin: 0; font-size: var(--fs-small); color: var(--text-muted); max-width: none; }

/* ---- Shop-Produktseiten (Migration 31.08.2026) ----------------------------------------
   🔴 Beide Klassen stammen 1:1 aus der laufenden WooCommerce-Seite und sind bewusst
   uebernommen worden, nicht erfunden. `.cart` ist dort das Formular um den Kaufknopf —
   die Kaufstrecke funktioniert in unserem Stack NICHT (registrierter Blocker); das Markup
   steht trotzdem, weil Weglassen eine stille Entscheidung waere.
   🔑 Regeln statt Klassen entfernen: guard/klassen-ohne-regel faengt genau den Fall, dass
   Markup Klassen traegt, die niemand anspricht — und die Antwort darauf ist eine Regel
   oder ein sauberer Schnitt, nicht eine Befreiung. */
.bezahloptionen { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-block: .4rem 1rem; }
.bezahloptionen img { height: 1.9rem; width: auto; }
.cart { margin-block: 1rem 1.4rem; }

/* ── Teamkarten: ZURUECKGEZOGEN am 31.08.2026 ────────────────────────────────
   Die Regeln standen hier fuer zehn Team-Portraits, die am selben Tag wieder raus
   mussten (Nico: „Teamfotos muessen wir neu machen. Sind nicht mehr aktuell.").
   🔑 Regeln OHNE Markup sind kein Guard-Fall — `guard/klassen-ohne-regel` faengt die
   Gegenrichtung. Sie waeren also still liegen geblieben und beim naechsten Anlauf
   fuer aktuell gehalten worden. Deshalb raus statt auskommentiert.
   👉 Was sie geloest haben, steht im Protokoll (docs/bildsichtung-2026-08-31.md) und
   ist beim Wiederaufbau in fuenf Minuten zurueck: Raster mit `auto-fill minmax(15rem)`,
   Ausbruch aus der Lesebreite auf die Hero-Breite, KEIN `object-fit: cover`
   (die Personen stehen unterschiedlich weit links/rechts).
   ⚠️ Der Hero-Ausbruch fuer lange Woerter (`min-width: 0` bei `.hero__grid > *`) bleibt —
   der gehoerte nie zu den Teamkarten, er wurde nur an ihnen gefunden. */

/* ---- Vollflächiger Foto-Hero, UNTERSEITEN-Fassung (31.08.2026) ------------------
   🔴 ENTSCHEIDUNG DER PM-SUITE, auf Nicos Rueckmeldung „Hero-Bilder sind in der Regel noch
   nicht wie gewuenscht gebaut, sondern klein neben den Ueberschriften":
   Die vollflaechige Form gilt fuer alle — die Hierarchie Start/Unterseite wandert von der
   BAUFORM in die PROPORTION. Startseiten min(78vh,660px), Unterseiten flacher.

   🔑 GEMESSEN VOR DER ENTSCHEIDUNG: Von 160 gebauten Seiten hatten 2 die vollflaechige Form
   und 15 die Kachel — und die 2 waren GENAU die beiden Startseiten. Das war keine Unordnung,
   sondern eine ungeschriebene Regel. Deshalb wird sie nicht weggeworfen, sondern verschoben.

   ⚠️ WARUM ALS EIGENE KLASSE UND NICHT IN DIE SEITEN KOPIERT: Der Container stand bisher je
   Seite im eigenen <style> — bei zwei Seiten vertretbar, bei fuenf ist es die Dublette, die
   spaeter auseinanderlaeuft. Die beiden Startseiten bleiben unangetastet: sie unterscheiden
   sich echt (ICKE positioniert das Bild absolut, AXT setzt die Hoehe am Bild), und sie
   funktionieren. 🔑 Vereinheitlichen heisst nicht, Funktionierendes anzufassen.

   🔴 WO KEIN TRAGFAEHIGES BILD IST, WIRD DIESE KLASSE NICHT BENUTZT — dann bleibt ein reiner
   Textkopf. Eine vollflaechige LEERE Flaeche ist schlimmer als eine leere Kachel.

   ⚠️ Der Filter ist derselbe wie auf den beiden Startseiten (saturate 1.04 / contrast 1.05),
   damit alle vollflaechigen Heros gleich aussehen. Er weicht von `--bild-grade` (.85/1.03) ab,
   das fuer Inhaltsbilder gilt — zwei Werte im Bestand, gemeldet, hier nicht stillschweigend
   vereinheitlicht.
   🔵 SAETTIGUNG 31.08.2026 von .92 auf 1.04 angehoben, an allen drei Stellen (hier und in den
   beiden Startseiten). Grund: Nico hat die Heros als „zu flach" und die alte Fassung als
   „waermer" bezeichnet — ein Teil davon war die Entsaettigung, nicht die Helligkeit. Gemessen:
   Kontrast unveraendert (Zeile 15/15, Ueberschrift 15/15, Vorspann 15/15, gleiche Extremwerte),
   mittlere Saettigung ueber die 15 Heros 21,0 % -> 21,7 %.
   👉 EIGENER HEBEL: Diese Zeile kostet keinen Kontrast und kann einzeln zurueckgenommen werden,
      ohne dass die Kontrastzahlen neu erhoben werden muessen. Die drei Stellen gehoeren zusammen. */
/* ⚠️ KEINE eigene Hintergrundflaeche: Das Bild liegt `inset:0` darueber und deckt sie. Eine
   Farbe hier waere ein rohes Paletten-Token in components.css — der Token-Disziplin-Guard
   verlangt dort semantische, und die Befreiungsliste liegt in fremdem Territorium.
   🔑 Die ICKE-Startseite setzt an derselben Stelle ebenfalls keine Flaeche. Faellt das Bild
   aus, greift die Seitenflaeche — das ist der richtige Rueckfall, nicht eine zweite Farbe. */
.hero-full--unterseite { position: relative; overflow: hidden;
  border-radius: 0 0 var(--radius-xl) var(--radius-xl); }
.hero-full--unterseite .hero-full__img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 45%; filter: saturate(1.04) contrast(1.05); }
/* 🔴 DER INHALT LIEGT HIER IM FLUSS, NICHT ABSOLUT — und das ist der Unterschied zur Startseite.
   ANLASS, gemessen beim ersten Anlauf: Mit dem Startseiten-Muster (`__inner` absolut, Hoehe ueber
   `min-height` am Container) war der Hero 374px hoch und sein Inhalt 396px. Weil absolut
   positionierter Inhalt NICHTS zur Hoehe beitraegt, schob er sich um 22px nach OBEN — die
   Eyebrow-Zeile verschwand hinter der klebenden Kopfleiste.
   🔑 Das Startseiten-Muster funktioniert nur, WEIL es hoch ist: bei min(78vh,660px) ist der
   Inhalt nie groesser. Eine flachere Fassung erbt den Fehler, den die Hoehe bisher zugedeckt hat.
   👉 Deshalb traegt hier der Inhalt die Hoehe, und `min-height` ist nur noch ein BODEN. */
.hero-full--unterseite .hero-full__inner { position: static; display: flex; align-items: flex-end;
  min-height: min(52vh, 440px); }
.hero-full--unterseite .hero-full__box { position: relative; padding-top: clamp(2.5rem, 6vw, 4rem); }

/* ============================================================================
   PHYSIO-INTAKE — /patientenerfassung-physio-v1/

   🔴 ANLASS, gemessen bei der Sichtpruefung am 05.09.2026: Die Seite bestand ALLE
   sechs eigenen Guards (noindex · keine Fremd-Loads · echter Datenschutz-Link · beide
   Messereignisse ohne Inhalt · Absenden gesperrt) — und war am Handy unbenutzbar.
   Label und Feld lagen nebeneinander, der Text lief ueber den rechten Rand.
   🔑 Gruene Guards heissen nicht, dass eine Seite richtig aussieht.

   ⚠️ ZWEITER ANLASS, ebenfalls am selben Tag: die erste Fassung dieses Blocks trug
   `var(--token, #hexwert)`-Rueckfaelle. Der Token-Guard hat sie als GETARNTE
   Hardcode-Farben gemeldet — zu Recht: ein Rueckfall auf einen festen Hexwert ist eine
   Palette, die nur so lange unsichtbar bleibt, wie das Token existiert.
   👉 Nur semantische Tokens, ohne Rueckfall.

   Mobile-first: Label UEBER dem Feld, volle Breite, Tap-Flaechen >= 44 px.
   ============================================================================ */
.intake { max-width: 46rem; }
.intake__lead { font-size: var(--fs-body); }

/* 🔴 Der sichtbare Blocker. Er soll auffallen — er ist der Ausloeser dafuer, dass die
   Seite noch nicht fertig ist, und verschwindet gemeinsam mit dem Endpunkt. */
.intake__sperre {
  display: block; margin: 1.5rem 0; padding: 1rem 1.1rem;
  border-left: 4px solid var(--accent);
  background: var(--surface);
  border-radius: var(--radius-card); line-height: 1.5;
}
.intake__sperre strong { display: block; margin-bottom: .25rem; }

.intake__form fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  margin: 1.75rem 0; padding: 1rem 1.1rem 1.25rem;
}
.intake__form legend { font-weight: 600; padding: 0 .4rem; }

/* 🔴 24.10.2026 — DER SEITENKOERPER SCROLLTE BEI 375 px DOCH QUER, und die Zeile weiter
   unten bei `.intake__tabelle` behauptet seit jeher das Gegenteil: „Die Preistabelle
   scrollt in IHREM Kasten — der Seitenkoerper nie quer."
   🔑 URSACHE, im Browser gemessen mit EINER geaenderten Groesse und zurueckgenommen: ein
   `fieldset` traegt per Browser-Default `min-inline-size: min-content` und weigert sich
   deshalb, unter die Mindestbreite seines Inhalts zu schrumpfen — das `overflow-x: auto`
   der Tabelle laeuft dadurch ins Leere.
     vorher   clientWidth 375 · scrollWidth 388 · Feldset 364 px · min-inline-size min-content
     mit `0`  clientWidth 375 · scrollWidth 375 · Feldset 327 px   ⇒ Ueberlauf weg
     zurueck  scrollWidth 388                                     ⇒ Ursache belegt
   ⚠️ Das ist eine REPARATUR und keine Erweiterung: sie stellt her, was der Kommentar bei
   `.intake__tabelle` seit jeher zusichert. Ein Kommentar, der einen Schutz behauptet, den
   es nicht gibt, liest sich weiter wie eine Zusicherung — und ein Test waere rot geworden,
   ein Kommentar wird geglaubt.
   🔵 REICHWEITE GEMESSEN, nicht geschaetzt: `.intake__form` steht in GENAU EINER Datei
   (`src/pages/patientenerfassung-physio-v1.astro`, 8 Feldsets). Kein anderes Formular im
   Korpus ist beruehrt — die uebrigen fuenf nutzen eigene Klassen. */
.intake__form fieldset { min-inline-size: 0; }

/* 🔴 Label UEBER dem Feld — das war der Fehler in der ersten Fassung. */
.intake__form label { display: block; margin: .9rem 0 0; line-height: 1.4; }
.intake__form input[type="text"],
.intake__form input[type="email"],
.intake__form input[type="tel"],
.intake__form input[type="date"],
.intake__form select {
  display: block; width: 100%; box-sizing: border-box;
  margin-top: .35rem; padding: .6rem .7rem;
  min-height: var(--tap-min);
  font: inherit; color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-btn);
}
.intake__form input:focus-visible,
.intake__form select:focus-visible,
.intake__form button:focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }

/* 🔴 Tap-Flaeche: die ganze Zeile ist anklickbar, nicht nur das Kaestchen.
   Gemessen war sie vorher 19 px hoch. */
.intake__check, .intake__radio {
  display: flex; align-items: flex-start; gap: .6rem;
  min-height: var(--tap-min); padding: .45rem 0; cursor: pointer;
}
.intake__check input, .intake__radio input {
  flex: 0 0 auto; width: 1.15rem; height: 1.15rem; margin-top: .15rem;
}

.intake__optional { font-weight: 400; color: var(--text-muted); }
.intake__hinweis { margin: .6rem 0 0; font-size: var(--fs-small); color: var(--text-muted); line-height: 1.5; }

/* ── Zeichenfeld fuer die handschriftliche Unterschrift (24.10.2026) ──────────
   🔴 NUR SEMANTISCHE TOKEN. Tinte und Papier des Bildes stehen im SKRIPT, nicht hier:
   das PNG verlaesst die Seite und wird in einem anderen Betrachter gezeigt, wo unsere
   Token nicht gelten — eine themenabhaengige Unterschrift waere dort unsichtbar.
   🔴 `touch-action: none` ist die tragende Zeile, nicht Schmuck: ohne sie scrollt die
   Seite, waehrend jemand mit dem Finger unterschreibt, und es entsteht kein Strich.
   🔵 `aspect-ratio` statt fester Hoehe — der Puffer bleibt 600x200 (Groessengrenze des
   Endpunkts), die Anzeige skaliert mit. */
.intake__sig { margin: 1rem 0 0; }
.intake__sig-titel { display: block; font-weight: 600; margin-bottom: .35rem; }
.intake__sig-feld {
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  touch-action: none; cursor: crosshair;
}
.intake__sig-aktionen { margin-top: .5rem; }
.intake__sig-aktionen button {
  min-height: var(--tap-min); padding: .5rem .9rem; font: inherit;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-btn); cursor: pointer;
}
.intake__sig-aktionen button:focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }

/* ── Erfolgsansicht und Quittungs-Knopf (24.10.2026) ─────────────────────────
   Die Hausform der anderen Formulare: `1px solid currentColor`, Fehler-/Erfolgsfall
   ueber die Form, nicht ueber Farbe. Es gibt im Korpus kein Erfolgs-Farbtoken. */
/* 🔴 KEIN `display` HIER — 24.10.2026 gemessen und entfernt. Es stand `display: block`,
   und das UEBERSTEUERT das `hidden`-Attribut: ein Klassenselektor im Autoren-Stylesheet
   schlaegt die `[hidden]`-Regel des Browsers. Die Folge war im gesperrten Zustand
   unsichtbar und waere beim Scharfschalten sofort sichtbar geworden: die Erfolgsmeldung
   „Danke, deine Angaben sind angekommen" stand auf der Seite, BEVOR jemand etwas
   abgeschickt hatte (gemessen bei 375 px: hidden=true, display=block, Hoehe 234 px).
   🔑 Die Deklaration war ausserdem WIRKUNGSLOS: `<aside>` ist von Haus aus Block. Sie hat
   nichts hinzugefuegt und eine Zusicherung des Markups gebrochen. */
.intake__erfolg {
  margin: 1.5rem 0; padding: 1rem 1.1rem;
  border: 1px solid currentColor; border-radius: var(--radius-card); line-height: 1.5;
}
.intake__erfolg strong { display: block; margin-bottom: .25rem; }

/* Fehler-Ansicht: dieselbe Hausform, der Fehlerfall unterscheidet sich ueber `border-style`
   und nicht ueber Farbe — wie bei allen anderen Formularen im Korpus. */
/* 🔴 Ebenfalls ohne `display` — siehe `.intake__erfolg` oben. `<p>` ist von Haus aus Block;
   die Deklaration hat nur das `hidden`-Attribut ausgehebelt (gemessen: Hoehe 152 px). */
.intake__meldung {
  margin: 0 0 1.25rem; padding: 1rem 1.1rem;
  border: 1px solid currentColor; border-radius: var(--radius-card); line-height: 1.5;
}
.intake__meldung--fehler { border-style: dashed; }
.intake__meldung strong { display: block; margin-bottom: .25rem; }
.intake__meldung:focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }
.intake__erfolg:focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }
.intake__quittung { margin: .9rem 0 0; }
.intake__quittung-knopf {
  display: inline-block; min-height: var(--tap-min);
  padding: .6rem 1rem; font: inherit;
  color: var(--on-cta); background: var(--cta);
  border-radius: var(--radius-btn); text-decoration: none;
}
.intake__quittung-knopf:focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }

/* Die noch fehlende Schweigepflichtentbindung — sichtbar als Luecke, nicht als Text. */
.intake__luecke {
  margin: .5rem 0 1rem; padding: .85rem 1rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-card); line-height: 1.55;
}

/* 🔴 Die Preistabelle scrollt in IHREM Kasten — der Seitenkoerper nie quer. */
.intake__tabelle { overflow-x: auto; margin: .5rem 0 1rem; }
.intake__tabelle table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.intake__tabelle th, .intake__tabelle td {
  padding: .45rem .6rem; text-align: left; border-bottom: 1px solid var(--border);
}
.intake__tabelle th { font-weight: 600; }
.intake__tabelle td + td { text-align: right; white-space: nowrap; }

.intake__ds { margin: 1.5rem 0; line-height: 1.6; }
.intake__form button[type="submit"] {
  min-height: var(--tap-min); padding: .7rem 1.4rem;
  font: inherit; font-weight: 600; border-radius: var(--radius-btn);
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
}
.intake__form button[type="submit"][disabled] { opacity: .55; cursor: not-allowed; }

@media (min-width: 48rem) { .intake__form fieldset { padding: 1.25rem 1.5rem 1.5rem; } }

/* ============================================================================
   VIDEO-VERWEISE — Form A (Karte) und Form B (Zeile).
   🔴 Anlass: Nicos Ansage vom 06.09.2026, Form A+B von ihm gewaehlt.
   🔑 Alle Farben ueber Tokens: die Seiten tragen [data-register="dark"] — gemessen am
   gebauten Bestand, 185 von 185. Wer hier einen Festwert einsetzt, bricht das creme
   gefuehrte Physio-Register mit, ohne es zu sehen.
   ============================================================================ */
.video-verweis { margin: 0 0 var(--space-3, 1rem); }
/* 🔴 Nur der TITEL ist der Link — sonst wird der zugaengliche Name des Anchors
   „Kanal + Titel + oeffnet YouTube" und der anchor-guard wird zu Recht rot.
   Anklickbar bleibt die ganze Flaeche ueber das ::after darunter. */
.video-verweis {
  position: relative;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
}
.video-verweis:hover { border-color: var(--accent-ink); }
.video-verweis:has(a:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.video-verweis a { color: inherit; text-decoration: none; }
.video-verweis a::after { content: ""; position: absolute; inset: 0; }
.video-verweis .vv-titel { display: block; font-family: var(--font-body); color: var(--text); }

/* --- Form A: Titelkarte --- */
.video-verweis--karte { padding: 1.1rem 1.25rem 0.95rem; }

/* 🔴 Vorschaubild der Titelkarte — steht NUR dort, wo eine LOKALE Datei existiert
   (VideoKarte.astro prueft mit existsSync). YouTube liefert `hqdefault` als 480x360,
   also 4:3 mit schwarzen Balken; der KASTEN entscheidet hier, nicht das Bild —
   aspect-ratio + object-fit schneiden die Balken weg. Dieselbe Bauform wie VideoKlick.
   ⚠️ width/height am <img> setzen die ANZEIGEgroesse nicht, sie verhindern nur den
   Layout-Sprung beim Laden. */
.video-verweis--karte img.vv-bild { display: block; width: 100%; height: auto; margin: 0 0 .75rem; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 6px; }
.video-verweis--karte .vv-kanal {
  display: flex; align-items: center; gap: 0.45rem;
  font-family: var(--font-ui); font-size: 0.72rem; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--accent-ink);
}
.video-verweis--karte .vv-kanal::before {
  content: ""; flex: none; width: 0; height: 0;
  border-left: 8px solid var(--accent-ink);
  border-top: 5px solid transparent; border-bottom: 5px solid transparent;
}
.video-verweis--karte .vv-kanal, .video-verweis--karte .vv-fuss, .video-verweis--karte .vv-titel { margin: 0; }
.video-verweis--karte .vv-titel { font-size: 1.25rem; line-height: 1.32; margin: 0.55rem 0 0.7rem; }
.video-verweis--karte .vv-fuss {
  display: flex; justify-content: space-between; gap: 0.6rem;
  font-family: var(--font-ui); font-size: 0.72rem; color: var(--text-muted);
  border-top: 1px solid var(--border); padding-top: 0.55rem;
}

/* --- Form B: Zeile mit Signatur --- */
.video-verweis--zeile { margin-bottom: 0.45rem; }
.video-verweis--zeile { display: flex; align-items: center; gap: 0.8rem; padding: 0.7rem 0.8rem; }
.video-verweis--zeile .vv-sig {
  display: block; flex: 0 0 46px; width: 46px; height: 46px;
  border-radius: 7px; overflow: hidden; background: var(--surface-2);
}
.video-verweis--zeile .vv-sig svg { display: block; width: 46px; height: 46px; }
.video-verweis--zeile .vv-text { display: block; min-width: 0; flex: 1 1 auto; }
.video-verweis--zeile .vv-titel {
  font-size: 1rem; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.video-verweis--zeile .vv-meta {
  display: block; font-family: var(--font-ui); font-size: 0.7rem;
  color: var(--text-muted); margin-top: 0.2rem;
}

/* 🔴 Herkunft einmal ueber der Liste — siehe src/components/video/VideoQuelle.astro.
   Sie steht ausserhalb der Karten, damit sie fuer die ganze Liste gilt und nicht
   fuer den ersten Eintrag. */
.video-quelle {
  font-family: var(--font-ui); font-size: 0.78rem; color: var(--text-muted);
  margin: 0 0 0.6rem; letter-spacing: 0.02em;
}
.video-quelle strong { color: var(--accent-ink); font-weight: 600; }
