/* schrift.css */
/* Schrifteinbindung — ausschliesslich lokale Dateien aus src/assets/schriften/.
   Herkunft und Lizenz der Schriften: src/assets/schriften/LIZENZ.md

   Nach dem Seiten-Nachbau (Phase 3) nachgezaehlt: Alle fuenf hier eingebundenen
   Schnitte werden benutzt. Inter 700 traegt h1 bis h4, Inter 600 die Knoepfe, die
   Navigation, das Karten-Label, die Schrittnummern und die Namen der Kundenstimmen.
   Open Sans 400 ist der Fliesstext, Open Sans 600 die hervorgehobene Ergebniszeile
   der Kundenstimmen, Open Sans 700 kommt ueber einige Dutzend <strong> in
   Ueber-uns, Impressum und Datenschutz. Der sechste Schnitt, Inter 400, war von keiner Regel angesprochen
   — Block und WOFF2-Datei sind deshalb entfallen (--schrift-headline steht an genau
   sechs Stellen, jede setzt ein Gewicht von 600 oder 700). */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../schriften/inter-600.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../schriften/inter-700.woff2') format('woff2');
}

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../schriften/open-sans-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../schriften/open-sans-600.woff2') format('woff2');
}

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../schriften/open-sans-700.woff2') format('woff2');
}

/* basis.css */
/* Basis: Design-Tokens, Reset, Typografie, Buttons.
   Header- und Footer-Regeln gehoeren nach layout.css, nicht hierher. */

/* 1. Design-Tokens ------------------------------------------------------- */

:root {
  --primaer: #0077b6;
  --primaer-dunkel: #023e8a;
  --text: #1a1a1a;
  --text-gedaempft: #666666;
  /* Gedaempfter Text auf faerbenden Flaechen. #666 traegt auf Weiss (5,74:1) und
     Grau (5,45:1), faellt auf der 20-%-Blauflaeche aber auf 4,02:1 und verfehlt
     damit WCAG AA fuer Normaltext. Dieser Ton haelt dort 6,18:1 (ueber #e6f7ff)
     bzw. 6,72:1 (ueber Weiss) und bleibt optisch ein Grauton. */
  --text-gedaempft-stark: #4a4a4a;
  --weiss: #ffffff;
  --flaeche-hell: #e6f7ff;
  /* Heller Sektionsgrund (Abschnitte 8, 10 und 13 der Startseite). */
  --flaeche-grau: #f8f9fa;
  /* Blaue Flaeche mit 20 % Deckkraft: Hero, Finder-Aufruf, Terminblock, Footer.
     Die Vorlage nennt hier #0277b633; uebernommen wird der Blauton der Vereinbarung
     (#0077b6) mit derselben Deckkraft, weil die beiden Blautoene der Live-Seite
     bewusst auf einen vereinheitlicht wurden. Abgeleitet statt ausgeschrieben:
     Ein geaenderter --primaer zieht die Flaeche mit, statt still von ihr
     wegzudriften. */
  --flaeche-blau: color-mix(in srgb, var(--primaer) 20%, transparent);
  /* Zweiter Halt des Verlaufs im Kernprodukte-Abschnitt. */
  --flaeche-cyan: #90e0ef;
  /* Footer-Flaeche — derselbe Blauton, damit es nur einen gibt. */
  --flaeche-fuss: var(--flaeche-blau);
  --schatten: 0 2px 8px rgba(0, 0, 0, .07);
  /* Knopfschatten: derselbe Blauton wie der Knopf selbst, ebenfalls abgeleitet. */
  --schatten-knopf: 0 2px 8px color-mix(in srgb, var(--primaer) 8%, transparent);
  --linie: #e5e7eb;
  --radius: 10px;
  --schrift-headline: 'Inter', system-ui, sans-serif;
  --schrift-text: 'Open Sans', system-ui, sans-serif;
  --breite-max: 1200px;
}

/* 2. Reset --------------------------------------------------------------- */

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

body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
ul,
ol {
  margin: 0;
}

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

a {
  color: inherit;
}

/* 3. Basis-Typografie und Seitenrahmen ----------------------------------- */

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

body {
  font-family: var(--schrift-text);
  color: var(--text);
  background: var(--flaeche-hell);
  line-height: 1.6;
  font-size: clamp(16px, 1rem + 0.2vw, 18px);
}

h1,
h2,
h3,
h4 {
  font-family: var(--schrift-headline);
  font-weight: 700;
  line-height: 1.2;
  /* Deutsche Komposita wie "Versicherungsmakler" sind auf 360px breiter als die
     Textspalte und wuerden sonst ueber den Seitenrahmen hinauslaufen. */
  overflow-wrap: break-word;
}

h1 {
  font-size: clamp(2rem, 1.5rem + 2.2vw, 2.75rem);
}

h2 {
  font-size: clamp(1.5rem, 1.2rem + 1.3vw, 2rem);
}

h3 {
  font-size: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
}

h4 {
  font-size: 1.125rem;
}

.inhalt-breite {
  max-width: var(--breite-max);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
}

.skip:focus {
  left: 0;
  z-index: 100;
  background: var(--weiss);
  color: var(--primaer);
  padding: 12px 24px;
  border: 2px solid var(--primaer);
  border-radius: var(--radius);
}

/* 4. Buttons ------------------------------------------------------------- */

.knopf {
  display: inline-block;
  background: var(--primaer);
  color: var(--weiss);
  padding: 12px 24px;
  font-family: var(--schrift-headline);
  font-weight: 600;
  border: 0;
  border-radius: var(--radius);
  box-shadow: var(--schatten-knopf);
  text-decoration: none;
  cursor: pointer;
}

.knopf:hover {
  background: var(--primaer-dunkel);
}

.knopf:focus-visible {
  outline: 3px solid var(--primaer-dunkel);
  outline-offset: 2px;
}

/* ponytail: Eine zweite Knopf-Variante (Umriss) und ein Akzent-Token gab es hier,
   ohne dass sie irgendwo verwendet wurden — entfernt. Phase 3 fuehrt sie mit dem
   ersten echten Anwendungsfall wieder ein. */

/* layout.css */
/* Layout: Header und Footer. Nutzt ausschliesslich die Tokens aus basis.css —
   hier wird keine Farbe und keine Groesse neu als Rohwert definiert.
   Grundzustand ist die schmale Ansicht (Burger), Desktop ab 1200px — der
   Umschaltpunkt ist weiter unten ausfuehrlich begruendet und haengt mit der
   matchMedia-Zeile in nav.js und dem Feld navOffen in
   pruefung/layout-pruefung.mjs zusammen. */

/* 1. Header -------------------------------------------------------------- */

.kopf {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--weiss);
  border-bottom: 1px solid var(--linie);
}

.kopf__innen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  padding-block: 0.75rem;
}

/* Seit dem Telefonlink stehen DREI Dinge in der Kopfzeile. justify-content:
   space-between haette sie gleichmaessig verteilt und den Telefonlink in die
   Mitte gestellt; gewollt ist Logo links, alles andere rechts. Das auto-Rand
   nimmt den freien Platz hinter dem Logo auf — space-between bleibt stehen und
   liefert bei zwei Elementen (falls hier je eines wegfaellt) dasselbe Bild. */
.kopf__logo {
  margin-right: auto;
}

/* ponytail: min() statt zweiter Media-Query — 200px, auf sehr schmalen
   Geraeten automatisch kleiner, damit neben dem Burger Platz bleibt. */
.kopf__logo img {
  width: min(200px, 45vw);
  height: auto;
}

/* Telefonnummer in der Kopfzeile (Ticket d338c8f6). Der Link traegt in JEDER
   Breite nur das Symbol, als 44x44-Flaeche — dasselbe Tippziel wie der Burger
   daneben; die Nummer steht im aria-label. Warum nicht ausgeschrieben: siehe die
   Messung am Umschaltpunkt weiter unten.
   margin-right trennt die beiden Tippziele — ohne ihn grenzen die 44x44-Flaechen
   von Hoerer und Burger in der schmalen Ansicht unmittelbar aneinander. Ab 1200px
   ueberschreibt die Media-Query den Wert (Messung dort), sie bleibt unberuehrt.
   Farbe: --primaer-dunkel und nicht --primaer. Der Kopf steht auf --weiss, wo
   beide AA halten; das Anruf-Band der Startseite (.anruf__nummer a in
   seite-startseite.css) und die Fusslinks tragen aus Kontrastgruenden bereits
   diesen Ton (Begruendung bei .fuss__bereiche a), und zwei Telefonlinks
   derselben Seite in zwei Blautoenen waeren ohne Grund verschieden. */
.kopf__telefon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin-right: 0.5rem;
  color: var(--primaer-dunkel);
  text-decoration: none;
}

/* Ohne Groesse faellt ein <svg> ohne width/height-Attribute auf die
   Ersatzgroesse 300x150 zurueck. */
.kopf__telefon svg {
  flex: none;
  width: 24px;
  height: 24px;
}

.kopf__telefon:hover {
  color: var(--primaer);
}

.kopf__telefon:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

.kopf__burger {
  display: block;
  padding: 10px;
  background: none;
  border: 0;
  cursor: pointer;
}

.kopf__burger:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

.kopf__balken {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--text);
}

.kopf__balken + .kopf__balken {
  margin-top: 5px;
}

.nav {
  display: none;
  flex-basis: 100%;
}

.kopf--offen .nav {
  display: block;
}

.nav ul {
  list-style: none;
  padding: 0;
}

.nav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--schrift-headline);
  font-weight: 600;
  text-decoration: none;
}

.nav a:hover,
.nav a:focus-visible {
  color: var(--primaer);
}

.nav a:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

.nav .knopf {
  display: inline-flex;
  margin-block: 0.5rem;
  color: var(--weiss);
}

.nav .knopf:hover,
.nav .knopf:focus-visible {
  color: var(--weiss);
}

/* Der Ring darf nicht die Farbe der Flaeche haben, die er umgibt: .nav
   a:focus-visible (0,2,1) schlaegt .knopf:focus-visible aus basis.css (0,1,1) und
   legte damit den Primaerton um den Knopf, der selbst in diesem Ton gefuellt ist —
   zu erkennen war der Ring nur an der 2px breiten Luecke des outline-offset. Der
   dunklere Ton setzt sich von beidem ab. Betrifft genau den Punkt, den ein
   Tastaturnutzer auf /versicherungsfinder/ als aktiven anspringt. */
.nav .knopf:focus-visible {
  outline-color: var(--primaer-dunkel);
}

/* Aktive Seite hervorheben. Das Merkmal setzt der Build als aria-current="page" —
   damit traegt es zugleich die Ansage fuer Screenreader und muss beim Anlegen einer
   neuen Seite nicht mehr hier nachgepflegt werden. */
.nav a[aria-current="page"] {
  color: var(--primaer);
  text-decoration: underline;
  text-underline-offset: 6px;
}

/* Seit Ticket d14bd1fa fuehrt der Knopf auf eine eigene Seite — er kann also selbst
   der aktive Punkt sein. Die Regel darueber wuerde ihm dort den Primaerton geben,
   und der steht auf der Primaerflaeche des Knopfes praktisch unsichtbar. Deshalb
   bleibt die Schrift weiss; das Aktivmerkmal traegt allein die Unterstreichung, die
   auf der Flaeche gut zu sehen ist. Die hoehere Spezifitaet ist der ganze Zweck der
   Regel. */
.nav .knopf[aria-current="page"] {
  color: var(--weiss);
}

/* Umschaltpunkt zwischen Burger und offener Navigation. Er stand bis Phase 4 auf
   768px und bis Phase 9 auf 1024px; mit dem sechsten Punkt („Ratgeber") misst die
   Reihe 865px — neben dem 200px breiten Logo und den 40px Seitenrand braucht sie
   damit 1105px. Bei 1024px brach sie in eine zweite Kopfzeile um (gemessen: der
   Kopf wurde 107 statt der damaligen 77px hoch). Ein Umbruch in eine zweite Zeile
   ist kein gewollter Zustand, und Schrumpfen von Schrift oder Abstaenden brachte die
   fehlenden 85px nicht zusammen — der Burger ist dort der ehrlichere Zustand.
   Mit dem siebten Punkt („Blog", Ticket bcd59018) mass die Reihe 928px, also 1168px
   mit Logo und Seitenrand — einzeilig bei 1200px, aber nur noch mit rund 32px
   Reserve. Seit Ticket d14bd1fa sind es wieder sechs Punkte; der letzte ist dafuer
   ein Knopf mit eigener Beschriftung. Gemessen bei 1200x800 (Stand 2026-08-20):
   Reihe 764px, davon 227px der Knopf; mit dem 200px breiten Logo und 40px
   Seitenrand 1004px, Kopfhoehe 77,8px — einzeilig, Reserve rund 196px. Die
   Beschriftung des Knopfes bleibt trotzdem der Engpass: Die Fassung „… – Jetzt
   Direktabschluss" mass 971px Reihe und brach in eine zweite Kopfzeile um (gemessen:
   Kopfhoehe 108px). Wer die Beschriftung verlaengert oder einen Punkt ergaenzt, misst
   neu.
   Die Reserve haengt an der geladenen Webschrift (Open Sans). Deshalb einmal
   gegengemessen, was ohne sie passiert (Schriftdateien im Browser geblockt, es
   greift der Rueckfall system-ui, sans-serif — auf diesem Arbeitsplatz Segoe UI):
   Reihe 722px, mit Logo und Seitenrand 962px, Kopfhoehe unveraendert 77,8px,
   einzeilig. Der Rueckfall laeuft also SCHMALER als die Webschrift, die Reserve
   waechst dort auf rund 238px. Ein fehlendes Schriftpaket oder das
   font-display-Fenster bricht die Kopfzeile damit nicht — die Messung deckt
   allerdings nur diesen einen Rueckfall ab, ein Schirm mit anderer Systemschrift
   ist damit nicht vermessen.
   Nachgemessen am 2026-09-16 mit dem Telefonlink (Ticket d338c8f6), 1200x800:
   Reihe 763,7px, Telefonlink 44px + 24px Abstand, Logo 200px, Seitenrand 40px —
   zusammen 1071,7px, Reserve 128,3px, Kopfhoehe unveraendert 77,8px, einzeilig.
   Mit AUSGESCHRIEBENER Nummer im Link ginge das nicht mehr auf: Der Link misst
   dann 193,1px, die Summe 1220,8px — die Reihe brach in eine zweite Kopfzeile um
   (gemessen: Kopfhoehe 121,8px). Und zwar auf JEDER Bildschirmbreite, denn
   .kopf__innen traegt .inhalt-breite und ist damit bei 1200px gedeckelt; ein
   breiterer Schirm schafft hier keinen Platz mehr. Die kleinere Schrift
   (0.9375rem) passte mit 166,2px zwar wieder hinein, liess aber nur 6,1px
   Reserve (mit auf 1rem verkuerztem Abstand 14,1px) — zu wenig fuer eine Reihe,
   die schon zweimal genau hier umgebrochen ist und deren Breite an der
   geladenen Schrift haengt. Deshalb traegt der Kopf nur das Symbol (Christopher
   2026-09-16: "Das Symbol fuer die Telefonnummer passt"); ausgeschrieben steht
   die Nummer im Anruf-Band und im Schnellkontakt der Startseite sowie im
   Impressum — im Fuss seit dem 2026-09-16 auf seinen Wunsch nicht mehr.
   ACHTUNG: Diese Zahl gehoert mit der matchMedia-Zeile in nav.js und dem Feld
   `navOffen` in pruefung/layout-pruefung.mjs zusammen — wer sie hier aendert,
   aendert sie dort. */
@media (min-width: 1200px) {
  .kopf__burger {
    display: none;
  }

  /* Hier faellt der Burger weg — der Telefonlink steht also unmittelbar vor der
     Navigationsreihe und haelt zu ihr denselben Abstand, den die Punkte der
     Reihe untereinander halten (das gap unten). */
  .kopf__telefon {
    margin-right: 1.5rem;
  }

  .nav {
    display: block;
    flex-basis: auto;
  }

  .nav ul {
    display: flex;
    align-items: center;
    gap: 1.5rem;
  }

  .nav a {
    min-height: 0;
  }

  .nav .knopf {
    margin-block: 0;
  }
}

/* 2. Inhaltsbereich ------------------------------------------------------- */

/* Der Header klebt oben. Ohne diesen Abstand landet der Skip-Link genau darunter,
   also auf verdecktem Text — und trifft damit die Nutzergruppe, fuer die er da ist. */
#inhalt {
  scroll-margin-top: 5rem;
}

/* 3. Footer -------------------------------------------------------------- */

.fuss {
  background: var(--flaeche-fuss);
  border-top: 1px solid var(--linie);
  padding-block: 2.5rem;
}

.fuss__innen {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  text-align: center;
}

.fuss__innen img {
  width: 200px;
  height: auto;
}

/* Die Bereichszeile sieht aus wie die Rechtszeile darunter — beide sind schlichte
   Linkreihen mit Trennstrich. Deshalb eine gemeinsame Regel statt einer zweiten
   Kopie derselben drei Zustaende; seit dem 2026-08-20 teilen sie auch die Farbe. */
.fuss__bereiche a,
.fuss__recht a {
  text-decoration: none;
}

/* Alle Fusslinks — die drei Hubs und die Rechtszeile — tragen
   denselben kontrastfesten Ton. Gerechnet auf der halbtransparenten Fussflaeche,
   also 20 % --primaer ueber dem Seitengrund: --primaer kommt dort auf 3,40:1
   (ueber #e6f7ff) bzw. 3,67:1 (ueber Weiss auf der Terminseite) und verfehlt WCAG
   AA fuer Normaltext deutlich, --primaer-dunkel haelt 7,13:1 bzw. 7,70:1.
   Die Rechtszeile lief bis 2026-08-20 als Vorbestand auf --primaer und ist jetzt
   mitgezogen: Zwei unmittelbar benachbarte Linkzeilen in zwei Farben, deren
   einziger Unterschied ein bekannter AA-Verstoss ist, sind weder gestalterisch
   noch fachlich zu halten. */
.fuss__bereiche a,
.fuss__recht a {
  color: var(--primaer-dunkel);
}

.fuss__bereiche a:hover,
.fuss__recht a:hover {
  text-decoration: underline;
}

.fuss__bereiche a:focus-visible,
.fuss__recht a:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

/* Die Fussflaeche ist halbtransparent, der Kontrast haengt also am Seitengrund:
   #666 kaeme auf 4,02:1 (ueber #e6f7ff) bzw. 4,35:1 (ueber Weiss auf der
   Terminseite) und verfehlt WCAG AA fuer Normaltext auf jeder Seite. Der
   dunklere Grauton haelt 6,18:1 bzw. 6,72:1. */
.fuss__copy {
  color: var(--text-gedaempft-stark);
  font-size: 0.9rem;
}

/* Statuszeile nach § 1 Abs. 5 StRVV (Firma, Maklerbezeichnung, GISA-Zahl,
   Registerlink). Sie muss "deutlich sichtbar" sein — deshalb dieselbe Groesse
   wie die Copyright-Zeile und nicht kleiner, derselbe kontrastfeste Grauton;
   der Registerlink folgt den uebrigen Fusslinks. */
.fuss__status {
  color: var(--text-gedaempft-stark);
  font-size: 0.9rem;
  line-height: 1.6;
  max-width: 60ch;
}

.fuss__status a {
  color: var(--primaer-dunkel);
}

.fuss__status a:hover {
  text-decoration: underline;
}

.fuss__status a:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

/* bausteine.css */
/* Bausteine: die Muster, die alle Inhaltsseiten teilen — Sektionen, Karten, Listen,
   Knopf-Zweitvariante, Platzhalter. Kopf und Fuss stehen in layout.css, Tokens und
   Grundtypografie in basis.css.

   Farben und Masse kommen ausschliesslich aus den Tokens: hier steht kein roher
   Farbwert. Wer eine neue Farbe braucht, legt sie in basis.css als Token an.
   Die Klassennamen sind der Vertrag fuer die Seitenplaene 03-02 bis 03-05 und
   werden nicht umbenannt. */

/* 1. Sektionen ----------------------------------------------------------- */

/* Eine Sektion laeuft ueber die volle Breite; begrenzt wird erst der innere
   Container. Ohne Flaechen-Modifikator bleibt der helle Seitengrund sichtbar —
   die Seite hat eine durchgehende Farbflaeche, Sektionen sind darauf transparent. */
.sektion {
  padding-block: 2.5rem;
}

.sektion--weiss {
  background: var(--weiss);
}

.sektion--grau {
  background: var(--flaeche-grau);
}

.sektion--blau {
  background: var(--flaeche-blau);
}

/* Der Verlauf traegt weissen Text. Die Vorlage laesst ihn von #0077b6 glatt bis
   #90e0ef laufen — dort steht Weiss in der Verlaufsmitte nur noch bei 2,6:1 und
   verfehlt WCAG AA deutlich. Beide Vorlagenfarben und die Verlaufsrichtung bleiben
   erhalten; nur der Aufhellungsbereich ist in die letzten 30 % geschoben. Gemessen
   (1440x900, 900x900, 360x740) liegt der weisse Kopftext zwischen 3,5 % und 67 %
   der Verlaufslinie und damit vollstaendig auf dem flachen #0077b6 — 4,87:1 fuer
   Normal- und Grosstext. Die helle Ecke unten rechts liegt hinter bzw. unter den
   weissen Karten, wo kein weisser Text steht. */
.sektion--verlauf {
  background: linear-gradient(135deg, var(--primaer) 0, var(--primaer) 70%, var(--flaeche-cyan) 100%);
  color: var(--weiss);
}

.sektion--verlauf h2,
.sektion--verlauf h3,
.sektion--verlauf p {
  color: var(--weiss);
}

/* Gegenregel zur Zeile darueber, direkt neben ihrer Ursache: Karten bringen ihre
   eigene weisse Flaeche mit — ohne diese Regel stuende dort Weiss auf Weiss.
   Sie stand bis zum Review in seite-startseite.css und haette jede weitere Seite
   mit .sektion--verlauf + .karte unlesbar gemacht. */
.sektion--verlauf .karte h3,
.sektion--verlauf .karte p {
  color: var(--text);
}

/* Innerer Container. Die Breitenbegrenzung kommt aus .inhalt-breite, das im Markup
   daneben steht (`class="sektion__innen inhalt-breite"`) — hier steht bewusst kein
   zweites max-width, nur der Bezugsrahmen fuer abgesetzte Elemente. */
.sektion__innen {
  position: relative;
}

.sektion__kopf {
  margin-bottom: 2rem;
  text-align: center;
}

.sektion__unterzeile {
  color: var(--text-gedaempft);
  max-width: 60ch;
  margin-inline: auto;
}

/* Auf faerbenden Sektionen wuerde der gedaempfte Grauton absaufen. */
.sektion--verlauf .sektion__unterzeile {
  color: var(--weiss);
}

/* Auf der 20-%-Blauflaeche kommt #666 nur auf 4,02:1 — unter WCAG AA fuer
   Normaltext. Derselbe Grauton eine Stufe dunkler haelt dort 6,18:1. */
.sektion--blau .sektion__unterzeile {
  color: var(--text-gedaempft-stark);
}

/* 2. Karten -------------------------------------------------------------- */

/* Grundzustand ist eine Spalte (schmale Geraete); die Modifikatoren teilen erst
   ab 768px auf. Die Kopfnavigation schaltet seit Phase 9 erst bei 1200px um
   (layout.css) — das ist bewusst ein anderer Punkt: Karten koennen schmaler
   werden, eine Navigationsreihe nicht. */
.karten {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}

/* Deutsche Komposita sind laenger als jede Spalte, die drei Karten auf einem
   Tablet uebrig lassen: „Krankenversicherung" misst allein 235px. Ohne Trennung
   waere das die Mindestbreite der Spalte — genau daran ist das Kartenraster bei
   768px ueber den Viewport hinausgelaufen (aufgefallen mit dem Tablet-Viewport in
   layout-pruefung.mjs). `hyphens` trennt sauber am Wortstamm (die Seite ist
   lang="de-AT"), `overflow-wrap` ist der Rueckfall fuer Browser ohne
   Trennmuster. */
.karte {
  background: var(--weiss);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  hyphens: auto;
  overflow-wrap: break-word;
}

/* Das display:flex oben ist eine Autorenregel und schlaegt damit die
   Browser-Regel fuer [hidden] — eine mit hidden ausgezeichnete Karte stuende
   ohne diese Zeile trotzdem auf der Seite. Aufgefallen bei Ticket 1de93fff auf
   /antrag/, wo es gleich drei Karten betraf (Hinweis-Kasten, Erfolgs-Kasten,
   Unterlagen-Karte). Die Regel steht hier und nicht auf der Seite: Sie gehoert
   zum Baustein, sonst braucht sie jede kuenftige Seite mit versteckter Karte
   noch einmal. */
.karte[hidden] { display: none; }

/* Zentriert steht der Kartentext seit Ticket d14bd1fa auf ALLEN Seiten und nicht
   mehr nur auf der Startseite: Eine Kachel mit kurzer Beschriftung ist ein
   geschlossener Block, kein Lesetext, und auf 360px stand sie je nach Seite mal so
   und mal so. Die Startseite ist der Massstab — dort sind Kacheln seit Ticket
   197dea4c zentriert (abgenommen und deployt). Ausgenommen sind die Kacheln, deren
   Inhalt Lesetext IST: die Hub-Listen unten und die beiden Karten auf /ratgeber/
   (seite-ratgeber.css).
   Ab 768px wird die Angabe unten wieder zurueckgenommen: Dort stehen Kacheln
   nebeneinander, die Zeilen werden kuerzer und linksbuendig liest sich besser.
   Der Desktop bleibt damit unangetastet — genau das ist der Zweck der
   Rueckstellung, nicht bloss ein Nebeneffekt.

   Die Ausrichtung steht als eigene Regel in :where() — Spezifitaet 0,0,0. Sie und
   ihre Ruecknahme ab 768px duerfen keine seiteneigene Ausrichtung schlagen:
   .vorteil (seite-ueber-uns.css) sowie .weg, .produkt, .schritt und .stimme
   (seite-startseite.css) haben je 0,1,0 und gewinnen damit auf jeder Breite —
   vorher hing genau das an der Reihenfolge der <link>-Zeilen in layout.html, weil
   beide Seiten dieselbe Spezifitaet hatten. Nur die Ausrichtung ist entschaerft,
   nicht die Flaechenangaben oben: Zu denen gibt es keine seiteneigene Gegenregel,
   und 0,0,0 waere dort eine Schwaechung ohne Nutzen. */
:where(.karte) {
  text-align: center;
}

/* Hub-Karten tragen Fliesstext, keine Kachelbeschriftung: Titel und Auszug sind
   vier bis sieben Zeilen und lesen sich nur an einer Kante — zentriert flattern
   beide Textkanten und das Auge findet den Zeilenanfang nicht. Die Kachel selbst
   bleibt zentriert (Bild, Datum), der Lesetext darin nicht.
   0,2,0 und damit staerker als die :where()-Regeln oben und unten: Diese Ausnahme
   gilt bewusst auf JEDER Breite — ab 768px stuende der Text ohnehin links. */
.liste .karte {
  text-align: left;
}

/* Silbentrennung glaettet eine flatternde Kante — bei zentriertem Text gibt es
   keine, dort bleiben nur die Trennstriche als Rauschen. Gemessen bei 360px ueber
   die Zeilenkaesten: In den zentrierten Kachel-Absaetzen der Startseite stehen 16
   Trennstriche (.weg, .produkt, .schritt und der Absenden-Hinweis), auf
   /ueber-uns/ in den zwoelf zentrierten Kacheltexten keiner.
   Ab 768px bleibt die Trennung, denn dort hat sie ihren Grund: Ein deutsches
   Kompositum ist die Mindestbreite seiner Spalte und hat das Kartenraster bei
   768px ueber den Viewport geschoben (siehe .karte oben). Auf 360px steht die
   Kachel allein in ihrer Spalte, und `overflow-wrap: break-word` bleibt als
   Rueckfall stehen — Ueberbreite kann daraus nicht entstehen, layout-pruefung.mjs
   misst sie je Element mit.
   Die Regel deckt auch die beiden linksbuendigen Ausnahmen mit ab (Hub-Karten,
   /ratgeber/). Dort waere die Trennung nicht falsch, aber eine zweite Regel nur
   fuer sie waere mehr Pflegestelle als Gewinn: 272px Spaltenbreite lassen wenig
   Flattern uebrig. */
@media (max-width: 767.98px) {
  .karte {
    hyphens: manual;
  }
}

/* 3. Knopf-Zweitvariante -------------------------------------------------- */

/* Sekundaer-CTA der Vorlage: weisser Grund, blauer Rahmen, beim Ueberfahren gefuellt.
   Ergaenzt .knopf aus basis.css, ersetzt es nicht — beide Klassen stehen zusammen. */
.knopf--umriss {
  background: var(--weiss);
  color: var(--primaer);
  border: 2px solid var(--primaer);
  box-shadow: none;
}

.knopf--umriss:hover {
  background: var(--primaer);
  color: var(--weiss);
}

/* 4. Listen und Bilder ---------------------------------------------------- */

.liste-haken {
  list-style: none;
  padding: 0;
}

.liste-haken li {
  position: relative;
  padding-left: 1.75rem;
}

.liste-haken li::before {
  content: "\2714";
  position: absolute;
  left: 0;
  color: var(--primaer);
}

.bild-rund {
  border-radius: 50%;
  object-fit: cover;
  aspect-ratio: 1;
}

/* 5. Einbettungen --------------------------------------------------------- */

/* Rahmen fuer die GHL-Widgets. Die .platzhalter-box, die hier bis Phase 5 stand,
   ist ersatzlos entfallen — seit den beiden echten Einbettungen nutzt sie keine
   Seite mehr.

   Die Hoehe ist bewusst eine UNTERGRENZE und keine feste Angabe: Das
   form_embed.js von api.leadconnectorhq.com ist ein iframeResizer, der die
   Inhaltshoehe im Widget misst und sie per postMessage als inline height an das
   iframe schreibt. min-height wirkt daneben als Boden — ein zu kurz gemeldetes
   Widget wird nicht abgeschnitten, ein hoeheres darf wachsen. Eine feste height
   wuerde genau dieses Nachziehen verhindern. */
/* Der Container bekommt bewusst KEINE Breitenangabe. Ein div fuellt als Blockbox
   ohnehin die verfuegbare Breite und zieht dabei seine eigenen Raender ab; ein
   width: 100% haette dagegen die volle Elternbreite gefordert und die Raender
   obendrauf gelegt — eine Einbettung in einer Karte mit Innenabstand ragte auf
   360px genau um diesen Abstand heraus. Der Fall ist in Phase 5 einmal
   aufgetreten (layout-pruefung.mjs) und bleibt fuer jede kuenftige Einbettung
   in einer Karte ausgeschlossen.
   Das iframe darunter braucht die Angabe sehr wohl: Als ersetztes Element bringt
   es eine eigene Vorgabebreite von 300px mit. */
.einbettung iframe {
  display: block;
  width: 100%;
  border: 0;
}

/* Der Buchungskalender braucht auf dem Desktop rund 780px. Auf schmalen Geraeten
   stapelt GHL Monatsraster und Zeitliste untereinander statt nebeneinander —
   dort liegt die Untergrenze deshalb deutlich hoeher. */
.einbettung[data-ghl-kalender] iframe {
  min-height: 780px;
}

@media (max-width: 600px) {
  .einbettung[data-ghl-kalender] iframe {
    min-height: 1000px;
  }
}

/* Zwei-Klick-Consent (Ticket 2c2834dc): Vor dem Klick traegt das iframe nur
   data-src — der leere Rahmen wuerde sonst mit seiner min-height als weisse
   Flaeche unter der Consent-Karte stehen. Nach dem Klick setzt
   kalender-consent.js die src und blendet die Karte aus. */
.einbettung[data-ghl-kalender] iframe:not([src]) {
  display: none;
}

.kalender-consent {
  padding: 24px;
  text-align: center;
}

.kalender-consent p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-gedaempft);
  max-width: 46ch;
  margin: 0 auto 16px;
  text-align: left;
}

/* 6. Abschlussbild -------------------------------------------------------- */

/* Die Vorlage setzt diese Sektion auf padding-top/-bottom 0 — das Bild schliesst
   direkt an den Footer an. Steht auf Ueber uns, Impressum und Datenschutz und
   gehoert damit zu den geteilten Mustern; bis zum Review lag der Block dreimal
   wortgleich in den drei Seitendateien. */
.abschlussbild {
  padding-block: 0;
}

.abschlussbild img {
  width: 100%;
}

/* 7. Sicherheitsnetz ------------------------------------------------------ */

/* Seiten ohne Sektionsaufbau (Impressum, Datenschutz, spaeter der Rechner) haengen
   sonst randlos am Fensterrand: main traegt seit Phase 3 keine Breitenbegrenzung
   mehr, weil vollflaechige Sektionen bis zum Rand laufen muessen. */
main > :not(.sektion) {
  max-width: var(--breite-max);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

/* 8. Blogbeitraege und Rasseprofile --------------------------------------- */

/* Diese Muster teilen sich Blog- und Rassenbereich vollstaendig: Beide Hubs
   zeigen dieselbe Liste, beide Beitragsarten haben dieselben Kopf- und
   Fussbausteine (V12). Sie stehen deshalb hier und nicht zweimal in
   seite-blog.css und seite-rasse.css. Wirklich bereichseigen ist nur das
   Datum in der Blog-Liste und die Steckbrief-Tabelle der Rasseprofile. */

/* Brotkruemelnavigation ueber der H1 (V6). Sie steht als direktes Kind von <main>
   und bekommt Breite und Seitenrand vom Sicherheitsnetz weiter oben. */
.brotkrumen {
  padding-top: 1.5rem;
  font-size: 0.9rem;
  color: var(--text-gedaempft-stark);
}

.brotkrumen ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
  list-style: none;
  padding: 0;
}

/* Das Trennzeichen gehoert zur Darstellung, nicht zum Text: Als ::before landet es
   weder in der Vorlesereihenfolge noch in der Zwischenablage. */
.brotkrumen li + li::before {
  content: "\203A";
  margin-right: 0.5rem;
}

/* Hub-Liste. Das Markup erzeugt build.mjs; jeder Eintrag traegt zusaetzlich .karte,
   Flaeche und Innenabstand kommen also von dort. */
.liste {
  display: grid;
  gap: 1.5rem;
  list-style: none;
  padding: 0;
}

.liste__titel {
  font-size: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
}

.liste__titel a {
  text-decoration: none;
}

.liste__titel a:hover {
  color: var(--primaer);
  text-decoration: underline;
}

.liste__titel a:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

.liste__leer {
  color: var(--text-gedaempft);
}

/* Vorschaubild einer Kachel. Breite, Hoehe und Blockdarstellung kommen aus dem
   Reset in basis.css (`img { max-width: 100%; height: auto; display: block }`) —
   hier bleibt genau das uebrig, was das Bild in die Karte einpasst. Es steht als
   erstes Kind der Karte; den Abstand zum Titel setzt das `gap` von .karte.
   Kein voller Anschnitt bis zum Kartenrand: Das kostete einen negativen Rand in
   der Breite des Karten-Innenabstands und braeche, sobald der sich aendert. */
.liste__bild {
  border-radius: var(--radius);
}

/* Autorenzeile direkt unter der H1 (V15). Ohne Foto: Die Portraets stehen auf
   /ueber-uns/, wohin der Name verlinkt — eine zweite Kopie waere eine zweite
   Pflegestelle. */
.autorenzeile {
  max-width: 70ch;
  margin-top: 0.75rem;
  font-size: 0.9rem;
  color: var(--text-gedaempft-stark);
}

/* Der Fliesstext eines Beitrags oder Rasseprofils. Dasselbe Zeilenmass wie auf
   Ueber uns: ueber 70 Zeichen wird eine Zeile auf grossen Schirmen unlesbar. */
.beitrag {
  max-width: 70ch;
}

.beitrag h2 {
  margin-top: 2.5rem;
}

/* Deckt zugleich die Fragen des FAQ-Abschnitts ab — sie stehen als h3 (V12). */
.beitrag h3 {
  margin-top: 1.75rem;
}

.beitrag p,
.beitrag ul,
.beitrag ol,
.beitrag table {
  margin-top: 0.75rem;
}

.beitrag li + li {
  margin-top: 0.25rem;
}

/* Titelbild unter der Autorenzeile. Die <figure> braucht einen eigenen Abstand:
   Der Reset nimmt ihr den Vorgabe-Rand des Browsers, und die Abstandsregel eine
   Zeile weiter oben nennt nur p, ul, ol und table. Etwas grosszuegiger als der
   Fliesstext-Abstand — das Bild schliesst den Kopfbereich des Beitrags ab. */
.beitrag__bild {
  margin-top: 1.5rem;
}

.beitrag__bild img {
  border-radius: var(--radius);
}

/* Alle Textlinks der beiden Bereiche in einer Regel — sie stehen alle auf dem
   hellen Seitengrund und teilen dieselbe Begruendung.
   --primaer kommt dort auf 4,43:1 und verfehlt WCAG AA fuer Normaltext (4,5:1);
   --primaer-dunkel haelt 9,28:1, auf der 20-%-Blauflaeche der CTA-Box noch 7,13:1.
   Gleiche Korrektur wie in Phase 4 beim Budget-Hinweis des Versicherungsfinders
   und beim Namen auf der Terminseite.
   Das :not(.knopf) ist kein Beiwerk: .beitrag a (0,2,0) schlaegt .knopf (0,1,0) und
   haette den gefuellten CTA-Knopf in der Box blau auf blau gefaerbt. */
.brotkrumen a,
.autorenzeile a,
.quellen a,
.beitrag a:not(.knopf) {
  color: var(--primaer-dunkel);
}

/* CTA-Box. Genau zwei je Seite (V14): eine nach dem Versicherungsabschnitt, eine am
   Seitenende. Kein Popup, kein Overlay — das ist der einzige CTA-Fehler mit
   belegtem Ranking-Effekt. */
.cta-box {
  background: var(--flaeche-blau);
  border-radius: var(--radius);
  padding: 1.5rem;
  margin-top: 2rem;
}

/* Die Ueberschrift ist das erste Kind der Box. Ohne die erste Zeile erbt sie
   .beitrag h3 { margin-top: 1.75rem } und stuende mit einem Loch von fast zwei
   Zeilen unter dem eigenen Innenabstand.
   Zentriert steht auf schmalen Geraeten nur noch sie (Ticket d14bd1fa, ab 768px
   unten zurueckgesetzt): Die Box ist ein Handlungsaufruf mitten im Fliesstext und
   soll sich von ihm absetzen, das leistet die Ueberschrift zusammen mit der
   Knopfreihe darunter. Die beiden Absaetze DAZWISCHEN sind Lesetext und bleiben
   linksbuendig — die Box steht in <article class="beitrag">, und die
   Beitragsfliesstexte sind eine namentliche Bestandsausnahme des Tickets. Der
   zweite Absatz ist ausserdem der Provisionsoffenlegungssatz und steht auf 51
   Beitragsseiten je zweimal; zentrierter Flattersatz ueber drei bis fuenf Zeilen
   ist ausgerechnet dort die schlechteste Darstellung. */
.cta-box h3 {
  margin-top: 0;
  text-align: center;
}

/* Die Knopfreihe ist ein Flexcontainer — text-align der Box greift hier nicht,
   die Ausrichtung macht justify-content (dasselbe Muster wie .hero__aktionen in
   seite-startseite.css). */
.cta-box__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1rem;
  justify-content: center;
}

/* Abgrenzungshinweis am Ende jedes Gesundheitsabschnitts (V15). Abgesetzt, aber
   ohne Warnfarbe: Er ordnet ein, er warnt nicht. */
.hinweis {
  border-left: 4px solid var(--primaer);
  padding: 0.75rem 1rem;
  margin-top: 2rem;
  font-size: 0.95rem;
  color: var(--text-gedaempft-stark);
}

/* Quellenblock am Beitragsende (V15): ein bis drei Primaerquellen mit Abrufdatum. */
.quellen {
  margin-top: 2.5rem;
  font-size: 0.9rem;
  color: var(--text-gedaempft-stark);
}

/* Wie bei der CTA-Box: Der Block bringt seinen Abstand schon mit, das erbte
   .beitrag h2 { margin-top: 2.5rem } addierte sich sonst darauf. */
.quellen h2 {
  margin-top: 0;
}

.quellen ul {
  padding-left: 1.25rem;
}

/* Quellenangaben fuehren die URL teils als reinen Text mit (statt als Link mit
   kurzem Ankertext). Eine solche URL ist ein einziges, unumbrechbares Wort und
   schob den Quellenblock auf 360px um bis zu 123px ueber den Rand — belegt von
   layout-pruefung.mjs auf /hunderassen/labrador-retriever/. "anywhere" statt
   "break-word", weil nur ersteres auch in die Mindestbreite des Elements
   eingeht: Der Umbruch muss schon bei der Breitenberechnung gelten, nicht erst
   beim Fuellen der Zeile. */
.quellen li {
  overflow-wrap: anywhere;
}

/* 9. Chat-Knopf ------------------------------------------------------------ */

/* Der Chat haengt an keiner Seitenquelle: src/assets/js/chat.js baut Knopf und
   Consent-Karte auf jeder Seite per JS. Hier stehen nur ihre Stile.

   Der Anker spannt sich ueber die volle Breite (left UND right gesetzt), statt
   nur rechts zu kleben: Damit begrenzt der Elternrahmen die Karte, und sie kann
   auf 360px nicht ueber den Viewport hinausragen — ohne eine 100vw-Rechnung, die
   die Bildlaufleiste mitzaehlt. Die Ueberbreiten-Wache in layout-pruefung.mjs
   nimmt zwar position: fixed aus, seine KINDER misst sie aber weiter.
   Klicks faengt der Streifen nicht ab (pointer-events: none), sonst laege ein
   unsichtbares Band ueber der ganzen Breite des Seitenfusses.

   z-index 60: ueber dem klebenden Kopf (50, layout.css), unter dem Skip-Link
   (100, basis.css) — der Sprung zum Inhalt bleibt in jedem Fall klickbar.

   Bewusst ohne Ein- und Ausblend-Animation. Dann gibt es auch nichts, was
   prefers-reduced-motion abzuschalten haette. */
.chat-anker {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  pointer-events: none;
}

.chat-knopf,
.chat-consent {
  pointer-events: auto;
}

.chat-knopf {
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--primaer);
  box-shadow: var(--schatten);
  cursor: pointer;
}

/* Die Pfote (chat.js) fuellt den Knopf ganz aus; ihr blauer Grund ist derselbe
   --primaer wie der des Knopfes darunter, und ihre Ecken sind transparent — das
   Motiv ist schon ein Kreis. border-radius ist nur die Versicherung fuer den
   Fall, dass die Pfote je als Quadrat geliefert wird. display: block nimmt die
   Grundlinienluecke, die ein inline-Bild sonst unten anhaengt. */
.chat-knopf img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

/* Seit dem Bild statt des Symbols (2026-09-16) waere ein Hintergrundwechsel
   unsichtbar — die Pfote deckt den Knopf vollstaendig ab. Deshalb wird er beim
   Ueberfahren minimal groesser statt dunkler; nur mit echtem Zeiger, damit auf
   dem Handy nach dem Antippen kein vergroesserter Knopf haengen bleibt. */
@media (hover: hover) {
  .chat-knopf:hover {
    transform: scale(1.06);
  }
}

.chat-knopf:focus-visible {
  outline: 3px solid var(--primaer-dunkel);
  outline-offset: 2px;
}

/* Die Karte haengt fix am unteren Rand (.chat-anker) und waechst nach OBEN. Bei
   200 % Textzoom und im Mobil-Landscape wird sie hoeher als der Viewport und
   ragte oben aus dem Bild — ausgerechnet der Einwilligungstext waere dann nicht
   mehr vollstaendig lesbar. Mit Deckel und eigenem Bildlauf bleibt er es.
   88px sind der Platz darunter: 56px Knopf, 12px Abstand, 16px zum Rand.
   Die vh-Zeile davor ist der Fallback fuer Browser ohne dvh. */
.chat-consent {
  max-width: 320px;
  max-height: calc(100vh - 88px);
  max-height: calc(100dvh - 88px);
  overflow-y: auto;
  padding: 16px;
  border-radius: var(--radius);
  background: var(--weiss);
  box-shadow: var(--schatten);
}

.chat-consent__text {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-gedaempft);
  margin-bottom: 12px;
}

/* Die Stoerungsmeldung bleibt als Live-Bereich immer im Dokument und ist nur
   leer — weggeschaltet wuerde sie beim Fuellen nicht angesagt. Ein leerer
   Absatz ist 0 Pixel hoch; den Abstand bekommt er deshalb erst mit Inhalt. */
.chat-consent__stoerung {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-gedaempft);
}

.chat-consent__stoerung:not(:empty) {
  margin-bottom: 12px;
}

.chat-consent__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Knapper als der Seiten-CTA: Zwei Knoepfe in voller Groesse passen auf der
   schmalen Karte nicht nebeneinander. */
.chat-consent .knopf {
  padding: 10px 18px;
  font-size: 14px;
}

/* Waehrend das Widget laedt, ist der Zustimmungsknopf gesperrt — das muss man
   ihm ansehen, sonst klickt der Besucher in die Wartezeit hinein. */
.chat-consent .knopf[disabled] {
  opacity: .7;
  cursor: default;
}

/* 10. Einwilligungs-Banner ------------------------------------------------ */

/* Gebaut aus dem, was schon da ist: die Karte der Chat-Einwilligung als Vorbild
   (weisse Flaeche, --radius, --schatten) und .knopf aus basis.css fuer die
   Antworten. Keine neue Gestaltungssprache, keine zweite Schrift, nichts von
   aussen — der Banner soll wie ein Teil der Seite aussehen und nicht wie ein
   eingekaufter Aufsatz.

   Unten links und nicht als Balken ueber die volle Breite: Der Chat-Knopf steht
   fix unten rechts, ein Balken laege ueber ihm. 88px Abstand nach unten sind
   genau sein Platz (56px Knopf, 12px Abstand, 16px Rand) — damit bleibt er auf
   schmalen Geraeten sichtbar und anklickbar, wo die Karte die volle Breite
   nimmt.

   z-index 70: ueber dem Chat-Anker (60) und dem klebenden Kopf (50), unter dem
   Skip-Link (100) — der Sprung zum Inhalt bleibt in jedem Fall erreichbar.

   Kein display hier: Ohne eigene Angabe greift die Browser-Regel fuer [hidden],
   und der Banner bleibt vor seinem Auftritt wirklich weg (anders als .karte, die
   dafuer eine eigene Zeile braucht).

   Bewusst ohne Ein- und Ausblend-Bewegung. Dann gibt es auch nichts, was
   prefers-reduced-motion abzuschalten haette. */
.consent-banner {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 88px;
  z-index: 70;
  max-width: 420px;
  /* Bei 200 % Textzoom wird die Karte hoeher als der Bildschirm und ragte oben
     heraus — ausgerechnet der Einwilligungstext waere dann nicht mehr ganz
     lesbar. Die vh-Zeile davor ist der Rueckfall fuer Browser ohne dvh. */
  max-height: calc(100vh - 104px);
  max-height: calc(100dvh - 104px);
  overflow-y: auto;
  padding: 16px;
  border-radius: var(--radius);
  background: var(--weiss);
  box-shadow: var(--schatten);
}

.consent-banner__titel {
  font-family: var(--schrift-headline);
  font-weight: 600;
  margin-bottom: 8px;
}

.consent-banner__text {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-gedaempft-stark);
  margin-bottom: 12px;
}

/* Beide Antworten teilen sich die Zeile zu gleichen Teilen. `flex: 1 1 8rem`
   statt fester Breiten: Auf 360px rutscht die zweite Antwort damit sauber unter
   die erste, statt dass eine von beiden schmaler wird — eine kleinere Antwort
   waere die unauffaelligere, und genau das darf hier keine sein. */
.consent-banner__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Gleiche Groesse, gleiche Flaeche, gleicher Kontrast fuer "Ablehnen" und
   "Akzeptieren" — keine Umriss-Variante fuer eine der beiden. Das ist eine
   Rechtsanforderung an die Einwilligung, keine Gestaltungslaune: Sobald eine
   Antwort leiser ist als die andere, ist die Entscheidung gelenkt.
   Knapper als der Seiten-CTA, damit beide nebeneinander passen. */
.consent-banner .knopf {
  flex: 1 1 8rem;
  padding: 10px 18px;
  font-size: 14px;
  text-align: center;
}

/* Der Widerruf im Seitenfuss ist ein Knopf und kein Link — er fuehrt nirgendwohin,
   sondern oeffnet den Banner erneut. Aussehen und Zustaende uebernimmt er von den
   Links seiner Zeile (layout.css, .fuss__recht a), damit die Rechtszeile eine
   Reihe bleibt und keine Mischung aus Text und Bedienelement. */
.fuss__cookies {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--primaer-dunkel);
  cursor: pointer;
}

.fuss__cookies:hover {
  text-decoration: underline;
}

.fuss__cookies:focus-visible {
  outline: 3px solid var(--primaer);
  outline-offset: 2px;
}

/* 11. Ab Tablet ----------------------------------------------------------- */

@media (min-width: 768px) {
  .sektion {
    padding-block: 4rem;
  }

  /* Ruecknahme der beiden Zentrierungen von oben. Sie gelten ausschliesslich auf
     schmalen Geraeten; ab hier steht neben jeder Kachel eine zweite und der
     Beitrag hat seine volle Lesebreite. Zugleich die Zusicherung, dass Ticket
     d14bd1fa Tablet, Laptop und Desktop nicht anfasst — belegt ueber den
     Byte-Vergleich der Referenzbilder.
     Seiteneigene Zentrierungen schlagen diese Regel bewusst: .vorteil in
     seite-ueber-uns.css und .weg, .produkt, .schritt, .stimme in
     seite-startseite.css haben 0,1,0 und bleiben deshalb auf jeder Breite
     zentriert — so, wie sie es vor diesem Ticket auch waren. :where() haelt die
     Ruecknahme dafuer auf 0,0,0: Sie greift nur dort, wo KEINE seiteneigene
     Ausrichtung steht, und kann keine schlagen. Vorher hing genau das an der
     Reihenfolge der <link>-Zeilen in layout.html.
     .liste .karte (0,2,0) schlaegt diese Regel ebenfalls — gewollt, die Hub-Karten
     stehen dann auf jeder Breite links, was hier ohnehin das Ergebnis waere. */
  :where(.karte) {
    text-align: left;
  }

  .cta-box h3 {
    text-align: left;
  }

  .cta-box__aktionen {
    justify-content: flex-start;
  }

  /* Zwei Spalten ab Tablet. minmax(0, 1fr) aus demselben Grund wie beim
     Kartenraster darunter: Ein langes Wort schoebe die Spalte sonst ueber ihren
     Anteil hinaus. */
  .liste {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* minmax(0, 1fr) statt 1fr: Ein blosses `1fr` hat als Mindestbreite den
     laengsten unteilbaren Inhalt der Spalte. Ein langes Wort schiebt die Spalte
     damit ueber ihren Anteil hinaus und das ganze Raster ueber den Viewport —
     bei 768px messbar passiert. Die Null als Minimum bindet die Spalte an ihren
     Anteil; die Trennung im Wort erledigt `hyphens` auf .karte. */
  .karten--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .karten--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* Vier Karten nebeneinander werden erst auf grossen Schirmen lesbar —
     dazwischen stehen sie zu zweit. */
  .karten--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .nur-mobil {
    display: none;
  }
}

@media (min-width: 1024px) {
  .karten--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
