/**
 * PKVbuddy Cappuccino Design System
 *
 * Basierend auf: code/templates/core/styleguide.html
 * Version: 1.0
 */

/* ==================== CSS VARIABLES ==================== */

/*
 * Farb-, Brand-, Neutral- und Latte-Art-Tokens leben jetzt zentral in tokens.css
 * (kanonische Quelle, vor dieser Datei geladen). Hier verbleiben nur projekt-
 * spezifische Glue-Tokens, die das Design-System-Token-Set nicht kennt.
 */
:root {
  /* Bootstrap Overrides - Cappuccino Farben.
     Audit B4/UX4-06: Die Utility-Klassen (.text-primary, .bg-primary,
     .text-secondary, …) werden AUSSCHLIESSLICH hier über die --bs-*-Tokens
     eingefärbt. Eigene Redefinitionen dieser Klassen sind zwecklos —
     Bootstraps Utilities tragen !important und gewinnen immer. */
  --bs-primary: #2A9D8F;
  --bs-primary-rgb: 42, 157, 143;
  --bs-primary-bg-subtle: #E6F4F2;
  --bs-primary-border-subtle: #40B4A6;
  --bs-primary-text-emphasis: #1E7268;
  --bs-secondary: #A57459;
  --bs-secondary-rgb: 165, 116, 89;
  --bs-secondary-bg-subtle: #F5EAE3;
  --bs-secondary-border-subtle: #C49480;
  --bs-secondary-text-emphasis: #5C4033;
  --bs-body-color: #3D2B1F;
  --bs-body-bg: #FFFAF5;
  --bs-link-color: #2A9D8F;
  --bs-link-color-rgb: 42, 157, 143;
  --bs-link-hover-color: #1E7268;
  --bs-link-hover-color-rgb: 30, 114, 104;

  /* Audit B2/UX4-01: Glue vervollständigt. Die folgenden Variablen fehlten,
     dahinter hängen .text-muted/.text-body-secondary (--bs-secondary-color),
     die text-*-Utilities von success/warning/danger/info (--bs-*-rgb),
     Bootstrap-Komponentenränder (--bs-border-color) sowie die
     subtle/emphasis-Tripel (u. a. Alerts, bg-*-subtle). Werte kommen aus
     tokens.css — hier wird nur verdrahtet, nie dupliziert.
     AUSNAHME sind die hartkodierten RGB-Tripel (--bs-*-rgb): CSS kann einen
     Hex-Token nicht in R, G, B zerlegen, deshalb stehen die Tripel hier als
     Literale — sie MÜSSEN synchron zu den Hex-Werten in tokens.css bleiben
     (bei jeder Token-Änderung dort hier mitziehen). */
  --bs-body-color-rgb: 61, 43, 31;
  --bs-body-bg-rgb: 255, 250, 245;
  --bs-emphasis-color: var(--espresso);
  --bs-emphasis-color-rgb: 61, 43, 31;
  --bs-secondary-color: var(--stone-500);
  --bs-secondary-color-rgb: 122, 112, 104;
  --bs-secondary-bg: var(--stone-100);
  --bs-secondary-bg-rgb: 245, 240, 235;
  --bs-tertiary-color: var(--stone-400);
  --bs-tertiary-color-rgb: 160, 150, 136;
  --bs-tertiary-bg: var(--stone-50);
  --bs-tertiary-bg-rgb: 250, 248, 245;
  --bs-border-color: var(--stone-200);
  --bs-border-color-translucent: rgba(61, 43, 31, 0.15);
  --bs-success: var(--success);
  --bs-success-rgb: 25, 135, 84;
  --bs-success-bg-subtle: var(--status-success-bg);
  --bs-success-border-subtle: var(--status-success-fg);
  --bs-success-text-emphasis: var(--status-success-fg);
  --bs-warning: var(--warning);
  --bs-warning-rgb: 217, 119, 6;
  --bs-warning-bg-subtle: var(--status-open-bg);
  --bs-warning-border-subtle: var(--status-open-fg);
  --bs-warning-text-emphasis: var(--status-open-fg);
  --bs-danger: var(--danger);
  --bs-danger-rgb: 220, 38, 38;
  --bs-danger-bg-subtle: var(--status-error-bg);
  --bs-danger-border-subtle: var(--status-error-fg);
  --bs-danger-text-emphasis: var(--status-error-fg);
  --bs-info: var(--info);
  --bs-info-rgb: 13, 202, 240;
  --bs-info-bg-subtle: var(--status-pending-bg);
  --bs-info-border-subtle: var(--status-pending-fg);
  --bs-info-text-emphasis: var(--status-pending-fg);

  /* Logo-Farben */
  --logo-hell: #BE9977;
  --logo-dunkel: #A57459;

  /* Mobile Header (FEATURE-0053) — nicht im Design-System-Token-Set */
  --mobile-header-bg: var(--milk-pure);  /* hell, wie Design .mtopbar */
  --mobile-header-logo-height: 40px;
}

/* ==================== BASE STYLES ==================== */

* {
  box-sizing: border-box;
}

::selection {
  background: rgba(42, 157, 143, 0.2);
}

/* Base styles for public pages */
body {
  font-family: var(--font-sans);
  background-color: var(--milk);
  color: var(--espresso);
  line-height: 1.6;
}

/* Audit B4C/UX4-09 (selektorform-heben): je Stufe auch die .hN-Klassenform,
   damit der Projekt-Schriftschnitt (Comfortaa 600) dieselbe Spezifität hat
   wie Bootstraps .hN { font-weight: 500 } und über die Ladereihenfolge
   gewinnt — z. B. <h1 class="h3"> auf Login und Gebührenordnung. Die
   GRÖSSE kommt bei Klassen-Kombis weiter aus der Größenklasse (Bootstrap),
   deshalb bleiben die font-size-Regeln darunter in Elementform. h5/h6
   styled das Marketing bewusst nicht. */
.h1,
h1,
.h2,
h2,
.h3,
h3,
.h4,
h4 {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--espresso);
}

h1 {
  font-size: 3.5rem;
  line-height: 1.2;
}

h2 {
  font-size: 2.5rem;
  /* Audit B4C/UX5-11: 1.3 → 1.4 — Zeilenhöhe der zweiten Ebene auf einen
     Wert der gelebten Skala (1.2/1.4/1.6). */
  line-height: 1.4;
}

h3 {
  font-size: 1.25rem;
  line-height: 1.4;
}

p {
  font-size: 0.95rem;
  color: var(--stone-600);
}

.lead {
  font-size: 1.1rem;
  color: var(--stone-500);
}

/* ==================== OVERLINE ==================== */

.overline,
.overline {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--stone-500);  /* Geändert von --crema-light für WCAG AA Kontrast (4.3:1) */
  text-transform: uppercase;
  letter-spacing: 3px;
  margin-bottom: 0.5rem;
}

/* ==================== BUTTONS ==================== */

.btn {
  font-family: var(--font-sans);
  padding: 0.875rem 2rem;
  border-radius: 25px;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  /* Nur Farben und Schatten, nie `all`: Mit `all` animierte jede Eigenschaft,
     die ein Zustand ändert, auch Lage und Größe (BUG-0266). */
  transition: background-color var(--dur-base) ease,
              border-color var(--dur-base) ease,
              color var(--dur-base) ease,
              box-shadow var(--dur-base) ease;
  /* Farbe aus Bootstraps Variable, nicht fest transparent: Die
     btn-outline-*-Varianten setzen nur --bs-btn-border-color. Mit
     `transparent` verloren sie in Ruhe ihren Rahmen, „Einwilligung
     widerrufen" sah aus wie ein Textlink (BUG-0290). Gefüllte Varianten
     tragen dort ihre Hintergrundfarbe, .btn ohne Variante transparent. */
  border: 2px solid var(--bs-btn-border-color, transparent);
}

/* Größenvarianten (BUG-0273). .btn oben setzt padding und font-size direkt und
   lädt nach Bootstrap. Bootstraps .btn-sm/.btn-lg ändern nur die Variablen
   --bs-btn-padding-* und --bs-btn-font-size, die .btn hier nicht liest: Ohne
   diese Regeln waren beide Varianten so groß wie ein normaler Knopf. Sie müssen
   nach .btn stehen, sonst gewinnt .btn bei gleicher Spezifität.
   Abstände im Verhältnis wie bei Bootstrap (klein 2/3, groß 4/3 von .btn),
   Schrift aus der Token-Skala. Der Radius bleibt der aus .btn (25px): ein
   voller Pillen-Radius machte die zweizeiligen btn-lg im Scanner zu Ovalen. */
.btn-sm {
  padding: 0.5rem 1.25rem;
  font-size: var(--fs-14);
}

.btn-lg {
  padding: 1.125rem 2.5rem;
  font-size: var(--fs-20);
}

/* WEISS AUF TÜRKIS HEISST --accent-dark. Weiß auf --accent sind 3,32:1, und AA
   verlangt 4,5:1 — das betraf jeden Primärknopf im Haus, also steht die Antwort
   hier und nicht an einer Call-Site. Die Ruhefarbe rückt eine Stufe nach unten
   (5,73:1), der Hover eine weitere (--accent-deep, 7,80:1); der Unterschied
   zwischen Ruhe und Hover bleibt damit derselbe Schritt wie zuvor.

   Dieselbe Rechnung galt schon einmal und stand nur nicht hier: Die aktive
   Station der Beleg-Reise trägt --accent-dark mit dem Vermerk „3:1 für Text zu
   wenig". Das war die Regel, lokal notiert. */
.btn-primary,
.btn-primary:active,
.btn-primary:visited {
  background-color: var(--accent-dark);
  color: #fff;
  border-color: var(--accent-dark);
}

/* KEIN HOVER-SCHATTEN. Hier stand ein türkiser Glow (0 6px 20px
   rgba(42,157,143,.35)) — der einzige Knopf-Hover-Schatten des Hauses:
   .btn-outline-primary wechselt im Hover nur die Farbe, und Schatten-Hover
   tragen sonst allein Karten, in warmem Braun (--shadow-xl). Ein farbiger
   Glow an genau einem Knopftyp war ein Sonderfall ohne Regel; der Token
   --shadow-cta, der denselben Wert trug, hatte ohnehin keinen Konsumenten
   und ist mit entfallen.

   KEINE HEBUNG. Hier hob translateY(-2px) den Knopf im Hover an. Stand der
   Zeiger am unteren Rand, verließ er durch die Hebung den Knopf, der Hover
   fiel weg, der Knopf senkte sich, der Hover griff wieder: Der Knopf zitterte.
   Über :focus blieb er nach einem Klick außerdem angehoben. Hover wechselt
   deshalb nur die Farbe, wie bei .btn-secondary; das gilt auch für die
   Startseiten-CTAs und für .app-btn-primary (BUG-0266). Hebungen im Hover
   tragen nur Karten. */
.btn-primary:hover,
.btn-primary:focus {
  background-color: var(--accent-deep);
  border-color: var(--accent-deep);
  color: #fff;
}

/* Deaktiviert bleibt der Knopf in seiner Farbe, nur gedämpft.

   OHNE DIESE REGEL WIRD ER BOOTSTRAP-BLAU (#0d6efd). Bootstrap setzt
   `.btn-primary:disabled` mit zwei Klassenstufen, die Zeilen darüber setzen
   `.btn-primary` mit einer — jede Gewichtung gewinnt gegen eine schwächere,
   ganz gleich, welches Blatt später kommt. Die Falle greift überall im Haus,
   wo ein primärer Knopf deaktiviert wird; sie war zuletzt lokal in reise.css
   gefangen, und genau das ist der Grund, warum sie hierher gehört.

   .disabled zusätzlich, weil ein <a> kein disabled-Attribut kennt und
   Bootstrap dort dieselbe Darstellung über die Klasse fährt. */
.btn-primary:disabled,
.btn-primary.disabled {
  background-color: var(--accent-dark);
  border-color: var(--accent-dark);
  color: #fff;
  opacity: 0.55;
  box-shadow: none;
  cursor: default;
}

.btn-secondary,
.btn-outline-primary,
.btn-secondary:active,
.btn-outline-primary:active {
  background-color: transparent;
  color: var(--accent);
  border-color: var(--accent);
}

/* Gefüllt mit weißer Schrift, also dieselbe Rechnung wie beim Primärknopf —
   und derselbe Ton, sonst wäre der sekundäre Knopf im Hover heller als der
   primäre in Ruhe. */
.btn-secondary:hover,
.btn-secondary:focus,
.btn-outline-primary:hover,
.btn-outline-primary:focus {
  background-color: var(--accent-dark);
  color: #fff;
  border-color: var(--accent-dark);
}

/* Deaktiviert bleibt auch der sekundäre Knopf in seiner Farbe, nur gedämpft —
   dieselbe Bootstrap-Falle wie bei .btn-primary:disabled oben: Ohne diese
   Regel wird .btn-outline-primary:disabled Bootstrap-BLAU und
   .btn-secondary:disabled grau. Sie greift app-weit (z. B. „Zurück" im ersten
   Schritt der Beleg-Reise) und steht deshalb hier und nicht an einer
   Call-Site. Nach den Hover-Regeln, damit sie bei gleicher Gewichtung
   gewinnt. */
.btn-secondary:disabled,
.btn-secondary.disabled,
.btn-outline-primary:disabled,
.btn-outline-primary.disabled {
  background-color: transparent;
  color: var(--accent);
  border-color: var(--accent);
  opacity: 0.55;
  box-shadow: none;
  cursor: default;
}

/* .btn-ghost abgebaut (Grep: 0 Konsumenten in Templates, Python und JS).
   Stand ebenfalls in .claude/rules/frontend-design.md §3 als „Erlaubt" —
   dort im selben Zug gestrichen. */

/* Anbieter-Buttons (Google/Microsoft): der einzige Button-Typ, der ein Symbol
   trägt (siehe .claude/rules/frontend-design.md §5 „Markenlogos"). Das farbige
   Markenlogo IST hier der Erkennungswert.

   Eigenes Farbidiom statt .btn-secondary/.app-btn-primary, weil beide auf
   --accent umschlagen (btn-secondary im Hover, app-btn-primary dauerhaft). Ein
   farbiges Logo auf Türkis ist weder lesbar noch markenkonform: #4285F4 auf
   --accent ergibt 1,07:1, das Google-Blau verschwindet. Google erlaubt weiß,
   hellgrau und dunkelgrau, Microsoft weiß und dunkelgrau. Die Akzentfarbe ist
   in keiner der beiden Vorgaben enthalten.

   Grund bleibt daher in jedem Zustand neutral, Hover und Fokus dunkeln die
   Fläche ab statt sie umzukehren. Rahmen über --control-border (3,73:1 auf
   Weiß, SC 1.4.11) wie .app-btn-outline.

   Zwei Klassen im Selektor, weil app-components.css NACH dieser Datei lädt und
   .app-btn-outline sonst bei gleicher Spezifität gewinnt. */
.btn.is-provider,
.btn.is-provider:active,
.app-btn.is-provider,
.app-btn.is-provider:active {
  background-color: #fff;
  color: var(--espresso);
  border: 2px solid var(--control-border);
  box-shadow: none;
}

.btn.is-provider:hover,
.btn.is-provider:focus,
.app-btn.is-provider:hover,
.app-btn.is-provider:focus {
  background-color: var(--stone-100);
  color: var(--espresso);
  border-color: var(--espresso-light);
  box-shadow: none;
}

/* Flex und Abstand nur im .btn-Zweig, denn .app-btn bringt inline-flex und
   gap: 6px schon in seiner Basis mit (app-components.css). */
.btn.is-provider {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-weight: 600;
}

/* ==================== CARDS ==================== */

.card {
  background-color: #fff;
  border-radius: 16px;
  padding: 1.5rem;
  border: 1px solid var(--hairline);
  box-shadow: 0 2px 12px rgba(61, 43, 31, 0.04);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.card:hover {
  box-shadow: 0 4px 20px rgba(61, 43, 31, 0.08);
}

.card.accent {
  background-color: var(--accent-muted);
  border: 2px solid var(--accent);
}

.card.dark {
  background-color: var(--espresso);
  border: none;
  color: var(--milk);
}

.card.dark h3,
.card.dark h4,
.card.dark p {
  color: var(--milk);
}

.card-title {
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--espresso);
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 2px solid var(--tasse-muted);
}

/* ==================== FEATURE CARDS ==================== */

.feature-card {
  background-color: #fff;
  border-radius: 16px;
  padding: 1.5rem;
  border: 1px solid var(--hairline);
  text-align: center;
  transition: transform 0.2s ease;
  display: flex;
  flex-direction: column;
}

.feature-card:hover {
  transform: translateY(-4px);
}

/* Die Hebebewegung beim Zeigen entfaellt bei reduzierter Bewegung; die
   Blog-Karte teilt dieselbe Bewegung (Review L9). */
@media (prefers-reduced-motion: reduce) {
  .feature-card,
  .blog-card {
    transition: none;
  }

  .feature-card:hover,
  .blog-card:hover {
    transform: none;
  }
}

/* .feature-card-icon abgebaut (schlichter oeffentlicher Bereich, Grep: 0
   Konsumenten) — Karten tragen kein Symbol mehr ueber der Ueberschrift. */

/* margin-top entfiel mit dem Symbol darueber: die Ueberschrift ist jetzt
   erstes Kind der Karte und sitzt am Innenabstand. */
.feature-card-title {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--espresso);
  margin-bottom: 0.5rem;
}

.feature-card-desc {
  font-size: 0.85rem;
  color: var(--stone-500);
  line-height: 1.5;
}

/* Kopfzeile einer linksbuendigen Karte: Titel und Symbolkreis nebeneinander.
   Der Titel steht vor dem Kreis, weil im oeffentlichen Bereich kein Symbol
   ueber einer Ueberschrift steht (Regel C, core/tests/test_public_ueberschriften.py). */
.feature-card-kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.feature-card-kopf .feature-card-title {
  margin-bottom: 0;
}

/* Heller Kreis hinter einem kleinen Motiv in der Kopfzeile der
   Datenschutz-Karten (weisser Kartengrund). Bewusst ohne Akzentfarbe
   (anders als der abgebaute .benefit-icon): die Motive tragen ihren Akzent
   selbst, ein tuerkiser Grund dahinter wuerde ihn schlucken.

   Nur auf weissem Grund: auf einer milk-warm-Flaeche ist der Kreis exakt
   die Flaechenfarbe und damit unsichtbar (Review M3). Das Register der
   Feature-Uebersicht loest dasselbe Problem seit dem 24.08.2026 anders und
   traegt einen WEISSEN Kreis (.benefit-item-ring): weiss ist dort sichtbar,
   wo --milk-warm es nicht ist. Kontrast der Motiv-Kontur (--espresso) auf dem
   Ring: 11,5:1; die Flaechen der Motive bleiben wie in den grossen
   Zeichnungen auf --linie-flaeche, die Kontur traegt die Form. */
.icon-ring {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--milk-warm);
}

/* Symbolskala (frontend-design.md §5): Kachelsymbole tragen --icon-2xl. */
.icon-ring-motiv {
  display: block;
  width: var(--icon-2xl);
  height: var(--icon-2xl);
}

@media (forced-colors: active) {
  .icon-ring {
    border: 1px solid CanvasText;
  }
}

/* ==================== LATTE ART CONTAINER ==================== */

/* .latte-container-light/-dark abgebaut (Grep: 0 Konsumenten in Templates,
   Python und JS — die Klassen existierten nur noch in ihrer eigenen
   Styleguide-Demo). Runde Icon-Flächen laufen über .icon-blob/.icon-blob-lg
   und .icon-feature-primary/-secondary. */

/* .preview-icon-lg abgebaut (Audit B4/UX4-11+UX6-08, Grep: 0 Konsumenten). */

/* ==================== ORGANIC BLOB ICONS ==================== */

/* Base Icon Container */
.icon-blob {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100px;
  height: 100px;
}

.icon-blob svg {
  position: relative;
  z-index: 1;
  width: var(--icon-3xl);
  height: var(--icon-3xl);
  stroke: var(--crema-dark);
  stroke-opacity: 0.85;
}

/* Blob Background (Pseudo-Element) */
.icon-blob::before {
  content: '';
  position: absolute;
  width: 90px;
  height: 80px;
  background: var(--crema);
  opacity: 0.18;
  filter: blur(6px);
  z-index: 0;
  animation: blob-breathe 10s ease-in-out infinite;
}

/* 6 Blob Shape Variants */
.icon-blob.blob-1::before { border-radius: 60% 40% 50% 50% / 50% 60% 40% 50%; }
.icon-blob.blob-2::before { border-radius: 40% 60% 55% 45% / 55% 45% 60% 40%; }
.icon-blob.blob-3::before { border-radius: 55% 45% 40% 60% / 45% 55% 50% 50%; }
.icon-blob.blob-4::before { border-radius: 50% 50% 45% 55% / 60% 40% 55% 45%; }
.icon-blob.blob-5::before { border-radius: 45% 55% 60% 40% / 50% 50% 45% 55%; }
.icon-blob.blob-6::before { border-radius: 52% 48% 42% 58% / 48% 52% 58% 42%; }

/* Breathing Animation */
@keyframes blob-breathe {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50% { transform: scale(1.05) rotate(3deg); }
}

/* Animation Delays for visual interest */
.icon-blob.blob-2::before { animation-delay: -2s; }
.icon-blob.blob-3::before { animation-delay: -4s; }
.icon-blob.blob-4::before { animation-delay: -6s; }
.icon-blob.blob-5::before { animation-delay: -8s; }
.icon-blob.blob-6::before { animation-delay: -3s; }

/* Large Variant (for Highlight Sections) */
.icon-blob-lg {
  width: 140px;
  height: 140px;
}

/* Audit B4GL/A3-17: Symbolskala statt Einzelwert. */
.icon-blob-lg svg {
  width: var(--icon-4xl);
  height: var(--icon-4xl);
}

.icon-blob-lg::before {
  width: 120px;
  height: 110px;
}

/* Reduced Motion Support */
@media (prefers-reduced-motion: reduce) {
  .icon-blob::before {
    animation: none;
  }
}

/* ==================== ICON FEATURE PRIMARY ==================== */
/* Grüne/Türkise Icons für Haupt-Features - clean, minimal */

.icon-feature-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
}

/* Audit B4GL/A3-17: Die Klasse gewinnt gegen die width/height-Attribute des
   Tags — sie muss deshalb selbst auf der Symbolskala liegen, sonst zeigt das
   Markup eine Größe, die nie gerendert wird. War 36px. */
.icon-feature-primary svg {
  width: var(--icon-2xl);
  height: var(--icon-2xl);
  color: var(--accent);
  transition: color 0.2s ease;
}

.feature-card:hover .icon-feature-primary svg {
  color: var(--espresso);
}

/* ==================== ICON FEATURE SECONDARY ==================== */
/* Braune Icons für sekundäre Elemente - sehr dezent, kleiner */

.icon-feature-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
}

/* Audit B4GL/A3-17: war 28px — siehe .icon-feature-primary svg. */
.icon-feature-secondary svg {
  width: var(--icon-xl);
  height: var(--icon-xl);
  color: var(--crema-dark);
  opacity: 0.85;
  transition: color 0.2s ease, opacity 0.2s ease;
}

.feature-card:hover .icon-feature-secondary svg {
  color: var(--espresso);
  opacity: 1;
}

/* ==================== ICON FEATURES: REDUCED MOTION ==================== */

@media (prefers-reduced-motion: reduce) {
  .icon-feature-primary svg,
  .icon-feature-secondary svg {
    transition: none;
  }
}

/* .variant-label abgebaut (Audit B4/UX4-11+UX6-08, Grep: 0 Konsumenten). */

/* ==================== SECTIONS ==================== */

/* Standard Section Padding */
section {
  padding: 8rem 0;
}

/*
 * Wave-Transition Spacing System
 * ==============================
 *
 * .section-has-wave: Section hat eine Wave am Ende
 *   → Kein bottom padding (Wave erzeugt visuellen Übergang)
 *
 * .section-after-wave: Section folgt nach einer Wave
 *   → padding-top: 0 (Hintergrund verbindet nahtlos mit Wave)
 *   → Container bekommt padding-top für Content-Abstand
 */

/* Section mit Wave am Ende: kein bottom padding */
section.section-has-wave {
  padding-bottom: 0;
}

/* Section nach Wave: kein top padding auf Section-Ebene */
section.section-after-wave {
  padding-top: 0;
}

/* Section nach Wave: Content-Container bekommt spacing */
section.section-after-wave > .container {
  padding-top: 4rem;
}

/* Bootstrap pt-0 Override für manuelle Fälle */
section.pt-0 {
  padding-top: 0;
}

.section-milk {
  background-color: var(--milk);
}

.section-warm,
.section-milk-warm {
  background-color: var(--milk-warm);
}

/* .section-dark (+ h2/h3/p/.overline-Ableger) abgebaut
   (Audit B4/UX4-11+UX6-08, Grep: 0 Konsumenten) — Templates nutzen
   .section-espresso. */
.section-espresso {
  background-color: var(--espresso);
  color: var(--milk);
}

/* ==================== HERO ==================== */

section.hero {
  /* background-color wird durch section-milk-warm gesetzt */
  /* padding-bottom: 0 wird durch section-has-wave gesetzt */
  padding-top: 5rem;
  position: relative;
  overflow: hidden;
}

.hero h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  margin-bottom: 1.5rem;
}

.hero .lead {
  font-size: 1.25rem;
  color: var(--stone-500);
  margin-bottom: 2rem;
}

/* Steam Animation (Variante 7: Heller Dampf aus Styleguide)
 *
 * Specs:
 * - Opacity: 0.06–0.15
 * - Animation: 10–12s ease-in-out
 * - Farbe: Weiß + Crema-Hauch (#FFFAF5)
 */
.steam-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  overflow: hidden;
}

/* Basis-Nebel: großflächiger weißer Gradient von unten */
.steam-base {
  position: absolute;
  bottom: -20%;
  left: -10%;
  width: 120%;
  height: 80%;
  background: radial-gradient(ellipse 100% 60% at 50% 100%,
    #FFFAF5 0%,
    rgba(255, 250, 245, 0.8) 30%,
    transparent 70%
  );
}

/* Animierte Dampfwolken */
.steam-cloud {
  position: absolute;
  filter: blur(20px);
}

.steam-cloud-left {
  bottom: 0%;
  left: -20%;
  width: 70%;
  height: 60%;
  background: radial-gradient(ellipse at 50% 80%,
    rgba(255, 255, 255, 0.7) 0%,
    transparent 60%
  );
  animation: steam-float-left 10s ease-in-out infinite;
}

.steam-cloud-right {
  bottom: 5%;
  right: -15%;
  width: 60%;
  height: 55%;
  background: radial-gradient(ellipse at 50% 80%,
    rgba(255, 255, 255, 0.6) 0%,
    transparent 65%
  );
  filter: blur(25px);
  animation: steam-float-right 12s ease-in-out infinite;
}

@keyframes steam-float-left {
  0%, 100% {
    transform: translateX(0) translateY(0);
    opacity: 0.7;
  }
  50% {
    transform: translateX(5%) translateY(-8%);
    opacity: 0.9;
  }
}

@keyframes steam-float-right {
  0%, 100% {
    transform: translateX(0) translateY(0);
    opacity: 0.6;
  }
  50% {
    transform: translateX(-5%) translateY(-10%);
    opacity: 0.8;
  }
}

/* Reduced Motion Support */
@media (prefers-reduced-motion: reduce) {
  .steam-cloud-left,
  .steam-cloud-right {
    animation: none;
  }
}

/* .section-divider abgebaut (Audit B4/UX4-11+UX6-08, Grep: 0 Konsumenten). */

/* ==================== NAVIGATION ==================== */

/* Audit B4GL/UX6-12: Die Haftung der öffentlichen Kopfleiste sitzt auf dem
   <header> (base_public.html) — im <nav> hatte sie null Spielraum und scrollte
   am Desktop sofort mit heraus. Bootstrap gibt .sticky-top 1020; die App zählt
   fixierte Möbel über --z-sticky, damit der Kopf unter Dialogen (--z-modal),
   Overlays (--z-overlay) und dem Cookie-Banner bleibt. */
header.sticky-top {
  z-index: var(--z-sticky);
}

/* Sprungmarken (#anker) landen sonst hinter der haftenden Kopfleiste — das
   betrifft 26 Verweise je Wissensartikel und den Sprunglink selbst. Unter
   992px war das schon vorher so, weil .landing-nav dort fixiert ist. */
html:has(> body > header.sticky-top) {
  scroll-padding-top: calc(var(--landing-nav-height) + 1rem);
}

.landing-nav {
  background-color: var(--milk-warm);
  border-bottom: 1px solid var(--stone-200);
  padding: 1.25rem 0;
  /* Hält --landing-nav-height und die tatsächliche Höhe zusammen. */
  min-height: var(--landing-nav-height);
}

.landing-nav .navbar-brand {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--espresso);
}

.landing-nav .nav-item {
  margin: 0 0.75rem;
}

.landing-nav .nav-link {
  font-family: var(--font-sans);
  color: var(--stone-600);
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  padding: 0.5rem 0.25rem;
  position: relative;
  transition: color 0.3s ease;
}

.landing-nav .nav-link:not(.dropdown-toggle)::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 2px;
  background-color: var(--accent);
  transition: width 0.3s ease, left 0.3s ease;
}

.landing-nav .nav-link:hover {
  color: var(--accent);
}

.landing-nav .nav-link:not(.dropdown-toggle):hover::after {
  width: 100%;
  left: 0;
}

.landing-nav .dropdown-toggle::after {
  margin-left: 0.5em;
  transition: transform 0.2s ease;
}

.landing-nav .dropdown-toggle:hover::after {
  transform: translateY(2px);
}

/* Dropdown Menu */
.landing-nav .dropdown-menu {
  border-radius: 12px;
  border: 1px solid var(--stone-200);
  box-shadow: 0 4px 12px rgba(61, 43, 31, 0.1);
}

.landing-nav .dropdown-item {
  font-family: var(--font-sans);
}

.landing-nav .dropdown-item:hover {
  background-color: var(--milk-warm);
}

/* CTA Button */
.landing-nav .btn-nav-cta {
  background-color: var(--accent-dark);
  color: #fff;
  border-radius: 25px;
  padding: 0.625rem 1.5rem;
  font-family: var(--font-sans);
  font-weight: 600;
  transition: background-color 0.2s ease;
}

.landing-nav .btn-nav-cta:hover {
  background-color: var(--accent-deep);
  color: #fff;
}

/* Mobile Navigation */
@media (max-width: 991.98px) {
  /* Audit B4GL/UX6-12: fixierte statt haftender Kopfleiste — der Höhen-Token
     zieht mit, damit Sprungmarken und haftende Tabellenköpfe stimmen. */
  :root {
    --landing-nav-height: var(--mobile-header-height);
  }

  .landing-nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: calc(var(--z-sticky) + 10);
    height: var(--mobile-header-height);
    /* Audit B4C/A4-12: wie .mobile-header (app.css) — Inhalt unter die
       Systemanzeige, seitliche Federung fürs Querformat. */
    padding: env(safe-area-inset-top, 0px)
             calc(1rem + env(safe-area-inset-right, 0px))
             0
             calc(1rem + env(safe-area-inset-left, 0px));
    display: flex;
    align-items: center;
  }

  .landing-nav .navbar-brand img {
    height: var(--mobile-header-logo-height);
  }

  /* Audit B4GL Gruppe 6: Der Platz für die fixierte Kopfleiste stand hier
     als nacktes `body { padding-top }`. cappuccino.css laden aber beide
     Layouts — der Selektor griff also auch hinter dem Login, wo
     .main-panel (app.css) denselben Versatz bereits setzt: jede App-Seite
     schob ihren Inhalt um zwei Kopfhöhen nach unten.

     Die Regel steht jetzt in public.css. Sie gehört dorthin, ohne dass ein
     Selektor sie eingrenzen müsste: .landing-nav (base_public.html:27) und
     public.css (base_public.html:12) haben exakt denselben
     Geltungsbereich — je genau eine Fundstelle, im selben Template. */

  .landing-nav .navbar-collapse {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--milk-warm);
    z-index: var(--z-overlay);
    padding: 6rem 2rem 2rem;
    display: none;
    flex-direction: column;
    /* Bootstrap Collapse-Transition deaktivieren für sofortiges Erscheinen */
    transition: none !important;
    height: auto !important;
  }

  .landing-nav .navbar-collapse.collapsing {
    /* Auch während des Übergangs sofort zeigen */
    display: flex;
    height: auto !important;
  }

  .landing-nav .navbar-collapse.show {
    display: flex;
  }

  .landing-nav .navbar-nav {
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
  }

  .landing-nav .nav-item {
    margin: 0.75rem 0;
    opacity: 0;
    transform: translateY(20px);
  }

  .landing-nav .navbar-collapse.show .nav-item {
    animation: navItemFadeIn 0.4s ease forwards;
  }

  .landing-nav .navbar-collapse.show .nav-item:nth-child(1) { animation-delay: 0.05s; }
  .landing-nav .navbar-collapse.show .nav-item:nth-child(2) { animation-delay: 0.1s; }
  .landing-nav .navbar-collapse.show .nav-item:nth-child(3) { animation-delay: 0.15s; }
  .landing-nav .navbar-collapse.show .nav-item:nth-child(4) { animation-delay: 0.2s; }
  .landing-nav .navbar-collapse.show .nav-item:nth-child(5) { animation-delay: 0.25s; }
  .landing-nav .navbar-collapse.show .nav-item:nth-child(6) { animation-delay: 0.3s; }

  .landing-nav .nav-link {
    font-size: 1.5rem;
    font-weight: 600;
    padding: 0.75rem 1rem;
  }

  .landing-nav .nav-link:not(.dropdown-toggle)::after {
    display: none;
  }

  .landing-nav .navbar-collapse .d-flex {
    margin-top: auto;
    padding-top: 2rem;
  }

  .landing-nav .btn-nav-cta {
    font-size: 1.1rem;
    padding: 1rem 2.5rem;
  }

  .landing-nav .navbar-toggler {
    position: relative;
    z-index: calc(var(--z-overlay) + 10);
  }

  .landing-nav .navbar-collapse.show .d-flex {
    opacity: 0;
    animation: navItemFadeIn 0.4s ease forwards;
    animation-delay: 0.35s;
  }
}

@keyframes navItemFadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ==================== FOOTER ==================== */

.landing-footer {
  background-color: var(--espresso);
  color: var(--milk);
  padding: 3rem 0 1.5rem;
}

/* Footer Headings */
.landing-footer h2,
.landing-footer h3,
.landing-footer h5 {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--crema);
  margin-bottom: 1rem;
}

/* Footer Links — Audit B4/UX4-12: Hover-Farbe war doppelt definiert
   (hier --milk, weiter unten --crema); die spätere Regel gewann. Jetzt
   steht die gewinnende Farbe (--crema) an genau dieser einen Stelle. */
.landing-footer a {
  color: var(--stone-300);
  text-decoration: none;
  transition: color 0.2s ease;
}

.landing-footer a:hover,
.landing-footer a:focus {
  text-decoration: none;
}

.landing-footer a:hover {
  color: var(--crema);
}

/* Footer Lists */
.landing-footer ul {
  font-family: var(--font-sans);
}

/* Footer Tagline */
.landing-footer .footer-tagline {
  color: var(--stone-400);
  font-size: 0.9rem;
  font-family: var(--font-sans);
}

/* Footer Divider */
.landing-footer hr {
  border-color: var(--espresso-light);
  margin: 2rem 0 1.5rem;
  opacity: 1;
}

/* Footer Copyright */
.landing-footer .footer-bottom {
  color: var(--stone-400);
  font-size: 0.85rem;
  font-family: var(--font-sans);
}

.landing-footer .footer-bottom p {
  margin-bottom: 0;
}

/* ==================== UTILITIES ==================== */

/* Cappuccino Utilities */
.text-espresso { color: var(--espresso); }
.text-crema { color: var(--crema); }
.text-accent { color: var(--accent); }
.text-milk { color: var(--milk); }
.text-stone { color: var(--stone-500); }

.bg-milk { background-color: var(--milk); }
/* .bg-milk-warm/.bg-espresso/.bg-accent-muted abgebaut
   (Audit B4/UX4-11+UX6-08, Grep: 0 Konsumenten). */

/* Audit B4/UX4-06: Der frühere Block „Bootstrap Utility Overrides"
   (.text-primary, .bg-primary, .bg-primary-subtle, .border-primary,
   .link-primary, .text-secondary, .bg-secondary, .bg-secondary-subtle,
   .border-secondary) ist ersatzlos gestrichen — die gleichnamigen
   Bootstrap-Utilities tragen !important und gewannen immer. Die Färbung
   passiert real über die --bs-*-Glue-Tokens im :root oben. */

/* ==================== RESPONSIVE ==================== */

@media (max-width: 767.98px) {
  h1 {
    font-size: 2.5rem;
  }

  h2 {
    font-size: 2rem;
  }

  section {
    padding: 3rem 0;
  }

  .hero {
    padding: 3rem 0 2rem;
  }

}

/* ==================== TOASTS ==================== */

/* Audit B4/UX5-20: Meldungs-Ebene über das benannte Ebenen-Token statt
   Inline-Style in _toast_container.html. Muss auf dem Container selbst
   stehen — Bootstrap definiert --bs-toast-zindex dort lokal (1090,
   wertgleich mit --z-toast). */
.toast-container {
  --bs-toast-zindex: var(--z-toast);
}

/* ==================== ACCESSIBILITY ==================== */

/* Audit B4C/A5-12: Ringfarbe --accent-dark statt --accent — 5,73:1 auf
   Weiß, 4,89:1 auf --milk-warm (Ziel 3:1 nach SC 1.4.11; --accent lag
   auf --milk-warm bei 2,84:1). */
:focus-visible {
  outline: 2px solid var(--accent-dark);
  outline-offset: 2px;
}

/* Audit B4C/A5-12 (+ A5-11, UX6-05): die gemeinsame Fokusregel.
   Bootstrap setzt auf .btn/.nav-link:focus-visible outline:0 plus einen
   blauen Schatten über --bs-btn-focus-box-shadow (Spezifität 0-2-0) und
   gewinnt damit gegen die globale Regel oben (0-1-0) — blanke .btn ohne
   Variante (Kontomenü .navbar-user) blieben ganz ohne Fokusanzeige.
   Gleiche Selektorform hier gewinnt per Ladereihenfolge (cappuccino.css
   lädt nach bootstrap.min.css in base_meta.html). Text-Eingabefelder
   matchen :focus-visible bei jeder Fokusart — der Ring ersetzt dort den
   zu schwachen rgba-Glow als normative Fokusanzeige. */
.btn:focus-visible,
.nav-link:focus-visible,
.dropdown-item:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.form-check-input:focus-visible {
  outline: 2px solid var(--accent-dark);
  outline-offset: 2px;
}
.btn:focus-visible,
.nav-link:focus-visible {
  box-shadow: none; /* Bootstraps Blau-Ring aus */
}

/* Audit B4C/A4-06: 44px-Hitbox über ein unsichtbares Pseudo-Element,
   zentriert auf freistehende quadratische Bedienelemente — Optik
   unverändert. Modal-Schließen (Bootstrap .btn-close, u. a.
   Cashflow-Simulator mit gemessenen 16×6px) steht im Modal-Kopf frei, die
   Hitbox kollidiert mit keinem Nachbarn.
   Nachzug Completeness-Check (09.08.2026): .ins-icon-btn (40×40px, 2px
   Übertrag je Seite — passt unter die 10px gap in .ins-config-actions bzw.
   der actions-Zelle der Mitglieder-Tabelle) und .form-check-input (20×20px,
   12px Übertrag je Seite — passt unter die 16px Zell-Innenabstand von
   .list-table und kapert damit in _receipt_row.html nicht die
   Zeilennavigation, siehe deren eigenen Klick-Guard `td[data-cell=checkbox]`
   in tr[onclick]).
   Nachzug BUG-0404 (23.09.2026): .toast .btn-close (24×24px sichtbare
   Flaeche, 10px Uebertrag je Seite) — der Toast ist breit genug, dass die
   Hitbox nicht mit dem Meldungstext kollidiert. */
.modal-header .btn-close,
.ins-icon-btn,
.form-check-input,
.toast .btn-close {
  position: relative;
}
.modal-header .btn-close::after,
.ins-icon-btn::after,
.form-check-input::after,
.toast .btn-close::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

/* Audit B4 Global/A5-04: Der Sprunglink gilt jetzt auch hinter dem Login. Dort
   ist die mobile Kopfleiste fixiert (app.css: --z-overlay + 1) — mit dem alten
   Literal 100 waere der eingeblendete Link dahinter verschwunden.

   Versteckt wird er ueber translateY(-100%) statt ueber top: -40px. Der feste
   Versatz war eine Schaetzung der eigenen Hoehe und lag daneben: gemessen ist
   der Link 41,6 px hoch, seine Unterkante stand damit bei +1,6 px und ein
   zwei Pixel hoher tuerkiser Streifen lag am oberen Rand JEDER Seite. Vorher
   verdeckte ihn die klebende Kopfleiste, seit der Ebenenkorrektur oben liegt
   er darueber — sichtbar geworden im Vorher/Nachher-Sweep auf 214 von 219
   Shots. Prozentwerte haengen nicht von Schriftgroesse oder Innenabstand ab.

   Die zusaetzlichen 2 px sind Sicherheitsabstand: die gemessene Hoehe ist
   krumm (41,59 px), und bei genau buendigem Abschluss malte der Compositor
   noch eine halbdurchsichtige Pixelzeile in die erste Bildzeile. */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  background: var(--accent-dark);
  color: white;
  padding: 8px 16px;
  z-index: calc(var(--z-overlay) + 2);
  transform: translateY(calc(-100% - 2px));
  transition: transform 0.3s;
}

.skip-link:focus {
  transform: translateY(0);
}

/* ==================== HERO CHIP ==================== */

.hero-chip {
  display: inline-block;
  background: var(--milk);
  color: var(--espresso);
  padding: 0.5rem 1rem;
  border-radius: 20px;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 1.5rem;
  border: 1px solid var(--stone-200);
}

/* ==================== HERO USPS ==================== */

.hero-usps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--stone-600);
}

.usp-divider {
  color: var(--stone-300);
}

@media (max-width: 767.98px) {
  .hero-usps {
    flex-direction: column;
    gap: 0.5rem;
  }

  .usp-divider {
    display: none;
  }
}

/* ==================== SECTION WAVE ==================== */

.section-wave {
  position: relative;
  width: 100%;
  height: 80px;
  overflow: hidden;
  margin-top: -1px;
}

.section-wave svg {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 100%;
}

.section-wave-top {
  transform: rotate(180deg);
  margin-bottom: -1px;
  margin-top: 0;
}

/* Das -1px unten ist das Gegenstück zum -1px oben an .section-wave und keine
   Kosmetik. Der Wellen-div ist position: relative und malt deshalb nach den
   Hintergründen beider Sektionen. Landet seine Unterkante auf einer
   gebrochenen Pixelposition, mobil der Normalfall wegen des
   clamp(1.5rem, 5svh, 2.5rem) im Hero-Padding, dann wird die unterste Zeile
   des Pfad-Fills anti-aliased. Der Grund darunter gehört bis zur
   Sektionsgrenze noch der OBEREN Sektion; die Zeile mischt also zwei
   Flächenfarben und liest sich als Haarlinie. Die negative Margin zieht die
   Folgesektion eine volle Pixelreihe hoch, damit ist der Grund unter der Zeile
   ihr eigener. Gewacht von code/tests/e2e/test_wellen_naht.py. */
.section-wave-bottom {
  position: relative;
  width: 100%;
  height: 80px;
  margin-top: 4rem; /* Abstand zwischen Content und Wave */
  margin-bottom: -1px;
}

.section-wave-bottom svg {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 100%;
}

/* Wellen-Partial core/public/_welle.html: die Fuellung kommt ueber die
   Klasse aus tokens.css statt als Hex-Wert am Pfad. Die Startseite hat nach
   der Beleg-Reise zehn Uebergaenge; zehn handgepflegte Hex-Werte waeren zehn
   Gelegenheiten, einen Farbwechsel zu uebersehen. Die Missionsseite nutzt
   dasselbe Partial und dieselben Klassen. */
.welle--milk svg path {
  fill: var(--milk);
}

.welle--milk-warm svg path {
  fill: var(--milk-warm);
}

.welle--espresso svg path {
  fill: var(--espresso);
}

/* Im erzwungenen Kontrast gibt es keine Flaechenfarben mehr: die Welle
   bleibt als Linie sichtbar, sonst verschwindet der Sektionswechsel. */
@media (forced-colors: active) {
  .welle svg path {
    fill: Canvas;
    stroke: CanvasText;
    stroke-width: 2;
  }
}

/* ==================== SECTION WAVE BACKGROUND ==================== */
/* Subtile Wellen als Hintergrund-Element für Sections */
/* Farben können per CSS-Variablen überschrieben werden */

.section-wave-bg {
  position: relative;
  overflow: hidden;
  /* Default-Farben (warm/cream) - können überschrieben werden */
  --wave-color-1: rgba(240, 229, 219, 0.7);  /* Hintere Welle */
  --wave-color-2: rgba(237, 225, 214, 0.4);  /* Vordere Welle */
}

.section-wave-bg::before,
.section-wave-bg::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 70%;
  pointer-events: none;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: bottom;
  mask-position: bottom;
}

/* Hintere Welle */
.section-wave-bg::before {
  z-index: 0;
  background-color: var(--wave-color-1);
  -webkit-mask-image: url("../images/waves/wave-mask-1.a05dcc3f54de.svg");
  mask-image: url("../images/waves/wave-mask-1.a05dcc3f54de.svg");
}

/* Vordere Welle */
.section-wave-bg::after {
  z-index: 0;
  background-color: var(--wave-color-2);
  -webkit-mask-image: url("../images/waves/wave-mask-2.880a5c160984.svg");
  mask-image: url("../images/waves/wave-mask-2.880a5c160984.svg");
}

.section-wave-bg > .container {
  position: relative;
  z-index: 1;
}

/* Wellen-Varianten: Verschiedene Formen für Abwechslung */

/* Variante B: Sanft + Asymmetrisch */
.section-wave-bg-b::before {
  -webkit-mask-image: url("../images/waves/wave-mask-3.141891af9168.svg");
  mask-image: url("../images/waves/wave-mask-3.141891af9168.svg");
}
.section-wave-bg-b::after {
  -webkit-mask-image: url("../images/waves/wave-mask-4.02d8e8335fce.svg");
  mask-image: url("../images/waves/wave-mask-4.02d8e8335fce.svg");
}

/* Variante C: Doppelt sanft + Dramatisch */
.section-wave-bg-c::before {
  -webkit-mask-image: url("../images/waves/wave-mask-5.3a26f6ef2c9e.svg");
  mask-image: url("../images/waves/wave-mask-5.3a26f6ef2c9e.svg");
}
.section-wave-bg-c::after {
  -webkit-mask-image: url("../images/waves/wave-mask-6.05149721a118.svg");
  mask-image: url("../images/waves/wave-mask-6.05149721a118.svg");
}

/* Variante D: Asymmetrisch + Sanft (umgekehrt) */
.section-wave-bg-d::before {
  -webkit-mask-image: url("../images/waves/wave-mask-4.02d8e8335fce.svg");
  mask-image: url("../images/waves/wave-mask-4.02d8e8335fce.svg");
}
.section-wave-bg-d::after {
  -webkit-mask-image: url("../images/waves/wave-mask-3.141891af9168.svg");
  mask-image: url("../images/waves/wave-mask-3.141891af9168.svg");
}

/* ==================== STEP CARDS (.steps-grid abgebaut, Grep: 0 Konsumenten) ==================== */

.step-card {
  text-align: left;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* .step-icon-wrapper, .step-icon-wrapper .step-number und
   .step-card .icon-feature-primary abgebaut (schlichter oeffentlicher
   Bereich, Grep: 0 Konsumenten) — der Schritt trug ein Symbol mit
   angehefteter Nummer ueber der Ueberschrift. Die Nummer steht jetzt
   allein im Schritt und nutzt die Grundregel .step-number. */

.feature-link {
  color: var(--accent);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: auto;
  padding-top: 0.75rem;
}

.feature-link:hover {
  text-decoration: underline;
}

/* Feature-Cards linksbündig */
.feature-card.text-start {
  text-align: left;
}


.step-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: var(--accent-dark);
  color: #fff;
  border-radius: 50%;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 1rem;
}

/* ==================== FEATURES SLIDER ==================== */

.features-slider-container {
  position: relative;
}

.features-slider {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  gap: 1.5rem;
  padding: 1rem 0.5rem;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.features-slider::-webkit-scrollbar {
  display: none;
}

.features-slider .feature-card {
  flex: 0 0 280px;
  scroll-snap-align: start;
}

/* Reihe ohne Knoepfe: mobil wischbar mit scroll-snap, ab 768px ein Raster.
   Die Spaltenzahl haengt an --slider-spalten (Standard 3), damit dieselbe
   Reihe mit drei Stationen und mit acht Massnahmen auskommt. Die Reihe
   selbst scrollt (overflow-x am Container), die Seite nie.

   Ohne Knoepfe, Punkte und Scrollleiste ist der Anschnitt der naechsten
   Karte der einzige Hinweis auf mehr Inhalt: die Karte nimmt deshalb
   hoechstens 82 % der Reihe ein, auf 320 px bleiben so rund 30 px der
   naechsten Karte sichtbar, mit 280 px festen Karten waeren es 0. */
.features-slider--md-grid .feature-card {
  flex-basis: min(280px, 82%);
}

/* Die Reihe ist eine Tab-Station (tabindex="0" im Markup), damit sie ohne
   fokussierbares Kind per Tastatur blaetterbar ist. Eine Station ohne
   sichtbaren Fokus waere eine unsichtbare Falle. */
.features-slider:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

@media (min-width: 768px) {
  .features-slider--md-grid {
    display: grid;
    grid-template-columns: repeat(var(--slider-spalten, 3), minmax(0, 1fr));
    overflow: visible;
    scroll-snap-type: none;
    padding: 0;
  }

  .features-slider--md-grid .feature-card {
    flex: none;
  }
}

.slider-nav {
  display: flex;
  justify-content: center;
  gap: 1rem;
  margin-top: 1.5rem;
}

/* .slider-dots/.slider-dot (Audit B4/UX4-11+UX6-08) sowie .slider-btn,
   .slider-btn-small und .slider-nav-top (Startseiten-Prototyp B7) abgebaut,
   Grep: 0 Konsumenten — die Startseite blaettert nicht mehr. */

/* ==================== BENEFITS GRID ==================== */

.benefits-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
}

.benefit-item {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  padding: 1rem;
  background: #fff;
  border-radius: 12px;
  border: 1px solid var(--hairline);
}

.benefit-item strong {
  font-family: var(--font-display);
  font-size: 0.95rem;
  color: var(--espresso);
  display: block;
  margin-bottom: 0.25rem;
}

.benefit-item p {
  font-size: 0.85rem;
  color: var(--stone-500);
  margin: 0;
}

@media (max-width: 767.98px) {
  .benefits-grid {
    grid-template-columns: 1fr;
  }
}

/* Register-Variante: Zeilen mit Haarlinie statt Karten. Sieben Karten in
   zwei Spalten wuerden die Feature-Uebersicht zur Kachelwand machen; ein
   Register liest sich wie eine Liste und bleibt ruhig. Der akzentfarbene
   .benefit-icon ist abgebaut (Grep: 0 Konsumenten).

   Die Motive sind mobil groesser und tragen einen WEISSEN Kreis. .icon-ring
   nimmt seinen Grund aus --milk-warm und waere auf dieser Sektion unsichtbar;
   weiss ist auf --milk-warm sichtbar, wo --milk-warm es nicht ist, und nimmt
   dem Register den durchgehend beigen Eindruck. Der Kreis ist deshalb eine eigene Klasse
   (.benefit-item-ring) und nicht .icon-ring. */
.benefits-grid--register {
  row-gap: 0;
  column-gap: 3rem;
  border-top: 1px solid var(--hairline);
}

.benefit-item--register {
  padding: 1rem 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  border-radius: 0;
}

.benefit-item-motiv {
  display: block;
  flex: none;
  width: var(--icon-2xl);
  height: var(--icon-2xl);
  margin-top: 0.15rem;
}

/* Der weisse Kreis hinter dem Motiv. Er ist randlos, ohne Haarlinie.

   Weiss auf --milk-warm sind 1,15:1, und die Flaechen INNERHALB der Motive
   liegen ohnehin auf --milk-pure. Kreis und Motivflaeche verschmelzen deshalb
   zu einer weissen Flaeche, in der die Kontur die Form traegt. Der Kreis
   rahmt das Motiv also nicht, er hellt die Zeile auf. Das ist der Zweck.

   Diese Regeln stehen HINTER .benefit-item-motiv und nicht im mobilen Block
   weiter oben: test_startseite_sektionen.py sucht die erste Regel zu
   .benefit-item-motiv im Blatt und verlangt dort --icon-2xl. Eine frueher
   stehende Regel wuerde diesen Wächter kapern. */
.benefit-item-ring {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--milk-pure);
}

@media (forced-colors: active) {
  /* Ohne Rand bliebe vom Kreis hier nichts: Systemfarben ueberschreiben den
     Grund. Gleiche Behandlung wie .icon-ring. */
  .benefit-item-ring {
    border: 1px solid CanvasText;
  }
}

@media (max-width: 767.98px) {
  /* Mobil traegt das Motiv --icon-3xl (48 px). Die Stufe steht auf der
     Symbolskala (frontend-design.md §5); ein Zwischenwert waere der Wildwuchs,
     den die Skala beseitigt hat. Der Kreis waechst mit, damit der Rand um das
     Motiv gleich breit bleibt. */
  .benefit-item-ring {
    width: 4rem;
    height: 4rem;
  }

  .benefit-item-motiv {
    width: var(--icon-3xl);
    height: var(--icon-3xl);
    margin-top: 0;
  }
}

@media (min-width: 1200px) {
  .benefits-grid--register {
    column-gap: 5rem;
  }

  .benefit-item--register {
    padding: 1.25rem 0;
  }
}

/* ==================== STORY NOTE (Gruender-Notiz) ==================== */

/* Die Gruender-Geschichte auf /mission/ ist Lesetext, keine Kachel: linker
   Flattersatz, groessere Laufweite, mehr Innenabstand als eine .card sonst
   hat. Sie erbt Grund und Rahmen von .card und setzt nur den Lesefluss. */
.story-note {
  padding: 2.5rem;
  text-align: left;
}

.story-note p {
  font-family: var(--font-sans);
  font-size: 1.05rem;
  color: var(--stone-600);
  line-height: 1.8;
  margin-bottom: 1.5rem;
}

/* Spezifitaet gleichzieht mit `.story-note p` darueber — ein blosses
   .story-signature verlore gegen Klasse-plus-Element. */
.story-note .story-signature {
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--espresso);
}

@media (max-width: 575.98px) {
  .story-note {
    padding: 1.5rem;
  }
}

/* ==================== PRICING HIGHLIGHT ==================== */

.pricing-highlight {
  background: var(--espresso);
  color: var(--milk);
  border-radius: 20px;
  padding: 3rem;
  text-align: center;
}

/* h2 gehoert dazu: auf /mission/ ist die Preisfrage eine Sektionsueberschrift
   und darf keine h3 sein. Ohne sie erbte die Ueberschrift --espresso und stand
   unsichtbar auf dem espressofarbenen Grund. */
.pricing-highlight h2,
.pricing-highlight h3 {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 600;
  color: var(--milk);
  margin-bottom: 0.5rem;
}

.pricing-highlight p {
  color: var(--stone-400);
  font-size: 1rem;
  margin-bottom: 1.5rem;
}

.pricing-highlight .btn-primary {
  background-color: var(--accent-dark);
  color: #fff;
}

/* ==================== HIGHLIGHT SECTIONS ==================== */

.highlight-desc {
  font-family: var(--font-sans);
  font-size: 1.05rem;
  color: var(--stone-600);
  line-height: 1.7;
  margin-bottom: 1.5rem;
}

/* ==================== BLOG CARDS ==================== */

.blog-card {
  background: #fff;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--hairline);
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: transform 0.2s ease;
}

.blog-card:hover {
  transform: translateY(-4px);
}

/* .blog-card-image abgebaut (Grep: 0 Konsumenten).
   Die Flaeche war ein Bildplatzhalter, der nie ein Bild trug, sondern ein
   Symbol ueber der Artikelueberschrift — genau das, was hier faellt. Ohne
   Symbol waere ein leerer getoenter Balken uebriggeblieben, deshalb ging die
   Flaeche mit. Kommen echte Artikelbilder, kommt sie als Bildflaeche zurueck.
   Die Zweitregel `.blog-card-image i` war ohnehin tot: sie setzte eine
   Schriftgroesse auf ein <i>, also auf das nicht mehr eingebundene
   Bootstrap-Icons-Font. */

.blog-card-body {
  padding: 1.5rem;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.blog-card-title {
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 600;
  color: var(--espresso);
  margin-bottom: 0.5rem;
  line-height: 1.4;
}

.blog-card-excerpt {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--stone-500);
  font-style: italic;
  flex: 1;
  margin-bottom: 1rem;
}

.blog-card .feature-link {
  margin-top: auto;
}

/* ==================== HERO PREVIEW PLACEHOLDER ==================== */

.hero-preview-placeholder {
  background: linear-gradient(145deg, var(--milk-warm) 0%, #fff 100%);
  border-radius: 20px;
  padding: 2rem;
  border: 1px solid var(--stone-200);
  aspect-ratio: 4/3;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--stone-400);
  font-family: var(--font-sans);
}

/* Audit B4/UX4-12: „FOOTER NO UNDERLINE" nach oben in den FOOTER-Abschnitt
   gebündelt — Fußzeilen-Regeln stehen nur noch dort. */

/* ==================== STEP CARDS ==================== */

.step-title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--espresso);
  margin-bottom: 0.5rem;
}

.step-desc {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--stone-500);
}

/* ==================== ACCORDION ==================== */

.accordion {
  --bs-accordion-border-color: var(--stone-200);
  --bs-accordion-border-radius: 16px;
  --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(42, 157, 143, 0.25);
}

.accordion-item-rounded {
  border-radius: 16px;
  margin-bottom: 1rem;
  overflow: hidden;
}

.accordion-button {
  font-family: var(--font-sans);
  font-weight: 600;
  color: var(--espresso);
}

.accordion-body {
  font-family: var(--font-sans);
  color: var(--stone-600);
}

/* ==================== HERO SPECIFIC ==================== */

.hero-title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 3.5rem);
  font-weight: 600;
  margin-bottom: 1.5rem;
  line-height: 1.2;
}

.hero-title-espresso {
  color: var(--espresso);
}

.hero-title-crema {
  color: var(--crema);
}

.hero-lead {
  font-family: var(--font-sans);
  font-size: 1.25rem;
  color: var(--stone-500);
  margin-bottom: 2rem;
}

/* ==================== CTA SECTION ==================== */

.section-espresso h2 {
  color: var(--milk);
}

.section-espresso p {
  color: var(--stone-400);
}

.cta-subtitle {
  font-family: var(--font-sans);
  font-size: 1.1rem;
  color: var(--stone-400);
  margin-bottom: 2rem;
  max-width: 500px;
  margin-left: auto;
  margin-right: auto;
}

/* ==================== UTILITY CLASSES ==================== */

.icon-accent {
  color: var(--accent);
}

.subtitle-centered {
  font-family: var(--font-sans);
  font-size: 1.1rem;
  color: var(--stone-500);
  max-width: 600px;
}

.text-sm-muted {
  font-size: 0.85rem;
  color: var(--stone-400);
}

/* Der Wissensbereich (/wissen/) bringt seine Gestaltung seit August 2026 in
   css/wissen.css mit, geladen ueber extra_css — wie startseite.css und
   reise.css. Die frueheren Bloecke ARTICLE CONTENT, TABLE OF CONTENTS,
   SUMMARY BOX und EXTERNAL LINKS sind dorthin umgezogen: sie hatten
   ausserhalb von md_content keinen Konsumenten und luden bis dahin auf
   jeder Seite mit. */

/* ==================== FORMULAR-FELDER (alle Flächen) ==================== */
/* FEATURE-0134 AC-44: Feinschliff der allauth-Karten — Felder folgen dem
   form-fields-Idiom des Design-Systems (12px-Radius, Accent-Fokusring statt
   Bootstrap-Blau, Checkbox im Accent-Ton). base_public.html lädt kein
   dashboard-theme.css/app-components.css, daher leben die Regeln hier.

   FEATURE-0145: Der gesamte Feld-Layer ist hierher gezogen — Mini-Label,
   Eingabefeld, Auswahlfeld samt Chevron, Rückmeldungstexte und die Größe der
   Auswahlkästchen. Er lag in app-components.css und app.css, die base.html
   lädt und base_public.html nicht; Labels, Fehler- und Hilfetexte der
   Auth-Seiten standen deshalb auf Bootstrap-Defaults. Dieses Blatt laden
   beide Grundgerüste, es ist der einzige Ort, an dem der Layer einmal
   definiert für beide Flächen gilt.

   Warum nicht app-components.css zusätzlich in base_public.html: dessen
   erste Regel setzt `body { font-family: var(--font-app) }` (Manrope).
   Startseite und Auth sprängen von DM Sans auf Manrope — ein Markeneingriff,
   der hier nicht beauftragt ist (AC-09, Wächter in
   code/tests/test_audit_b2_formfelder.py).

   Scope: Die Regeln bleiben auf .app-form/.filter-form gescopet.
   Ungescopet würde die Uppercase-Regel den Cashflow-Simulator auf der
   Startseite (templates/public/_cashflow_simulator.html) mit umlackieren,
   der dieselben Bootstrap-Klassen ohne Formular benutzt. */

/* Gemeinsame Auth-Card-Breite (Änderungsrunde U-01/U-03): EINE Regel für
   alle allauth-Karten statt col-lg/col-xl-Staffelung pro Template —
   großzügig genug, dass „Mit Microsoft anmelden" einzeilig bleibt. */
.auth-card-col {
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
}

/* FEATURE-0322: „Nutzungsbedingungen" passt bei 390 px nicht in eine Zeile
   und brach ohne Trennstrich vor dem letzten Buchstaben. Wie BUG-0262 an der
   Silbengrenze trennen.

   Review 26.09.2026 K3: NICHT auf .auth-card-col h1 — das traf auch
   Anmelden, Registrieren und die 2FA-Seiten mit, die niemand angesehen hat.
   Auf die Überschrift der Abfrageseite begrenzt. FEATURE-0388: ebenso
   „Datenschutzerklärung" auf der Seite der Kenntnisnahme. */
[data-testid="nutzungsbedingungen-title"],
[data-testid="datenschutz-kenntnisnahme-title"] {
  hyphens: auto;
}

.form-control,
.form-select {
  /* Audit B4C/A5-09: Feldrahmen über --control-border (3,73:1, SC 1.4.11) */
  border-color: var(--control-border);
  border-radius: var(--radius-lg);
  color: var(--espresso);
  transition: border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.form-control::placeholder {
  /* Audit B4C/A5-08: Rollen-Token statt --stone-400 (2,91:1) — 4,83:1 auf Weiß.
     Gilt ungescopet für jedes Eingabefeld; die frühere Zweitfassung unter
     .filter-form/.app-form in app-components.css setzte denselben Wert und
     ist mit dem Umzug ersatzlos entfallen (FEATURE-0145). */
  color: var(--text-secondary);
}

/* ---- Feld-Layer der Formulare (aus app-components.css, FEATURE-0145) ---- */

/* Labels: uppercase Mini-Label.
   .app-form = Bearbeiten-/Erfassungs-Formulare, .filter-form = Filterkarten
   der Listen — derselbe Feld-Layer, zwei Einsatzorte. */
.filter-form .form-label,
.app-form .form-label {
  font-size: var(--fs-11); font-weight: 600; color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 7px;
}

/* Gruppenname einer Auswahlgruppe: includes/_form_radio_group.html sowie die
   drei Gruppen mit eigenem Optionen-Markup (Belegtyp-Umschalter in
   receipt_form/receipt_update, Kostenträger-Karten in submission_form).
   Bootstrap gibt <legend> im Reboot float: left, width: 100% und eine
   Überschriftengröße — damit bräche die Legende die Gruppe auf. Die Regel
   hängt an .form-label statt an .app-form: nur diese Fundstellen erzeugen die
   Kombination, fremde Legenden bleiben unberührt. */
legend.form-label {
  float: none;
  width: auto;
  line-height: inherit;
}

/* Inputs + Selects: Token-Radius, --control-border; der Türkis-Fokus-Ring
   kommt aus der Regel darunter (Audit B2/UX4-02: eine Definition statt drei). */
.filter-form .form-control,
.filter-form .form-select,
.app-form .form-control,
.app-form .form-select {
  /* Audit B4C/A5-09: Feldrahmen über --control-border (3,73:1) statt
     --stone-200 (1,34:1) — Felder sind vom Hintergrund unterscheidbar. */
  padding: 11px 14px; border: 1px solid var(--control-border); border-radius: var(--radius-lg);
  font-size: var(--fs-14); color: var(--espresso); background-color: white;
  transition: all var(--dur-fast) var(--ease-out);
}

/* BUG-0200: Ein gesperrtes Feld (readonly, z. B. der Betrag eines eingereichten
   Belegs) sieht nicht aus wie ein bedienbares — „sichtbar sperren, nicht nur
   sperren" (.claude/rules/views-htmx.md). Text bleibt espresso für den Kontrast. */
.app-form .form-control[readonly] {
  background-color: var(--stone-100);
  cursor: not-allowed;
}

/* Select: eigener Chevron statt Bootstrap-Default */
.filter-form .form-select,
.app-form .form-select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 42px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%237A7068' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
}

/* BUG-0236: Eine gesperrte Auswahl (die Person eines eingereichten Belegs) sieht
   aus wie ein gesperrtes Eingabefeld. Ein <select> kennt kein readonly; die
   Sperre steht als aria-readonly, die Auswahl bietet nur noch den gespeicherten
   Wert an. Ohne Chevron, weil es nichts aufzuklappen gibt. */
.app-form .form-select[aria-readonly="true"] {
  padding-right: 14px;
  background-color: var(--stone-100);
  background-image: none;
  cursor: not-allowed;
}

/* Rückmeldungstexte unter dem Feld (aus app.css, FEATURE-0145). Ungescopet
   wie in app.css — Bootstrap blendet beide ohnehin nur neben einem
   is-valid/is-invalid-Feld oder mit d-block ein. */
.valid-feedback {
  /* War das Literal #22c55e — wertgleich mit --success-light. */
  color: var(--success-light);
  font-size: var(--fs-12);
}

.invalid-feedback {
  color: var(--danger);
  font-size: var(--fs-12);
}

/* Audit B2/UX4-02: die EINE Fokus-Ring-Definition (vorher drei). Die
   .filter-form/.app-form-Selektoren bleiben in der Liste: gegen die
   Feld-Regel oben braucht es sie seit FEATURE-0145 nicht mehr (sie steht
   jetzt im selben Blatt darüber), wohl aber gegen die später geladenen
   Zeilen-Regeln in app-components.css. `.li-row--conf-high .form-select`
   und Geschwister setzen dort border-color bei gleicher Spezifität wie ein
   ungescopetes `.form-select:focus` — ohne die Scopes bliebe der Rahmen
   einer Positionszeile im Fokus in der Konfidenzfarbe stehen. Gleiches gilt
   vorsorglich für .line-items-table, .stmt-table und #deductibles-table. */
.form-control:focus,
.form-select:focus,
.filter-form .form-control:focus,
.filter-form .form-select:focus,
.app-form .form-control:focus,
.app-form .form-select:focus {
  /* Audit B4C/A5-12: Glow 0.15 → 0.25 (wie Toggle/Accordion/Range) — nur
     Begleiteffekt, die normative Fokusanzeige ist der outline-Ring der
     gemeinsamen Fokusregel (Accessibility-Sektion). */
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(42, 157, 143, 0.25);
}

/* Audit B4 Global/A7-14: Das native Loeschen-Symbol wird ausgeblendet, nicht
   gestaltet. Sobald ein Suchbegriff im Feld stand, zeigte der Browser sein
   eigenes Kreuz — und _search_input.html legte die eigene Schaltflaeche mit
   circle-x direkt daneben. Zwei Kreuze nebeneinander, beide loeschen dasselbe.

   Damit entfaellt auch die Einfaerbung aus Audit B4C/A5-08 (stone-500 statt
   Browser-Grau, wegen der 3:1-Schwelle fuer Bedienelement-Icons): ein Symbol,
   das niemand sieht, braucht keinen Kontrast. Die eigene Schaltflaeche bleibt
   die einzige — sie sieht in jedem Browser gleich aus und traegt ein
   aria-label.

   -webkit-appearance:none bleibt stehen: ohne diesen Reset laesst Chrome das
   Pseudo-Element gar nicht erst gestalten. */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

/* Auswahlkästchen: 20px statt Bootstrap-16px (Audit B4C/A4-06, aus
   app-components.css hierher, FEATURE-0145). margin-top gleicht die größere
   Box gegen die 24px-Textzeile aus; Switches behalten ihre Pillen-Proportion
   (36×20 statt 32×16). Die 44px-Trefferfläche ist die zentrierte
   ::after-Hitbox weiter oben in diesem Blatt — die rechnet mit genau diesen
   20px, deshalb gehören Größe und Hitbox in dieselbe Datei. */
.form-check-input {
  /* Audit B4C/A5-09: Rahmen über --control-border (3,73:1, SC 1.4.11)
     statt --stone-300 (1,92:1) */
  border-color: var(--control-border);
  width: 20px;
  height: 20px;
}

.form-check .form-check-input { margin-top: 0.125rem; }
.form-switch .form-check-input { width: 36px; }

.form-check-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(42, 157, 143, 0.25);
}

.form-check-input:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}

/* ===== Inline-Code (Design-Konsistenz Batch 3) =====
   Bootstrap rendert <code> per Default in Magenta (#d63384) - das bricht in
   App und Marketing sichtbar mit der Cappuccino-Palette (IBAN in den
   Bankkonten, Einladungs-Codes, PZN, GOAE-Ziffern, Platzhalter in der Doku).
   Eine zentrale Regel statt Overrides an jeder Call-Site: Monospace bleibt
   (Zifferngruppen bleiben ausgerichtet), die Farbe kommt aus den Tokens.
   Liegt in cappuccino.css, weil base.html UND base_public.html das Blatt laden. */
code {
  color: var(--espresso);
  background-color: var(--tint-warm);
  padding: 0.125rem 0.375rem;
  border-radius: var(--radius-sm);
  font-size: 0.875em;
}

/* Codes in Tabellenzellen und auf getoenten Flaechen: ohne eigene Flaeche,
   damit Zeilenhoehen und Gruppenzeilen-Tints nicht doppelt getoent wirken. */
td > code,
th > code {
  background-color: transparent;
  padding-inline: 0;
}

/* ===== Kruemelzeile (App + oeffentlicher Bereich) =====
   Stand bis August 2026 in app-components.css und damit nur hinter dem Login.
   Der Wissensbereich trug daneben eine nackte Bootstrap-.breadcrumb — zwei
   Gestaltungen fuer dieselbe Sache. Die Regeln liegen jetzt hier, weil
   base.html UND base_public.html dieses Blatt laden; eine Kopie im Marketing
   waere die naechste Divergenz gewesen.

   Zwei Unterschiede zwischen den Flaechen sind gewollt: In der App erbt die
   Zeile Manrope, oeffentlich DM Sans (Schriftfamilie der jeweiligen Flaeche).
   Und im oeffentlichen Bereich steht sie ohne Symbol, waehrend die App ein
   arrow-left traegt (frontend-design.md §6b) — deshalb laeuft das gap
   dort ins Leere.

   Vorbestehende Abweichung, mit umgezogen: --accent auf --milk ergibt bei
   12px 3,21:1 und liegt damit unter AA. Gilt in der App seit jeher genauso;
   ein Heben auf --accent-dark waere eine Aenderung an 27 Call-Sites und
   gehoert vor den PO, nicht in einen Breadcrumb-Angleich. */
.detail-back {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-12); font-weight: 600; color: var(--accent);
  text-decoration: none; margin-bottom: 7px;
}
.detail-back:hover { color: var(--accent-dark); }
/* Breadcrumb-Zeile: Zurück-Link + weitere Segmente ("Belege / Beleg-Details").
   white-space:nowrap auf den Kindern verhindert, dass ein einzelnes Segment
   INTERN mehrzeilig umbricht (Flex-Items schrumpfen sonst per Default
   (min-width:auto) unter ihre Textbreite, sobald die Segmentsumme nicht mehr
   in eine Zeile passt — "Abrechnung vom" / "15.09.2026" landeten dadurch in
   getrennten Spalten). Kein flex-wrap: ein Segment, das dennoch übersteht,
   soll nicht als eigene Zeile umbrechen (das ergab „/" allein am Zeilenende
   und ein einsames Folgesegment darunter), sondern per Ellipsis gekürzt
   werden — siehe die mobile Regel unten. */
.detail-crumbs {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--fs-12); font-weight: 500; color: var(--text-secondary);
  margin-bottom: 7px;
}
.detail-crumbs > * { white-space: nowrap; }
.detail-crumbs .detail-back { margin-bottom: 0; }

/* Mobil (BUG-0203-Nachtrag, 16.09.2026): dasselbe Muster wie
   `.article-head .crumb-current`/`.crumb-sep` in wissen.css, hier auf
   .detail-crumbs generalisiert statt auf den Wissensbereich beschränkt. Das
   aktuelle ("Sie sind hier")-Segment entfällt — der Seitentitel (H1) nennt es
   ohnehin zwei Zeilen weiter. `> span:last-child` trifft NUR Krumen mit einem
   solchen Segment: Es ist immer ein <span> (nie ein Link). Krumen, die nur
   aus dem Zurück-Link bestehen (<a>, einziges Kind, z.B. "Zurück zum
   Dashboard"), bleiben unberührt — dort ist :last-child ein <a>.
   :has() wählt den Trenner davor nur dann mit aus, wenn tatsächlich ein
   Sie-sind-hier-Segment vorhanden ist (sonst gäbe es bei einem einzelnen
   Trenner-losen Rücksprung nichts zu verstecken). */
@media (max-width: 767.98px) {
  .detail-crumbs > span:last-child { display: none; }
  .detail-crumbs:has(> span:last-child) > span:nth-last-child(2) { display: none; }

  /* Verbleibt danach noch ein zu langer Linktext (z.B. ein Abrechnungsdatum
     oder ein Vertragstitel), sprengt er sonst weiter die Zeile. Nur
     Nicht-erste Links sind hier variabler Text ohne Icon — der erste
     Zurück-Link trägt das arrow-left-Symbol und ist ohnehin ein festes,
     kurzes Wort ("Abrechnungen", "Belege", …), bleibt also inline-flex.
     text-overflow:ellipsis zeigt auf einem Flex-Container KEINE Auslassungs-
     punkte (nur hartes Abschneiden) — deshalb hier gezielt auf
     display:inline-block zurück: Diese Segmente tragen nie ein Icon, sind
     also reiner Text ohne Flex-Bedarf. */
  .detail-crumbs > a.detail-back:not(:first-child) {
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex-shrink: 1;
    vertical-align: middle;
  }
}

/* Unscoped Basisgeometrie (BUG-0390, 22.09.2026, Option 1): Stand bis dahin
   in app.css ("Star Admin 2 style") und damit nur hinter dem Login. Ohne sie
   bleibt ein Badge auf einer oeffentlichen Seite bei Bootstraps
   font-weight:700 — sichtbar kraeftiger als in der App, obwohl dieselbe
   Klasse (badge status-neutral in core/fee_schedule/detail.html,
   core/public/preise.html, core/public/startseite.html). Bewusst nur hier:
   die Farben unten gelten bereits fuer beide Flaechen, nur die Geometrie war
   zurueckgeblieben. Steht vor den Farben und der status-neutral-Ausnahme:
   Basis, Farben, Ausnahme. */
.badge {
    font-weight: 500;
    padding: 0.35em 0.65em;
}

/* ===== Status-Badges (App + oeffentlicher Bereich) =====
   Stand bis August 2026 in app.css und damit nur hinter dem Login. Bootstraps
   `.badge` setzt weisse Schrift auf transparenten Grund — ohne Farbregel ist
   ein Status-Badge auf einer oeffentlichen Seite weiss auf weiss. Der Fehler
   steht nicht im Markup und faellt in keinem HTML-Test auf: Er entsteht erst
   in der Kaskade.

   Genau diese Falle wurde dreimal umgangen statt entschaerft — mit einer
   eigenen Regel in preise.css, mit eigenen Badge-Klassen in reise.css und mit
   dem Geometrie-Block in app-components.css. Die Farbzuordnung liegt jetzt
   hier, weil base.html UND base_public.html dieses Blatt laden; jede weitere
   Kopie waere die naechste Divergenz.

   Bewusst nur die Farben: Die Geometrie (Polsterung, Rundung, Symbolgroesse)
   bleibt in app-components.css, weil sie dort zugleich die
   .badge-*-Klassen der Belegliste bedient und zum App-Chrome gehoert.
   Oeffentlich gilt Bootstraps Badge-Geometrie — Ausnahme (BUG-0390):
   .badge.status-neutral ist die
   einzige status-*-Klasse mit Konsumenten im oeffentlichen Bereich
   (core/fee_schedule/detail.html, core/public/preise.html,
   core/public/startseite.html) und bekommt ihr font-weight deshalb hier,
   nicht mehr zusaetzlich aus app-components.css — Ursache geloest statt
   den Wert an zwei Stellen zu pflegen.

   Farbwerte ausschliesslich aus tokens.css (FEATURE-0134 AC-17, Entscheidung
   A: muted statt Bootstrap-Solids). Welches Token welche Bedeutung traegt,
   steht in .claude/rules/frontend-design.md, Abschnitt 6. */
.badge.status-open    { background-color: var(--status-open-bg);    color: var(--status-open-fg); }
.badge.status-pending { background-color: var(--status-pending-bg); color: var(--status-pending-fg); }
.badge.status-success { background-color: var(--status-success-bg); color: var(--status-success-fg); }
.badge.status-neutral { background-color: var(--status-neutral-bg); color: var(--status-neutral-fg); }
.badge.status-error   { background-color: var(--status-error-bg);   color: var(--status-error-fg); }

/* BUG-0390: font-weight fuer .badge.status-neutral an der Stelle, die
   beide Bereiche laden. Ohne diese Regel kaeme der App-Wert 600 nur aus der
   spezifischeren Regel in app-components.css, und der oeffentliche Bereich
   bliebe bei der unscoped Basisgeometrie (500). Nur diese Klasse, die
   uebrigen .badge-*-Klassen bleiben App-only in app-components.css. */
.badge.status-neutral {
    font-weight: 600;
}

/* ===== Alerts (App + oeffentlicher Bereich) =====
   BUG-0390 (22.09.2026, Option 1): Stand bis dahin in app.css (Audit
   B2/UX4-03+UX5-03+A3-10) und damit nur hinter dem Login wirksam —
   base_public.html laedt app.css nicht (dieselbe Fehlerklasse wie
   BUG-0271: eine App-Kompat-Regel ohne Konsumenten auf oeffentlichen
   Seiten). Die vier Bootstrap-Alert-Varianten werden auf die
   --status-*-Tokens und den Kartenradius abgebildet: Flaeche aus den
   -bg-Tokens, Text und Rand aus den -fg-Tokens — dieselbe Farbsprache wie
   die Status-Badges oben. Kein Template angefasst, alle Fundstellen ziehen
   mit; Django-Formularfehler (alert-danger) ebenso.
   Erklaerende alert-info-Hinweise (reine Tipps ohne Warn-/Fehlercharakter)
   sind mit demselben Ticket zu gedaempftem Fliesstext ohne Box umgebaut
   (siehe .hint-text weiter unten) — die alert-info-Regel unten bleibt fuer
   die verbleibenden echten Info-Faelle im App-Bereich (dort weiterhin als
   Box verwendet) sowie als Absicherung, falls ein neues Template die Klasse
   setzt. */
.alert {
    --bs-alert-border-radius: var(--radius-lg);
}

.alert-success {
    --bs-alert-color: var(--status-success-fg);
    --bs-alert-bg: var(--status-success-bg);
    --bs-alert-border-color: var(--status-success-fg);
    --bs-alert-link-color: var(--status-success-fg);
}

.alert-warning {
    --bs-alert-color: var(--status-open-fg);
    --bs-alert-bg: var(--status-open-bg);
    --bs-alert-border-color: var(--status-open-fg);
    --bs-alert-link-color: var(--status-open-fg);
}

.alert-danger {
    --bs-alert-color: var(--status-error-fg);
    --bs-alert-bg: var(--status-error-bg);
    --bs-alert-border-color: var(--status-error-fg);
    --bs-alert-link-color: var(--status-error-fg);
}

.alert-info {
    --bs-alert-color: var(--status-pending-fg);
    --bs-alert-bg: var(--status-pending-bg);
    --bs-alert-border-color: var(--status-pending-fg);
    --bs-alert-link-color: var(--status-pending-fg);
}

/* also_fixed (Audit B2/UX4-03+UX5-03+A3-10): alert-secondary (1 Fundstelle,
   settings/_googledrive_guide.html) — neutraler Hinweis, daher
   Neutral-Status-Tokens statt Tasse-Braun. */
.alert-secondary {
    --bs-alert-color: var(--status-neutral-fg);
    --bs-alert-bg: var(--status-neutral-bg);
    --bs-alert-border-color: var(--status-neutral-fg);
    --bs-alert-link-color: var(--status-neutral-fg);
}

/* ===== Hinweis ohne Box (App + oeffentlicher Bereich) =====
   BUG-0386/BUG-0390: Tipps und
   Erklaerungen ohne Warn- oder Fehlercharakter (Spam-Ordner-Tipp,
   Warteliste-Hinweis, Einladungs-Banner, Loeschhinweis im Bestaetigungsdialog)
   stehen als gedaempfter Fliesstext statt in einer alert-info-Box. Eine Klasse
   fuer beide Bereiche, deshalb hier und nicht in public.css oder
   app-components.css (Review 23.09.2026, Punkt 7). Abstaende setzt das
   Template (<p>-Standard oder Utility).
   .confirm-delete-hint ist ein Alias mit den bisherigen 14px Abstand nach
   unten, bis fix/BUG-0388-0389-personen (_member_delete_modal.html, ein <div>)
   auf .hint-text umgestellt ist; danach entfaellt er. */
.hint-text,
.confirm-delete-hint {
    color: var(--text-secondary);
    font-size: var(--fs-13);
}
.confirm-delete-hint {
    margin-bottom: 14px;
}

/* ===== app-range (App + oeffentlicher Bereich) =====
   BUG-0256: Aus app-components.css hierher verschoben. `accent-color`
   greift in WebKit/Chromium nicht, sobald `-webkit-appearance: none` UND ein
   eigenes `::-webkit-slider-thumb` mit `background-color` gesetzt sind —
   genau das tut Bootstraps kompiliertes Vendor-CSS mit einem hartkodierten
   `#0d6efd`. `.app-range` ueberschreibt das Pseudoelement explizit auf
   `var(--accent)`. War bisher nur in app-components.css definiert, das
   base_public.html nicht laedt — der oeffentliche Cashflow-Simulator blieb
   deshalb blau. Zusaetzlich zur `.form-range` setzen. */
.app-range::-webkit-slider-thumb { background: var(--accent); }
.app-range::-webkit-slider-thumb:active { background: var(--accent-dark); }
.app-range:focus::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(42, 157, 143, 0.25); }
.app-range::-webkit-slider-runnable-track { background: var(--stone-200); }
.app-range::-moz-range-thumb { background: var(--accent); border: 0; }
.app-range::-moz-range-thumb:active { background: var(--accent-dark); }
.app-range:focus::-moz-range-thumb { box-shadow: 0 0 0 3px rgba(42, 157, 143, 0.25); }
.app-range::-moz-range-track { background: var(--stone-200); }

/* ===== Toasts (BUG: gelber Toast wirkte unschliessbar) =====
   Zwei Fehler im Zusammenspiel: Der Schliessen-Button trug fest
   `btn-close-white`, was das X per filter invertiert. Auf den hellen Levels
   `text-bg-warning` und `text-bg-info` (Bootstrap rechnet dort dunklen Text
   aus) war Weiss-auf-Gelb unsichtbar - der Toast wirkte nicht wegklickbar,
   obwohl der Button da war. Die Invertierung gehoert daher nur auf die
   dunklen Levels, nicht ins Markup (heute: weisses SVG, siehe unten).
   Zweitens sprengten lange URLs aus Fehlermeldungen (OAuth-Endpunkte) den
   Toast, weil sie keine Umbruchstelle haben. */
.toast .toast-body {
  overflow-wrap: anywhere;
}

/* BUG-0025: Positive Meldungen tragen die Akzentfarbe statt Bootstrap-Gruen.
   Gruen bleibt fachliche Statusfarbe (--success, Status-Badges, Diagramme,
   In-Page-Hinweise) — deshalb weicht hier nur die Toast-Flaeche ab und nicht
   das Token. Verwendet wird --accent-dark und nicht --accent: weisse Schrift
   auf --accent erreicht nur 3,3:1, auf --accent-dark 5,7:1 (WCAG 1.4.3).
   !important ist Pflicht, weil Bootstraps .text-bg-success beides selbst
   mit !important setzt. Waechter: tests/e2e/test_toast_erfolg_tuerkis.py
   misst die gerenderte Farbe — die Kaskade entscheidet, nicht der Quelltext. */
.toast.text-bg-success {
  background-color: var(--accent-dark) !important;
  color: white !important;
}

/* BUG-0394 (22.09.2026): Die uebrigen vier Toast-Typen bekommen nach
   demselben Muster eine eigene, gepinnte Toast-Markenfarbe statt der
   generischen `--bs-*-rgb`-Verdrahtung (fuer info/warning/secondary neue
   Tokens, siehe tokens.css) bzw. statt Bootstraps unveraendertem Rohwert
   (info). Keine Wiederverwendung der Domain-Status-Tokens
   (`--status-pending-*`/`--status-open-*`) — verworfen, BUG-0394 Notes
   „Token-Paare": Die Trennung Toast-/Status-Semantik aus BUG-0025 gilt jetzt
   fuer alle fuenf Typen. Kontrastwerte an den Token-Definitionen. */
.toast.text-bg-info {
  background-color: var(--info-dark) !important;
  color: white !important;
}
.toast.text-bg-warning {
  background-color: var(--warning-dark) !important;
  color: white !important;
}
/* `danger` war schon vor diesem Ticket die eigene Markenfarbe (ueber
   --bs-danger-rgb), nur ungepinnt — der Wert aendert sich nicht (4,83:1,
   siehe tests/e2e/test_toast_erfolg_tuerkis.py). */
.toast.text-bg-danger {
  background-color: var(--danger) !important;
  color: white !important;
}
/* --espresso-light statt eines neuen Tokens: passt in die Espresso-Familie
   und erreicht 9,39:1 (WCAG AA) — kein eigenes `--secondary-dark` noetig. */
.toast.text-bg-secondary {
  background-color: var(--espresso-light) !important;
  color: white !important;
}

/* Toast-Schliessen-Button (BUG-0394, BUG-0404, Review 23.09.2026).
   Alle fuenf Toast-Flaechen sind dunkel mit weisser Schrift (BUG-0394), das X
   ist deshalb ueberall weiss. Es kommt als weisses SVG ueber background-image
   und nicht per `filter: invert(...)`: Ein filter wirkt auf alles, was das
   Element zeichnet, also auch auf Unterlegung und Fokusring. Der weisse Ring
   kam so schwarz an (2,24:1 auf --espresso-light), die Unterlegung dunkler
   als der Toast. Der SVG-Wert steht ausgeschrieben und nicht als Verweis auf
   eine Bootstrap-Variable: --bs-btn-close-white-filter hiess seit 5.3.1
   anders, der Verweis zeigte ins Leere, ohne dass CSS etwas meldete.
   Waechter: tests/e2e/test_bug_0404_toast_schliessen_button.py
   (TestSchliessenButtonOhneFilter).
   margin-left: auto schiebt den Knopf im Flex-Container nach rechts —
   Bootstraps `.toast-header .btn-close` greift nicht, weil _toast.html und
   toasts.js ohne .toast-header bauen. Die halbtransparente Unterlegung
   macht ihn als Schaltflaeche erkennbar (Vorbild .ins-icon-btn). */
.toast .btn-close {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");
  background-size: 10px;
  margin-left: auto;
  /* WCAG 2.2 SC 2.5.8: mindestens 24x24px sichtbare Klickflaeche. Die
     44px-Hitbox aus dem gemeinsamen Block oben deckt zusaetzlich den
     Sicherheitsabstand ab. */
  width: 24px;
  height: 24px;
  padding: 0;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.2);
  opacity: 1;
}
.toast .btn-close:hover {
  background-color: rgba(255, 255, 255, 0.32);
  opacity: 1;
}
/* Bootstraps Fokus-Ring (blauer box-shadow) passt auf keiner Toast-Flaeche.
   Das App-weite Fokus-Ring-Muster (--accent-dark, siehe :focus-visible-Block
   weiter oben) faellt hier ebenfalls aus: --accent-dark auf der
   Erfolgs-Toast-Flaeche (--accent-dark) waere derselbe Farbton wie der
   Ring selbst und damit unsichtbar. Weiss ist auf allen fuenf dunklen
   Toast-Flaechen gleichermassen kontrastreich — bewusste Abweichung vom
   sonst einheitlichen Fokus-Ring, nur fuer diesen Kontext. */
.toast .btn-close:focus-visible {
  outline: 2px solid white;
  outline-offset: 2px;
  box-shadow: none;
}

/* Der Container waechst sonst auf Toast-Breite + Padding und ragt auf
   schmalen Viewports (< 382px) ueber den Rand hinaus. */
#toast-container {
  max-width: 100vw;
}
