/* ═══ tokens.css ═══ */
/* ════════════════════════════════════════════════════════════════════════════
   tokens.css — Shared Design Tokens (Brand + Semantik + Typo + Spacing)
   ────────────────────────────────────────────────────────────────────────────
   Eine Datei, von ALLEN vier Surfaces geladen (Admin, Mieter-Portal,
   Eigentuemer-Portal, oeffentliche Homepage). Aenderungen hier propagieren
   ueberall.

   Layering:
     tokens.css           ← Foundation (DIESE Datei). Brand + Semantik + Typo.
     app.css              ← Bootstrap-Erweiterungen (Admin-Forms etc.)
     app.industrial.css   ← Admin-Theme-Override (Dark/Light, Neon-Akzent)
     portal.css           ← Portale: gemeinsame Komponenten ueber tokens
     (inline-Style)       ← Pro-Portal-Akzent (Mieter blau / Eigentuemer gruen)

   Brand-Entscheidung (Adrian):
     Aktuell sind --brand-* Platzhalter, die zu den bisher genutzten Werten
     passen. Sobald Adrian ein finales Logo + Hausfarbe hat, hier die fuenf
     ROOT-Variablen umstellen — alle vier Surfaces folgen automatisch.
   ════════════════════════════════════════════════════════════════════════════ */

:root {

  /* ── Brand ─────────────────────────────────────────────────────────────────
     Markenname entschieden 2026-05-08: "Rottensteiner Hausverwaltung"
     2026-05-16: Brand-Palette auf "Bodensee" geupdated (Audit-Befund: drei
     parallele Token-Namensraeume — siehe /docs/design-system/README.md).
     Neue Werte synchron mit public.css. Alle vier Surfaces sollen perspekti-
     visch auf --color-* migrieren. */
  --brand-name:                'Rottensteiner Hausverwaltung';
  --brand-primary:             #2D6B8E;     /* Bodensee-Mittelblau */
  --brand-primary-hover:       #1A4D6B;
  --brand-primary-on:          #FFFFFF;     /* Text auf Brand-Primary */

  /* ── Bodensee-Surface-Palette (NEUE Single-Source-of-Truth) ───────────────
     Semantische Namen statt Farbnamen ("ink" statt "dark" — bleibt stabil
     auch wenn die konkrete Farbe in Zukunft wechselt). */
  --color-ink:                 #15243C;     /* Haupttext + dunkle Surfaces */
  --color-ink-soft:            #6B5E4E;     /* Sekundaertext (warmer Erd-Ton) */
  --color-ink-faint:           #ACA193;     /* Captions, sehr leise */
  --color-brand:               #2D6B8E;     /* See-Blau, Haupt-Akzent */
  --color-brand-deep:          #1A4D6B;     /* See-Blau dunkel (Hover) */
  --color-brand-mist:          #B8D4E3;     /* Morgennebel-Hell, Highlight */
  --color-brand-haze:          #E5EFF5;     /* Sehr heller Brand-Hintergrund */
  --color-paper:               #F7F2EA;     /* Warmes Bodenseepapier */
  --color-paper-deep:          #EDE5D4;     /* Schilf-Beige */
  --color-line:                #DDD4C2;     /* Sanfter Trenner (warm) */
  --color-line-soft:           #ECE5D8;     /* Subtiler Trenner */
  --color-accent:              #C8553D;     /* Apfelblueten-Akzent (sparsam!) */
  --color-admin-accent:        #5BB0D9;     /* Helles See-Blau — Admin-Industrial Akzent (Dark) */
  --color-admin-accent-light:  #2D6B8E;     /* Bodensee-Blau — Admin-Industrial Akzent (Light) */

  --brand-accent-mieter:       #1E3A5F;     /* Akzent fuer Mieter-Portal */
  --brand-accent-eigentuemer:  #2D4A3E;     /* Akzent fuer Eigentuemer-Portal (gruen) */
  --brand-accent-industrial:   #5BB0D9;     /* Akzent fuer Admin-Industrial (helles See-Blau, Dark) */

  /* ── Semantische Statusfarben ──────────────────────────────────────────────
     Identisch ueber alle Surfaces. Werden ggf. pro Theme noch ge-tweaked. */
  --color-success:             #15803D;
  --color-success-bg:          #DCFCE7;
  --color-success-on:          #FFFFFF;
  --color-success-dark:        #00E08F;     /* Dark-Theme/Begehung-Erfolg (hoher Kontrast auf dunklem BG) */
  --color-warning:             #B45309;
  --color-warning-bg:          #FEF3C7;
  --color-warning-on:          #1A1A1A;
  --color-danger:              #B91C1C;
  --color-danger-bg:           #FEE2E2;
  --color-danger-on:           #FFFFFF;
  --color-info:                #1D4ED8;
  --color-info-bg:             #DBEAFE;
  --color-info-on:             #FFFFFF;
  --color-muted:               #525252;
  --color-muted-bg:            #E5E5E5;
  --color-muted-on:            #FFFFFF;
  --color-accent-gold:         #FFD166;     /* Portal-Gold-Akzent (Nav-aktiv, Schnellzugriff) */

  /* ── HITL-Ampel (Autonomie-Stufe) ──────────────────────────────────────────
     Bewusst nicht success/warning/danger nachgemalt — semantisch anders:
     gruen = autonom, gelb = HITL-Pflicht, rot = blockiert. Eine HITL-Pille
     "rot" ist KEIN Fehler, sondern eine bewusste Autonomie-Entscheidung. */
  --color-traffic-rot:         #7F1D1D;
  --color-traffic-rot-bg:      #FECACA;
  --color-traffic-rot-on:      #FFFFFF;
  --color-traffic-gelb:        #92400E;
  --color-traffic-gelb-bg:     #FDE68A;
  --color-traffic-gelb-on:     #1A1A1A;
  --color-traffic-gruen:       #14532D;
  --color-traffic-gruen-bg:    #BBF7D0;
  --color-traffic-gruen-on:    #FFFFFF;

  /* ── Typografie ────────────────────────────────────────────────────────────
     Sans-Stack: Geist (lokal) → System-UI. Mono-Stack: JetBrains Mono → ui-mono.
     Konvention (siehe app/CLAUDE.md): keine fonts.googleapis.com — privacy + offline. */
  --font-sans:                 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono:                 'JetBrains Mono', 'Geist Mono', ui-monospace, 'SF Mono', Consolas, monospace;
  --font-display:              var(--font-sans);

  --fs-xs:     0.75rem;
  --fs-sm:     0.85rem;
  --fs-base:   0.95rem;
  --fs-lg:     1.15rem;
  --fs-xl:     1.4rem;
  --fs-2xl:    1.85rem;

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-bold:    600;

  /* ── Spacing-Skala (4px-Raster) ─────────────────────────────────────────── */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;

  /* ── Border-Radien ─────────────────────────────────────────────────────── */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-pill: 9999px;

  /* ── Schatten (sehr dezent, Industrial-tauglich) ──────────────────────── */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.08);

  /* ── Fokus-Ring (gilt fuer alle Surfaces) ───────────────────────────────── */
  --focus-ring-width: 3px;
  --focus-ring-offset: 2px;
  --focus-ring-color: var(--brand-accent-industrial);   /* Hoher Kontrast auch auf dunklen Themes */

  /* ════════════════════════════════════════════════════════════════════════
     Public-Surface-Tokens (Bodensee-Homepage)
     ────────────────────────────────────────────────────────────────────────
     Status 2026-05-28 nach UI-Audit: das Repo hat **zwei stabile**
     Token-Familien, KEINE laufende Migration mehr:

       --color-*       Foundation/Bodensee-Surface (semantisch, theme-stabil)
       --hv-*          Admin-Industrial (theme-variant: Light/Dark)

     Beide sind Single-Source-of-Truth fuer ihre Surface. Die Aliases unten
     (--dark/--blue/--cream/--surface/--border/--text/--text-muted/--accent-spark)
     werden von public.css + ~25 Homepage-Views aktiv genutzt — keine
     "Backward-Compat", sondern produktive API. Tot war nur --dark-soft (raus).

     Wenn du neuen Public-Homepage-Code schreibst: --color-*-Tokens nutzen
     (semantisch klarer). Bestehende --dark/--blue/--cream-Stellen muessen
     NICHT migriert werden — sind via Aliases korrekt resolved.
     ════════════════════════════════════════════════════════════════════════ */

  /* Public-Homepage-Surface-Tokens (Bodensee-Palette) */
  --dark:                      var(--color-ink);
  --blue:                      var(--color-brand);
  --blue-dark:                 var(--color-brand-deep);
  --blue-light:                var(--color-brand-haze);
  --blue-mid:                  var(--color-brand-mist);
  --cream:                     var(--color-paper);
  --cream-dark:                var(--color-paper-deep);
  --surface:                   #FFFFFF;
  --border:                    var(--color-line);
  --text:                      var(--color-ink);
  --text-muted:                var(--color-ink-soft);
  --accent-spark:              var(--color-accent);

  /* Typografie-Aliases (Public benutzt eigene Display-Font Fraunces) */
  --font-display-public:       'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans-public:          'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
}

/* ════════════════════════════════════════════════════════════════════════════
   Globaler Fokus-Ring
   ────────────────────────────────────────────────────────────────────────────
   Konsistent ueber Admin und beide Portale. Nutzt :focus-visible (nur Tastatur),
   sodass Maus-Klicks keinen sichtbaren Ring triggern.
   ════════════════════════════════════════════════════════════════════════════ */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

/* ════════════════════════════════════════════════════════════════════════════
   .hv-skip-link — Skip-to-content-Link (BFSG / WCAG 2.4.1)
   ────────────────────────────────────────────────────────────────────────────
   Unsichtbar bis Tab-Fokus, dann oben links. Konsistent ueber alle Surfaces.
   Public-Layout hat seine eigene .skip-link mit Bodensee-Farben, die hier
   ist die universelle Variante fuer Admin + beide Portale + Auth.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-skip-link {
  position: absolute;
  top: -100px;
  left: 0;
  z-index: 10000;
  background: var(--color-ink, #15243C);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 var(--radius-md, 8px) 0;
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  transition: top 0.2s ease;
}
.hv-skip-link:focus,
.hv-skip-link:focus-visible {
  top: 0;
  outline: 3px solid var(--color-brand, #2D6B8E);
  outline-offset: 2px;
  color: #fff;
}

/* ════════════════════════════════════════════════════════════════════════════
   .hv-pill — Status-Pille (semantik + HITL-Ampel)
   ────────────────────────────────────────────────────────────────────────────
   Ersetzt Bootstrap-`badge bg-*` an allen Stellen, an denen ein Status oder
   eine Autonomie-Ampel angezeigt wird. Die Klasse setzt nur Layout (Padding,
   Radius, Schrift); die Variante (success / warning / danger / info / muted /
   traffic-*) bringt Hintergrund + Vordergrund.

   Nutzung:
     <span class="hv-pill hv-pill--success">Bezahlt</span>
     <span class="hv-pill hv-pill--traffic-gelb">HITL: gelb</span>

   Helper (Handlebars): {{statusPill domain wert}} — siehe server.js.
   Mapping siehe app/src/utils/statusPills.js.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.15rem 0.6rem;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  font-family: var(--font-sans);
  line-height: 1.4;
  white-space: nowrap;
  vertical-align: baseline;
  letter-spacing: 0.01em;
}
.hv-pill--success      { background: var(--color-success-bg); color: var(--color-success); }
.hv-pill--warning      { background: var(--color-warning-bg); color: var(--color-warning); }
.hv-pill--danger       { background: var(--color-danger-bg);  color: var(--color-danger);  }
.hv-pill--info         { background: var(--color-info-bg);    color: var(--color-info);    }
.hv-pill--muted        { background: var(--color-muted-bg);   color: var(--color-muted);   }
.hv-pill--traffic-rot   { background: var(--color-traffic-rot-bg);   color: var(--color-traffic-rot);   }
.hv-pill--traffic-gelb  { background: var(--color-traffic-gelb-bg);  color: var(--color-traffic-gelb);  }
.hv-pill--traffic-gruen { background: var(--color-traffic-gruen-bg); color: var(--color-traffic-gruen); }

/* Dark-Theme-Override (Industrial Admin): Hintergruende sind im Dark-Mode
   sehr hell → Pille wird zu grell. Auf gedaempfte Versionen mit Alpha. */
[data-theme="dark"] .hv-pill--success      { background: rgba(34, 197, 94, 0.18); color: #6EE7A7; }
[data-theme="dark"] .hv-pill--warning      { background: rgba(245, 158, 11, 0.18); color: #FCD34D; }
[data-theme="dark"] .hv-pill--danger       { background: rgba(239, 68, 68, 0.18);  color: #FCA5A5; }
[data-theme="dark"] .hv-pill--info         { background: rgba(59, 130, 246, 0.18); color: #93C5FD; }
[data-theme="dark"] .hv-pill--muted        { background: rgba(160, 160, 160, 0.18); color: #D4D4D4; }
[data-theme="dark"] .hv-pill--traffic-rot   { background: rgba(220, 38, 38, 0.22);  color: #FCA5A5; }
[data-theme="dark"] .hv-pill--traffic-gelb  { background: rgba(234, 179, 8, 0.22);  color: #FDE047; }
[data-theme="dark"] .hv-pill--traffic-gruen { background: rgba(34, 197, 94, 0.22);  color: #86EFAC; }

@media print {
  .hv-pill {
    background: transparent !important;
    color: #000 !important;
    border: 1px solid #000;
    padding: 0.05rem 0.4rem;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   Field-Level-Validation (CSS-only, kein JS)
   ────────────────────────────────────────────────────────────────────────────
   Pattern: <input required pattern="..." />
            <small class="hv-field-error">Bitte E-Mail im Format ... eingeben</small>

   Sichtbarkeitslogik nutzt :user-invalid (Browser-native, greift erst nach
   Blur oder Submit-Versuch — kein roter Initial-Hint bei leeren Feldern).
   Fallback fuer Browser ohne :user-invalid: :invalid:not(:placeholder-shown)
   :not(:focus). Damit der Fallback greift, sollte das Eingabefeld einen
   placeholder haben (z.B. " " als Spacer fuer Floating-Labels).

   Die Klasse .hv-form-error markiert serverseitige Validation-Fehler — die
   bleibt unabhaengig vom user-invalid-Zustand sichtbar.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-field-error {
  display: none;
  font-size: var(--fs-xs);
  color: var(--color-danger);
  margin-top: 0.25rem;
  line-height: 1.35;
}

/* :user-invalid (modern) — greift nach User-Interaktion */
.form-control:user-invalid + .hv-field-error,
.form-select:user-invalid + .hv-field-error,
textarea:user-invalid + .hv-field-error {
  display: block;
}

/* Fallback :invalid + :not(:placeholder-shown) :not(:focus) */
.form-control:invalid:not(:placeholder-shown):not(:focus) + .hv-field-error,
.form-select:invalid:not(:focus) + .hv-field-error,
textarea:invalid:not(:placeholder-shown):not(:focus) + .hv-field-error {
  display: block;
}

/* Border-Akzent fuer invalid Eingaben (gleiche Sichtbarkeitslogik) */
.form-control:user-invalid,
.form-select:user-invalid,
textarea:user-invalid {
  border-color: var(--color-danger);
}
.form-control:invalid:not(:placeholder-shown):not(:focus),
textarea:invalid:not(:placeholder-shown):not(:focus) {
  border-color: var(--color-danger);
}

/* Server-seitige Inline-Fehler (immer sichtbar wenn die Klasse gesetzt ist) */
.hv-form-error {
  display: block;
  font-size: var(--fs-xs);
  color: var(--color-danger);
  margin-top: 0.25rem;
  line-height: 1.35;
}
.hv-form-error::before {
  content: '⚠ ';
  font-weight: var(--fw-bold);
}

/* Form-Field mit Server-Fehler: Container bekommt eine ID, die im
   form-errors-Partial als Anchor-Link verlinkt ist. Scroll-Margin-Top
   sorgt dafuer, dass der Anchor nicht hinter der Sidebar-Header verschwindet. */
.hv-field--error {
  scroll-margin-top: 80px;
}
.hv-field--error .form-control,
.hv-field--error .form-select,
.hv-field--error textarea {
  border-color: var(--color-danger);
}

/* ════════════════════════════════════════════════════════════════════════════
   Tabellen-Pattern (Phase 2.2)
   ────────────────────────────────────────────────────────────────────────────
   .hv-num         numerische Zelle (rechtsbuendig + Mono + tabular-nums)
   .hv-table-clickable  ganze Zeile als Click-Target (data-href)
   [data-density]  Density-Toggle (compact | cozy | comfy)
   ════════════════════════════════════════════════════════════════════════════ */
.hv-num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.hv-table-clickable tbody tr[data-href] {
  cursor: pointer;
  transition: background-color 120ms ease;
}
.hv-table-clickable tbody tr[data-href]:hover {
  background-color: rgba(0, 0, 0, 0.025);
}
[data-theme="dark"] .hv-table-clickable tbody tr[data-href]:hover {
  background-color: rgba(255, 255, 255, 0.04);
}

/* Density-Toggle: globale Einstellung in localStorage 'hv-density'.
   Default = cozy (Bootstrap-Default). Compact spart 30 % Vertikal-Raum,
   Comfy ist fuer Lese-Modus. */
[data-density="compact"] .table > :not(caption) > * > *,
[data-density="compact"] table > :not(caption) > * > * {
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
[data-density="compact"] .table,
[data-density="compact"] table.table-sm {
  font-size: var(--fs-xs);
}
[data-density="comfy"] .table > :not(caption) > * > *,
[data-density="comfy"] table > :not(caption) > * > * {
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
}

/* Density-Toggle-Button selbst (in Sidebar-Footer einsetzbar) */
.hv-density-toggle {
  display: inline-flex;
  gap: 1px;
  background: var(--color-muted-bg, #E5E5E5);
  border-radius: var(--radius-pill);
  padding: 2px;
}
.hv-density-toggle button {
  background: transparent;
  border: 0;
  padding: 0.15rem 0.55rem;
  font-size: var(--fs-xs);
  color: var(--color-muted);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.hv-density-toggle button[aria-pressed="true"] {
  background: var(--brand-primary, #1E3A5F);
  color: var(--brand-primary-on, #fff);
}
[data-theme="dark"] .hv-density-toggle {
  background: rgba(255, 255, 255, 0.06);
}
[data-theme="dark"] .hv-density-toggle button[aria-pressed="true"] {
  background: var(--brand-accent-industrial);
  color: #0A0A0B;
}

/* ════════════════════════════════════════════════════════════════════════════
   Mobile-Bottom-Nav (Phase 2.3)
   ────────────────────────────────────────────────────────────────────────────
   Fixe Navigation am unteren Bildschirmrand auf Mobile (<768px). Verdeckt
   die Sidebar nicht — Sidebar bleibt als Hamburger/Offcanvas verfuegbar.
   Touch-Targets mindestens 44x44 px (Apple/Google-Guideline).
   ════════════════════════════════════════════════════════════════════════════ */
.hv-bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1030;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  background: var(--brand-primary, #1E3A5F);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding: 0.25rem 0 max(0.25rem, env(safe-area-inset-bottom));
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
}
[data-theme="dark"] .hv-bottom-nav {
  background: #0F1418;
  border-top-color: rgba(255, 255, 255, 0.08);
}
.hv-bottom-nav-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.35rem 0.5rem;
  background: transparent;
  border: 0;
  text-decoration: none;
  color: rgba(255, 255, 255, 0.65);
  font-size: var(--fs-xs);
  line-height: 1.1;
  transition: color 100ms ease;
  cursor: pointer;
}
.hv-bottom-nav-item:hover,
.hv-bottom-nav-item:focus-visible {
  color: rgba(255, 255, 255, 0.92);
}
.hv-bottom-nav-item.active {
  color: var(--brand-accent-industrial, #5BB0D9);
}
.hv-bottom-nav-item i {
  font-size: 1.15rem;
  margin-bottom: 2px;
}
.hv-bottom-nav-item span {
  font-size: 0.65rem;
  letter-spacing: 0.02em;
}
/* Ungelesene-Mails-Badge: roter Kreis oben rechts am Icon */
.hv-bottom-nav-badge {
  position: absolute;
  top: 2px;
  left: 50%;
  margin-left: 0.4rem;
  min-width: 1.05rem;
  padding: 0.05rem 0.3rem;
  background: var(--hv-danger, #d92d20);
  color: #fff;
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  border-radius: 10px;
  pointer-events: none;
}

/* Bottom-Nav verdeckt unteren Content — Padding fuer den Content auf Mobile */
@media (max-width: 767.98px) {
  body:has(.hv-bottom-nav) .hv-content,
  body:has(.hv-bottom-nav) main {
    padding-bottom: 4.5rem;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   Inline-Hilfe — Tooltip-Popover (Phase 2.5)
   ────────────────────────────────────────────────────────────────────────────
   Klick-getriggertes Popover fuer komplexe Felder (Kappungsgrenze,
   Verteilerschluessel, AfA-Restwert, Mietspiegel). Kein Hover, weil Mobile
   das nicht hat. Keine Wall-of-Text — max. 2-3 Saetze pro Tip.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-tip {
  cursor: pointer;
  color: var(--color-muted, #525252);
  margin-left: 0.25rem;
  font-size: 0.95em;
  vertical-align: middle;
  transition: color 100ms ease;
}
.hv-tip:hover,
.hv-tip:focus-visible {
  color: var(--brand-primary, #1E3A5F);
}
[data-theme="dark"] .hv-tip:hover,
[data-theme="dark"] .hv-tip:focus-visible {
  color: var(--brand-accent-industrial, #5BB0D9);
}

/* Popover-Variante: schmaler + im Industrial-Look */
.popover.hv-tip-popover {
  max-width: 300px;
  font-size: var(--fs-sm);
  border: 1px solid var(--hv-border, #e5e7eb);
  box-shadow: var(--shadow-lg);
}
.popover.hv-tip-popover .popover-header {
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  background: var(--color-muted-bg, #f1f5f9);
  border-bottom: 0;
}
.popover.hv-tip-popover .popover-body {
  font-size: var(--fs-sm);
  line-height: 1.5;
}
[data-theme="dark"] .popover.hv-tip-popover {
  background: #1A1A1B;
  border-color: rgba(255, 255, 255, 0.12);
  color: #E5E5E5;
}
[data-theme="dark"] .popover.hv-tip-popover .popover-header {
  background: #0F1418;
  color: #fff;
}
[data-theme="dark"] .popover.hv-tip-popover .popover-arrow::after {
  border-top-color: #1A1A1B;
  border-bottom-color: #1A1A1B;
}

/* ════════════════════════════════════════════════════════════════════════════
   Auto-Save-Indikator (Phase 2.1)
   ────────────────────────────────────────────────────────────────────────────
   Wird in Wizard-Steps (Mieterhoehung, NK, Onboarding) eingesetzt.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-autosave {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--fs-xs);
  color: var(--color-success);
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}
.hv-autosave.hv-autosave-visible {
  opacity: 1;
}
.hv-autosave::before {
  content: '✓';
  font-weight: var(--fw-bold);
}
[data-theme="dark"] .hv-autosave {
  color: #6EE7A7;
}

/* ════════════════════════════════════════════════════════════════════════════
   Step-Wizard (Phase 3.1)
   ────────────────────────────────────────────────────────────────────────────
   Fortschrittsanzeige fuer Multi-Step-Forms. Status:
   done = grün + Haken + klickbar; active = Brand + fett; todo = muted.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-step-wizard-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-size: var(--fs-sm);
}
.hv-step-wizard-item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-pill);
  background: transparent;
}
.hv-step-wizard-item + .hv-step-wizard-item::before {
  content: '›';
  color: var(--color-muted);
  margin-right: 0.25rem;
  font-size: 1.1em;
}
.hv-step-wizard-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  background: var(--color-muted-bg);
  color: var(--color-muted);
}
.hv-step-wizard-item.done .hv-step-wizard-num {
  background: var(--color-success);
  color: var(--color-success-on);
}
.hv-step-wizard-item.active .hv-step-wizard-num {
  background: var(--brand-primary);
  color: var(--brand-primary-on);
}
.hv-step-wizard-titel {
  color: var(--color-muted);
  text-decoration: none;
}
.hv-step-wizard-item.done .hv-step-wizard-titel { color: var(--color-success); }
.hv-step-wizard-item.done a.hv-step-wizard-titel:hover { text-decoration: underline; }
.hv-step-wizard-item.active .hv-step-wizard-titel {
  color: var(--brand-primary);
  font-weight: var(--fw-bold);
}
[data-theme="dark"] .hv-step-wizard-num {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.7);
}
[data-theme="dark"] .hv-step-wizard-item.done .hv-step-wizard-num {
  background: rgba(34, 197, 94, 0.3);
  color: #6EE7A7;
}
[data-theme="dark"] .hv-step-wizard-item.done .hv-step-wizard-titel { color: #6EE7A7; }
[data-theme="dark"] .hv-step-wizard-item.active .hv-step-wizard-num {
  background: var(--brand-accent-industrial);
  color: #0A0A0B;
}
[data-theme="dark"] .hv-step-wizard-item.active .hv-step-wizard-titel {
  color: var(--brand-accent-industrial);
}

/* ════════════════════════════════════════════════════════════════════════════
   Onboarding-Tour-Spotlight (Phase 3.6)
   ────────────────────────────────────────────────────────────────────────────
   Dunkler Backdrop mit "ausgeschnittenem" Spotlight um das Tour-Ziel-Element.
   Bubble (.hv-tour-bubble) zeigt Titel + Markdown-Body + Skip/Weiter.
   ════════════════════════════════════════════════════════════════════════════ */
.hv-tour-overlay {
  position: fixed;
  inset: 0;
  z-index: 1090;
  pointer-events: none;
}
.hv-tour-overlay::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 11, 0.55);
  backdrop-filter: blur(2px);
  pointer-events: auto;
}
.hv-tour-spotlight {
  position: absolute;
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 9999px rgba(10, 10, 11, 0.55), 0 0 0 3px var(--brand-accent-industrial);
  pointer-events: none;
  transition: all 200ms ease;
}
.hv-tour-bubble {
  position: absolute;
  max-width: 360px;
  background: #fff;
  color: #1A1A1A;
  border-radius: var(--radius-md);
  padding: 1rem 1.15rem;
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  font-size: var(--fs-sm);
  line-height: 1.5;
}
.hv-tour-bubble h3 {
  margin: 0 0 0.5rem 0;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
}
.hv-tour-bubble p { margin: 0 0 0.5rem 0; }
.hv-tour-bubble p:last-child { margin-bottom: 0; }
.hv-tour-bubble ul { margin: 0 0 0.75rem 0; padding-left: 1.25rem; }
.hv-tour-bubble strong { color: var(--brand-primary); }
.hv-tour-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.85rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hv-border, #e5e7eb);
}
.hv-tour-progress {
  font-size: var(--fs-xs);
  color: var(--color-muted);
  margin-right: auto;
}
[data-theme="dark"] .hv-tour-bubble {
  background: #1A1A1B;
  color: #E5E5E5;
}
[data-theme="dark"] .hv-tour-bubble strong { color: var(--brand-accent-industrial); }
[data-theme="dark"] .hv-tour-actions { border-top-color: rgba(255, 255, 255, 0.1); }

/* ════════════════════════════════════════════════════════════════════════════
   A11y: prefers-reduced-motion (Phase 3.5)
   ────────────────────────────────────────────────────────────────────────────
   Wenn der User reduced-motion eingestellt hat, schalten wir Animationen
   + Transitions global ab. Greift auf alle hv-* Komponenten, Bootstrap
   (.fade, .collapse) UND inline transition-Werte.
   ════════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   S-NAV — Klick-Feedback bei klassischer Navigation (alle 4 Surfaces)
   ──────────────────────────────────────────────────────────────────────────── */

/* Top-Progress-Bar (gesteuert von public/js/nav-progress.js). */
.hv-nav-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  background: var(--brand-primary, #2D6B8E);
  box-shadow: 0 0 8px rgba(45, 107, 142, 0.55);
  opacity: 0;
  z-index: 2000;
  pointer-events: none;
  transition: width 0.2s ease, opacity 0.2s ease;
}
@media (prefers-reduced-motion: reduce) {
  /* Balken bleibt als reines „läuft"-Signal, aber ohne laufende Animation. */
  .hv-nav-progress { transition: none; }
}

/* View-Transitions: BEWUSST DEAKTIVIERT (Entscheidung 2026-06-10 nach 3
   Guard-Iterationen). @view-transition { navigation: auto } erzeugt in Chromium
   beim Browser-Teardown/Viewport-Resize einen in-page NICHT abfangbaren
   "Transition was aborted"-pageerror (weder pagereveal/pageswap-Catch noch
   früher unhandledrejection-Filter noch skipTransition halfen — die Seite ist
   beim Abort bereits in Zerstörung). Das verschmutzt jeden automatisierten
   Browser-Lauf und maskiert echte Fehler. Der Weiß-Blitz ist stattdessen über
   den dunklen Erst-Paint (Inline-Style in main.handlebars) gelöst, das
   Klick-Feedback über die Top-Progress-Bar (nav-progress.js). Die vt-guard-/
   skipTransition-Mechanik bleibt harmlos bestehen, falls VT später (besserer
   Browser-Support) reaktiviert wird. */

/* ════════════════════════════════════════════════════════════════════════════
   S-CHART/S-LOAD — Skeleton-Platzhalter (alle Surfaces; .hv-skeleton liegt sonst
   nur in app.css = Admin, fehlt aber im Portal/Public). Theme-neutral.
   ──────────────────────────────────────────────────────────────────────────── */
.hv-skeleton {
  position: relative;
  width: 100%;
  border-radius: 6px;
  background: linear-gradient(90deg,
    rgba(128, 128, 128, 0.06) 0%,
    rgba(128, 128, 128, 0.12) 50%,
    rgba(128, 128, 128, 0.06) 100%);
  background-size: 200% 100%;
  animation: hv-skeleton-pulse 1.5s ease-in-out infinite;
}
.hv-skeleton-msg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 0.85rem;
  color: var(--color-ink-soft, #6c757d);
  white-space: nowrap;
}
@keyframes hv-skeleton-pulse {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hv-skeleton { animation: none; }
}

/* Chart-Container: reserviert Platz (kein CLS/Leerblitz) + Skeleton liegt als
   Overlay über dem Canvas, bis nav die [data-chart-skeleton]-Elemente entfernt. */
.hv-chart-wrap { position: relative; }
.hv-chart-skeleton {
  position: absolute;
  inset: 0;
  height: auto !important;
  border-radius: 8px;
}

/* ════════════════════════════════════════════════════════════════════════════
   S-FILE — gestylter Datei-Upload (deutsch + Dateiname). Ersetzt das native,
   teils englische <input type=file>. Label umschließt das visuell versteckte
   Input; JS (app.js / portal-init.js) füllt [data-upload-name].
   ──────────────────────────────────────────────────────────────────────────── */
.hv-upload { position: relative; display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; cursor: pointer; max-width: 100%; }
.hv-upload__input {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); border: 0;
}
.hv-upload__btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0.45rem 0.9rem; border-radius: 8px;
  border: 1px solid var(--color-line, #ced4da);
  background: var(--color-paper-deep, #f1f3f5);
  color: var(--color-ink, #15243C);
  font-size: 0.9rem; font-weight: 500; white-space: nowrap;
}
.hv-upload:hover .hv-upload__btn,
.hv-upload:focus-within .hv-upload__btn {
  border-color: var(--brand-primary, #2D6B8E);
  background: var(--color-brand-haze, #E5EFF5);
}
.hv-upload__name { font-size: 0.85rem; color: var(--color-ink-soft, #6c757d); word-break: break-word; }


/* ═══ buttons.css ═══ */
/* ════════════════════════════════════════════════════════════════════════════
   buttons.css — Konsolidierte Button-Hierarchie (Design-System-Audit 2026-05-16)
   ────────────────────────────────────────────────────────────────────────────
   Vor diesem Refactor: 17 verschiedene Button-Varianten ueber 4 Surfaces
   (btn-blue / btn-cta-primary / btn-hero / btn-nav / btn-outline-dark /
    btn-cta-secondary / btn-hero-ghost / btn-cookie-* / btn-wohnung / …)

   Nachher: Drei semantische Varianten × drei Groessen, plus Bootstrap-
   Kompatibilitaet. Legacy-Namen sind als Aliases (Multi-Selektor) erhalten,
   sodass kein View geaendert werden muss.

   Verwendung (neu):
     <button class="ds-btn ds-btn--primary">Hauptaktion</button>
     <button class="ds-btn ds-btn--secondary">Sekundaer</button>
     <button class="ds-btn ds-btn--ghost">Tertiaer</button>
     <button class="ds-btn ds-btn--primary ds-btn--sm">Klein</button>
     <button class="ds-btn ds-btn--primary ds-btn--lg">Gross</button>

   "ds-" als Prefix = "design-system". Vermeidet Kollision mit Bootstrap
   (.btn) und alten Custom-Klassen.

   Migration: Sub-Agent kann in einem zweiten Schritt iterativ Views auf die
   neuen .ds-btn-Klassen umstellen. Aliases unten loeschen wenn 100% migriert.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Basis ──────────────────────────────────────────────────────────────── */
.ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md, 10px);
  font-family: var(--font-sans, system-ui, sans-serif);
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.2s;
  -webkit-appearance: none;
  appearance: none;
}

.ds-btn:disabled,
.ds-btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

.ds-btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-brand, #2D6B8E);
  outline-offset: 2px;
}

/* Loading-State: Pseudo-Element-Spinner, ersetzt Button-Text-Position */
.ds-btn[data-loading="true"] {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.ds-btn[data-loading="true"]::after {
  content: '';
  position: absolute;
  inset: auto;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  color: var(--color-paper, #fff);
  animation: ds-btn-spin 0.7s linear infinite;
}
@keyframes ds-btn-spin {
  to { transform: rotate(360deg); }
}

/* ── Variante: Primary (Hauptaktion, max 1 pro Screen) ─────────────────── */
.ds-btn--primary {
  background: var(--color-brand, #2D6B8E);
  color: #fff;
  border-color: var(--color-brand, #2D6B8E);
}
.ds-btn--primary:hover {
  background: var(--color-brand-deep, #1A4D6B);
  border-color: var(--color-brand-deep, #1A4D6B);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(45, 107, 142, 0.35);
}
.ds-btn--primary:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(45, 107, 142, 0.25);
}

/* ── Variante: Secondary (Outline-Stil, fuer Sekundaer-Aktionen) ───────── */
.ds-btn--secondary {
  background: transparent;
  color: var(--color-ink, #15243C);
  border-color: var(--color-line, #DDD4C2);
  border-width: 1.5px;
}
.ds-btn--secondary:hover {
  background: var(--color-paper-deep, #EDE5D4);
  border-color: var(--color-ink, #15243C);
  color: var(--color-ink, #15243C);
}

/* Secondary auf dunklem Hintergrund (Hero, CTA-Strip, Footer) */
.ds-btn--secondary.ds-btn--on-dark {
  color: rgba(255,255,255,0.78);
  border-color: rgba(255,255,255,0.2);
}
.ds-btn--secondary.ds-btn--on-dark:hover {
  color: #fff;
  background: rgba(255,255,255,0.07);
  border-color: rgba(255,255,255,0.45);
}

/* ── Variante: Ghost (Text-only, leichte Aktion) ───────────────────────── */
.ds-btn--ghost {
  background: transparent;
  color: var(--color-brand, #2D6B8E);
  border-color: transparent;
  padding: 0.55rem 0.85rem;
}
.ds-btn--ghost:hover {
  background: var(--color-brand-haze, #E5EFF5);
  color: var(--color-brand-deep, #1A4D6B);
}

/* ── Variante: Danger (Loeschen, kritische Aktion) ─────────────────────── */
.ds-btn--danger {
  background: var(--color-danger, #B91C1C);
  color: #fff;
  border-color: var(--color-danger, #B91C1C);
}
.ds-btn--danger:hover {
  background: #8B0F0F;
  border-color: #8B0F0F;
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(185, 28, 28, 0.35);
}

/* ── Groessen ──────────────────────────────────────────────────────────── */
.ds-btn--sm {
  padding: 0.45rem 1rem;
  font-size: 0.82rem;
  border-radius: var(--radius-sm, 6px);
}
.ds-btn--lg {
  padding: 0.9rem 1.85rem;
  font-size: 1rem;
  border-radius: 10px;
}

/* Full-Width-Variante (vor allem fuer Mobile-CTAs) */
.ds-btn--block {
  display: flex;
  width: 100%;
}

/* ════════════════════════════════════════════════════════════════════════
   LEGACY-ALIASES (2026-05-16)
   ────────────────────────────────────────────────────────────────────────
   Existierende Klassen werden auf die neuen Tokens gemappt, sodass kein
   View-Refactor noetig ist. Bei Aenderungen am Look-and-Feel:
   AUSSCHLIESSLICH die .ds-btn--*-Klassen oben aendern — die Aliases
   erben automatisch.
   ════════════════════════════════════════════════════════════════════════ */

/* Primary-Variante: btn-blue, btn-cta-primary, btn-hero, btn-nav */
.btn-blue,
.btn-cta-primary,
.btn-hero,
.btn-nav {
  background: var(--color-brand);
  color: #fff !important;
  border: 1px solid var(--color-brand);
  padding: 0.75rem 1.6rem;
  border-radius: var(--radius-md, 10px);
  font-weight: 600;
  font-size: 0.92rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  white-space: nowrap;
  transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
}
.btn-blue:hover,
.btn-cta-primary:hover,
.btn-hero:hover,
.btn-nav:hover {
  background: var(--color-brand-deep) !important;
  color: #fff !important;
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(45, 107, 142, 0.35);
}
/* Hero-spezifisch: groesseres Padding */
.btn-hero { padding: 0.9rem 1.85rem; font-size: 0.95rem; font-weight: 700; }
/* Nav-spezifisch: kleineres Padding (passt in Navbar-Hoehe) */
.btn-nav  { padding: 0.45rem 1.1rem !important; font-size: 0.875rem; }

/* Secondary-Variante: btn-outline-dark, btn-cta-secondary, btn-hero-ghost */
.btn-outline-dark {
  background: transparent;
  color: var(--color-ink);
  border: 1.5px solid var(--color-line);
  padding: 0.7rem 1.6rem;
  border-radius: var(--radius-md, 10px);
  font-weight: 600;
  font-size: 0.92rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: all 0.2s;
}
.btn-outline-dark:hover {
  border-color: var(--color-ink);
  color: var(--color-ink);
  background: var(--color-paper-deep);
}

/* Secondary-Variante "on-dark": CTA-Strip, Hero-Ghost */
.btn-cta-secondary,
.btn-hero-ghost {
  background: transparent;
  color: rgba(255,255,255,0.78);
  border: 1px solid rgba(255,255,255,0.2);
  padding: 0.85rem 1.75rem;
  border-radius: var(--radius-md, 10px);
  font-weight: 600;
  font-size: 0.92rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  transition: all 0.22s;
}
.btn-cta-secondary:hover,
.btn-hero-ghost:hover {
  color: #fff;
  background: rgba(255,255,255,0.07);
  border-color: rgba(255,255,255,0.45);
}

/* Cookie-Banner-Buttons: btn-cookie-accept (primary), btn-cookie-decline (ghost-on-dark) */
.btn-cookie-accept {
  background: var(--color-brand);
  color: #fff;
  border: none;
  padding: 0.55rem 1.25rem;
  border-radius: var(--radius-sm, 8px);
  font-size: 0.83rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}
.btn-cookie-accept:hover { background: var(--color-brand-deep); }

.btn-cookie-decline {
  background: transparent;
  color: rgba(255,255,255,0.55);
  border: 1px solid rgba(255,255,255,0.18);
  padding: 0.55rem 1.25rem;
  border-radius: var(--radius-sm, 8px);
  font-size: 0.83rem;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}
.btn-cookie-decline:hover { color: #fff; border-color: rgba(255,255,255,0.35); }

/* Wohnung-Card-Button: btn-wohnung (Sonderfall — Outline-Light) */
.btn-wohnung {
  display: block;
  text-align: center;
  background: var(--color-brand-haze);
  color: var(--color-brand-deep);
  border: 1px solid var(--color-brand-mist);
  padding: 0.65rem;
  border-radius: var(--radius-sm, 8px);
  font-weight: 700;
  font-size: 0.875rem;
  text-decoration: none;
  margin-top: 1rem;
  transition: all 0.2s;
}
.btn-wohnung:hover {
  background: var(--color-brand);
  color: #fff;
  border-color: var(--color-brand);
}


/* ═══ forms.css ═══ */
/* ════════════════════════════════════════════════════════════════════════════
   forms.css — Vereinheitlichtes Form-Pattern (Public-Surface)
   ────────────────────────────────────────────────────────────────────────────
   2026-05-16 Audit-Folge: 4 Public-Forms (Vormerk-Mieter, Vormerk-Eigentuemer,
   Kontakt, Schadensmeldung) hatten je eigene Layout-Logik. Diese Datei
   liefert das gemeinsame Pattern.

   Verwendung:
     <form class="ds-form" method="post" action="...">
       <div class="ds-form__row">                <!-- 2-Spalter -->
         <div class="ds-field ds-field--required">
           <label for="vorname">Vorname</label>
           <input id="vorname" name="vorname" type="text" required
                  autocomplete="given-name" placeholder=" ">
           <small class="ds-field__error">Bitte Vornamen angeben</small>
         </div>
         <div class="ds-field ds-field--required">…</div>
       </div>

       <div class="ds-field">                    <!-- 1-Spalter -->
         <label for="anmerkung">Anmerkung (optional)</label>
         <textarea id="anmerkung" name="anmerkung" rows="4" placeholder=" "></textarea>
       </div>

       <!-- Honeypot fuer Spam-Bots (versteckt, Bots fuellen es aus) -->
       <input type="text" name="firma_name" tabindex="-1" autocomplete="off"
              style="position:absolute;left:-9999px" aria-hidden="true">

       <button type="submit" class="ds-btn ds-btn--primary ds-btn--lg ds-btn--block">
         Anfrage senden
       </button>
     </form>
   ════════════════════════════════════════════════════════════════════════════ */

.ds-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 1rem);
}

/* Row = 2-Spalter (auf Mobile: 1-Spalter) */
.ds-form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4, 1rem);
}
@media (max-width: 640px) {
  .ds-form__row { grid-template-columns: 1fr; }
}

/* Section-Heading innerhalb des Forms (z.B. "Ihre Daten" / "Ihr Anliegen") */
.ds-form__section {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--blue);
  margin: var(--space-5, 1.5rem) 0 var(--space-2, 0.5rem);
  padding-bottom: var(--space-2, 0.5rem);
  border-bottom: 1px solid var(--border);
}
.ds-form__section:first-child { margin-top: 0; }

/* Field = Label + Input + (optional) Error/Helper */
.ds-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.ds-field > label {
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text-muted);
  letter-spacing: 0.005em;
  font-family: var(--font-sans);
}

/* Required-Stern auto */
.ds-field--required > label::after {
  content: ' *';
  color: var(--accent-spark);
  font-weight: 700;
}

.ds-field > input,
.ds-field > select,
.ds-field > textarea {
  display: block;
  width: 100%;
  padding: 0.65rem 0.85rem;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md, 8px);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--dark);
  line-height: 1.4;
  transition: border-color 0.18s, box-shadow 0.18s;
  -webkit-appearance: none;
  appearance: none;
}

.ds-field > textarea {
  resize: vertical;
  min-height: 120px;
  font-family: var(--font-sans);
}

.ds-field > select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%236B5E4E' stroke-width='1.8' stroke-linecap='round'><path d='M1 1 L6 6 L11 1'/></svg>");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px 8px;
  padding-right: 2.4rem;
}

.ds-field > input::placeholder,
.ds-field > textarea::placeholder { color: var(--text-muted); opacity: 0.55; }

.ds-field > input:hover,
.ds-field > select:hover,
.ds-field > textarea:hover { border-color: var(--blue-mid); }

.ds-field > input:focus,
.ds-field > select:focus,
.ds-field > textarea:focus {
  border-color: var(--blue);
  outline: none;
  box-shadow: 0 0 0 3px rgba(45, 107, 142, 0.18);
}

/* Validation: nur nach User-Interaktion (Modern Browser via :user-invalid).
   Placeholder=" " trick erlaubt :placeholder-shown-Fallback. */
.ds-field > input:user-invalid,
.ds-field > select:user-invalid,
.ds-field > textarea:user-invalid {
  border-color: var(--color-danger, #B91C1C);
}
.ds-field > input:invalid:not(:placeholder-shown):not(:focus),
.ds-field > textarea:invalid:not(:placeholder-shown):not(:focus) {
  border-color: var(--color-danger, #B91C1C);
}

.ds-field__error {
  display: none;
  font-size: 0.8rem;
  color: var(--color-danger, #B91C1C);
  margin-top: 0.15rem;
  line-height: 1.4;
  font-family: var(--font-sans);
}

.ds-field > input:user-invalid ~ .ds-field__error,
.ds-field > select:user-invalid ~ .ds-field__error,
.ds-field > textarea:user-invalid ~ .ds-field__error,
.ds-field > input:invalid:not(:placeholder-shown):not(:focus) ~ .ds-field__error,
.ds-field > textarea:invalid:not(:placeholder-shown):not(:focus) ~ .ds-field__error {
  display: block;
}

.ds-field__helper {
  font-size: 0.78rem;
  color: var(--text-muted);
  line-height: 1.5;
  margin-top: 0.15rem;
  font-family: var(--font-sans);
}

/* Server-side Error (immer sichtbar, nicht an :invalid gekoppelt) */
.ds-field--server-error > input,
.ds-field--server-error > select,
.ds-field--server-error > textarea {
  border-color: var(--color-danger, #B91C1C);
  background: #FEF8F7;
}
.ds-field--server-error .ds-field__error { display: block; }

/* Checkbox/Radio (z.B. fuer Datenschutz-Zustimmung) */
.ds-field--check {
  flex-direction: row;
  align-items: flex-start;
  gap: 0.65rem;
}
.ds-field--check > input[type="checkbox"],
.ds-field--check > input[type="radio"] {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  accent-color: var(--blue);
  flex-shrink: 0;
}
.ds-field--check > label {
  font-size: 0.88rem;
  color: var(--dark);
  font-weight: 400;
  line-height: 1.55;
  text-transform: none;
  letter-spacing: 0;
}
.ds-field--check > label a {
  color: var(--blue);
  text-decoration: underline;
}

/* Form-Card-Wrapper: gemeinsamer Container fuer Public-Formulare */
.ds-form-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  padding: var(--space-6, 2rem);
  max-width: 580px;
  margin: 0 auto;
}
.ds-form-card__title {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
  color: var(--dark);
}
.ds-form-card__intro {
  font-size: 0.92rem;
  color: var(--text-muted);
  margin-bottom: var(--space-5, 1.5rem);
  line-height: 1.6;
  font-family: var(--font-sans);
}

/* Success-State nach erfolgreichem Submit */
.ds-form-success {
  background: var(--surface);
  border: 1px solid var(--blue-mid);
  border-radius: var(--radius-lg, 14px);
  padding: var(--space-6, 2rem);
  text-align: center;
  max-width: 580px;
  margin: 0 auto;
}
.ds-form-success__icon {
  width: 64px;
  height: 64px;
  background: var(--blue-light);
  color: var(--blue);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.8rem;
  margin-bottom: var(--space-3, 0.75rem);
}
.ds-form-success__title {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.ds-form-success__text {
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1.6;
}


/* ═══ public.css ═══ */
/* ════════════════════════════════════════════════════════════════════════════
   public.css — Oeffentliche Homepage (rottensteiner-hausverwaltung.de)
   ────────────────────────────────────────────────────────────────────────────
   Refactor 2026-05-16: Aus views/layouts/public.handlebars (1355 Zeilen
   inline) ausgelagert. Quickwin-D-Folge (CSP-Hardening), gleichzeitig:
     - Display-Font Fraunces (variable, lokal gehostet, OFL)
     - Body-Font Geist (variable, lokal gehostet, OFL)
     - Bodensee-Color-Palette (warmer, regionaler) statt generischer Saas-Blau
     - Hero mit Layered-Gradient + SVG-Wellen-Pattern statt flach #2d2d2d
     - Foto-Container im Warum-Block (statt Person-Icon-Placeholder)

   Variablen-Namen (--dark, --blue, --cream …) bleiben gleich → bestehender
   Code funktioniert weiter. Nur die HEX-Werte sind angepasst.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── @font-face: lokal gehostet, kein Google-CDN ───────────────────────── */
@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/Fraunces-Variable.woff2?v=sub1') format('woff2-variations'),
       url('/fonts/Fraunces-Variable.woff2?v=sub1') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Geist';
  src: url('/fonts/Geist-Variable.woff2?v=sub1') format('woff2-variations'),
       url('/fonts/Geist-Variable.woff2?v=sub1') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ── Design-Tokens ──────────────────────────────────────────────────────
   2026-05-16 Audit-Folge: --dark/--blue/--cream sind jetzt Aliases auf
   die semantischen --color-* Tokens in tokens.css. Aenderungen an der
   Bodensee-Palette werden NUR DORT vorgenommen (Single-Source-of-Truth).
   Public-Layout laedt tokens.css VOR public.css.
   ───────────────────────────────────────────────────────────────────── */
:root {
  /* Fraunces-Display-Font wird im Public verwendet — die Token-Aliases
     fuer --font-display-public / --font-sans-public kommen aus tokens.css.
     Hier nur die public-spezifischen Kuerzel fuer die Animations- und
     Variable-Font-Settings. */
  --font-display:  var(--font-display-public);
  --font-sans:     var(--font-sans-public);
  --fraunces-soft-default: 50;
  --fraunces-wonk-default: 0;

  /* Flaechen-Ton der hellen Abschnitte (04.09.2026).
     Vorher: reines #FFFFFF. In einer Palette aus warmem Papier (#F7F2EA) und
     warmen Linien (#DDD4C2) war das der einzige kalte Ton auf der Seite — und
     weisse Karten auf weissem Grund hingen nur an ihrem 1px-Rand.
     Jetzt: Abschnitt warm gebrochen, Karte bleibt reinweiss. Damit hebt sich
     jede Karte von selbst ab, ohne einen einzigen zusaetzlichen Schatten. */
  --flaeche-warm:  #FDFAF5;

  /* Apfelblueten-Akzent, zugriffssichere Tiefe (04.09.2026).
     --color-accent (#C8553D) aus tokens.css ist fuer Kleintext zu hell:
     4,18:1 auf der warmen Flaeche, 3,48:1 auf Schilf-Beige — beides unter
     den 4,5:1, die unsere Barrierefreiheitserklaerung zusichert. Dieser Ton
     schafft 6,04 / 5,02 / 6,29 auf warm / beige / weiss und bleibt derselbe
     Farbfamilie. Der Palettenwert bleibt fuer Flaechen und Schatten gueltig. */
  --akzent-warm:   #A83C27;
}

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

body {
  font-family: var(--font-sans);
  color: var(--text);
  background: var(--cream);
  line-height: 1.65;
  font-feature-settings: 'ss01', 'cv05';   /* Geist: subtiles Glyphen-Polish */
}

/* Headlines + Section-Titles nutzen Display-Font.
   Eyebrow + UI-Text bleibt Sans. */
h1, h2, h3, .section-title, .hero h1, .cta-strip h3, .footer-brand {
  font-family: var(--font-display);
  font-feature-settings: 'ss01';
  font-variation-settings: 'opsz' 80, 'SOFT' 50;
}

/* ── BFSG: Skip-Link & globaler Fokus-Indikator ─────────────── */
.skip-link {
  position: absolute;
  top: -100px;
  left: 0;
  z-index: 10000;
  background: var(--dark);
  color: #fff;
  padding: .75rem 1.25rem;
  border-radius: 0 0 8px 0;
  font-weight: 700;
  font-size: .9rem;
  text-decoration: none;
  transition: top .2s;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 0;
  outline: var(--focus-ring-width) solid var(--blue);
  outline-offset: 2px;
  color: #fff;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: var(--focus-ring-width) solid var(--blue);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── Bootstrap-Default-Blau → Bodensee-Design-System ─────────────────────────
   An mehreren Stellen nutzt der öffentliche Auftritt rohe Bootstrap-Klassen
   (.btn-primary, .btn-outline-primary, .text-primary, ungestylte Links,
   nav-pills-Tabs). Deren Default-Blau #0d6efd fällt aus der Bodensee-Palette,
   und die aktive nav-pill kombiniert das Blau mit dem globalen Muted-Text-
   Override unten → brauner Text auf Blau, Kontrast 1.4:1 (WCAG-Fail). Hier
   einmalig auf --color-brand (#2D6B8E) gemappt. Nur Farben — kein Layout.
   ─────────────────────────────────────────────────────────────────────────── */
body {
  --bs-primary-rgb: 45, 107, 142;          /* #2D6B8E → text-/bg-/border-primary */
  --bs-link-color-rgb: 45, 107, 142;       /* ungestylte Links (Ratgeber, Breadcrumb) */
  --bs-link-hover-color-rgb: 26, 77, 107;  /* #1A4D6B (brand-deep) für Hover */
}

.btn-primary {
  --bs-btn-bg: var(--color-brand);
  --bs-btn-border-color: var(--color-brand);
  --bs-btn-hover-bg: var(--color-brand-deep);
  --bs-btn-hover-border-color: var(--color-brand-deep);
  --bs-btn-active-bg: var(--color-brand-deep);
  --bs-btn-active-border-color: var(--color-brand-deep);
  --bs-btn-disabled-bg: var(--color-brand);
  --bs-btn-disabled-border-color: var(--color-brand);
  --bs-btn-focus-shadow-rgb: 45, 107, 142;
}

.btn-outline-primary {
  --bs-btn-color: var(--color-brand);
  --bs-btn-border-color: var(--color-brand);
  --bs-btn-hover-bg: var(--color-brand);
  --bs-btn-hover-border-color: var(--color-brand);
  --bs-btn-active-bg: var(--color-brand);
  --bs-btn-active-border-color: var(--color-brand);
  --bs-btn-disabled-color: var(--color-brand);
  --bs-btn-disabled-border-color: var(--color-brand);
  --bs-btn-focus-shadow-rgb: 45, 107, 142;
}

/* nav-pills (Kontakt-Tabs, Portal-Preview-Tabs): aktive Pille auf Design-Blau
   mit weißer Schrift (Kontrast 5.8:1). Das color:#fff !important schlägt den
   .nav-link-Muted-Override weiter unten; die :hover-Variante verhindert, dass
   .nav-link:hover{background:cream} die aktive Pille auf Weiß-auf-Creme kippt. */
.nav-pills {
  --bs-nav-pills-link-active-bg: var(--color-brand);
  --bs-nav-pills-link-active-color: #fff;
}
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link,
.nav-pills .nav-link.active:hover,
.nav-pills .nav-link.active:focus {
  color: #fff !important;
  background-color: var(--color-brand);
}

/* ── Navbar ──────────────────────────────────────────────── */
.navbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 0.9rem 0;
  transition: box-shadow 0.3s;
}

.navbar.scrolled {
  box-shadow: 0 2px 24px rgba(21,36,60,0.07);
}

.navbar-brand {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--dark) !important;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 36, 'SOFT' 50;
}

/* Brand-Mark: SVG-Logo (Haus+Welle) statt "R"-im-Quadrat.
   Die Farben werden via currentColor gesteuert — Logo passt sich
   automatisch hellem/dunklem Container an. */
.brand-mark {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--dark);
  flex-shrink: 0;
  transition: color 0.2s, transform 0.2s;
}
.navbar-brand:hover .brand-mark { color: var(--blue); transform: rotate(-3deg); }

.brand-mark svg {
  width: 100%;
  height: 100%;
}

/* :not(.btn-nav): das !important hier hatte das color:#fff des „Vormerken"-CTA
   (buttons.css .btn-nav) überschrieben → braune Schrift auf Brand-Blau,
   Kontrast ~1.3:1 (axe serious). Der CTA behält sein eigenes Styling. */
.nav-link:not(.btn-nav) {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-muted) !important;
  padding: 0.4rem 0.85rem !important;
  border-radius: 6px;
  transition: all 0.18s;
}

.nav-link:not(.btn-nav):hover {
  color: var(--dark) !important;
  background: var(--cream);
}

/* .btn-nav: definiert in /css/buttons.css (Design-System) */

/* ── Burger-Toggle-Animation (Hamburger → X) ─────────────────────────────
   Bootstrap-Navbar-Toggler toggelt aria-expanded auf dem Button — wir
   nutzen das als CSS-State fuer die Transition. */
.navbar-toggler-anim {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.navbar-toggler-icon-anim {
  position: relative;
  width: 24px;
  height: 18px;
  display: inline-block;
}
.navbar-toggler-icon-anim span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--dark);
  border-radius: 2px;
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.18s ease;
  transform-origin: center;
}
.navbar-toggler-icon-anim span:nth-child(1) { top: 0; }
.navbar-toggler-icon-anim span:nth-child(2) { top: 8px; }
.navbar-toggler-icon-anim span:nth-child(3) { top: 16px; }

/* aria-expanded="true" → X-Form */
.navbar-toggler-anim[aria-expanded="true"] .navbar-toggler-icon-anim span:nth-child(1) {
  transform: translateY(8px) rotate(45deg);
}
.navbar-toggler-anim[aria-expanded="true"] .navbar-toggler-icon-anim span:nth-child(2) {
  opacity: 0;
  transform: scaleX(0.3);
}
.navbar-toggler-anim[aria-expanded="true"] .navbar-toggler-icon-anim span:nth-child(3) {
  transform: translateY(-8px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .navbar-toggler-icon-anim span { transition: none; }
}

/* ── Hero — Layered Gradient + Topografie-Wellen-Pattern statt flach ──
   Pattern als inline-SVG-Background; sehr subtil, evokiert
   Bodensee-Wellen ohne kitschig zu sein.
   .hero--with-photo: aktiv wenn /images/hero-bodensee.jpg existiert
   (server-Auto-Detect). Das Foto liegt UNTER dem Gradient als Layer. */
.hero {
  background:
    /* Subtiler heller Schimmer oben rechts */
    radial-gradient(ellipse 80% 60% at 85% 0%, rgba(45,107,142,0.35), transparent 70%),
    /* Tieferer Mid-Layer */
    radial-gradient(ellipse 60% 90% at 0% 100%, rgba(184,212,227,0.08), transparent 60%),
    /* Wellen-Pattern (sehr subtil, rgba 0.04 opacity) */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='200' viewBox='0 0 400 200'><g fill='none' stroke='%23E5EFF5' stroke-width='0.6' opacity='0.18'><path d='M0,40 Q100,20 200,40 T400,40' /><path d='M0,80 Q100,60 200,80 T400,80' /><path d='M0,120 Q100,100 200,120 T400,120' /><path d='M0,160 Q100,140 200,160 T400,160' /></g></svg>"),
    /* Basis-Farbe: Tiefes See-Nachtblau */
    linear-gradient(180deg, #15243C 0%, #0F1B2E 100%);
  color: #fff;
  padding: 7rem 0 5.5rem;
  position: relative;
  overflow: hidden;
}

/* Hero mit echtem Foto: legt das Foto UNTER den Overlay-Gradient.
   Overlay bleibt opaque genug fuer 4.5:1 Textkontrast (WCAG AA). */
.hero--with-photo {
  background:
    /* Dark Overlay fuer Text-Lesbarkeit */
    linear-gradient(180deg, rgba(21,36,60,0.78) 0%, rgba(15,27,46,0.92) 100%),
    /* Subtiles Wellen-Pattern bleibt drueber */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='200' viewBox='0 0 400 200'><g fill='none' stroke='%23E5EFF5' stroke-width='0.6' opacity='0.12'><path d='M0,40 Q100,20 200,40 T400,40' /><path d='M0,80 Q100,60 200,80 T400,80' /><path d='M0,120 Q100,100 200,120 T400,120' /><path d='M0,160 Q100,140 200,160 T400,160' /></g></svg>"),
    /* Bodensee-Foto, Center-Crop */
    url('/images/hero-bodensee.jpg') center/cover no-repeat,
    /* Fallback */
    linear-gradient(180deg, #15243C 0%, #0F1B2E 100%);
}

.hero::before {
  content: '';
  position: absolute;
  top: 0; right: 0;
  width: 45%;
  height: 100%;
  background: linear-gradient(135deg, transparent, rgba(45,107,142,0.18));
  /* Hier stand `border-left: 1px solid rgba(255,255,255,0.05)`. Gemeint war
     eine leise Lichtkante am Panel — angekommen ist eine Naht, die vom oberen
     bis zum unteren Rand durchlief und dabei mitten durch die Zeile
     „Persönlich verwaltet" schnitt. Entfernt 04.09.2026.

     Damit war die Kante aber erst halb weg: ein 135°-Verlauf ist an seiner
     linken Kante nur ganz oben durchsichtig und weiter unten schon eingefaerbt
     — dadurch blieb dort eine sichtbare Stufe stehen. Die Maske blendet die
     linke Kante ueber ein Drittel der Panelbreite ein, unabhaengig davon,
     welche Richtung der Verlauf darunter nimmt. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 34%);
          mask-image: linear-gradient(to right, transparent, #000 34%);
  pointer-events: none;
}

/* Sehr subtile horizontale "Wasseroberflaeche" auf 60% Hoehe */
/* ── Treibende Wellen im Seitenkopf (04.09.2026) ────────────────────────────
   Vorher lag hier eine waagerechte 1px-Zierlinie auf 60 % Hoehe. Sie hatte
   keinen Bezug zum Rest und wird jetzt als bewegte Wellenebene gebraucht.

   Wie die Tiefe entsteht, ohne zwei Elemente zu kosten: die Ebene traegt ZWEI
   Wellenmuster mit unterschiedlicher Kachelbreite (400 px und 600 px). Beide
   werden von derselben Verschiebung getragen, brauchen aber unterschiedlich
   lang fuer eine Kachel — dadurch driften sie gegeneinander. Darunter bleibt
   das Muster im .hero-Hintergrund stehen: bewegte Oberflaeche ueber ruhigem
   Grund.

   Verschoben wird um 1200 px — das kleinste gemeinsame Vielfache von 400 und
   600. Nur dort stehen beide Muster wieder exakt auf Anfang, nur dort ist die
   Schleife nahtlos. Wer die Zahlen aendert, muss das Vielfache mitziehen.

   Bewegt wird ausschliesslich per transform: das laeuft auf der Grafikkarte,
   loest kein Neuzeichnen aus und kostet kein einziges geladenes Byte. */
.hero::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  /* Zwei volle Zyklen Vorrat, nicht einer. Mit exakt 1200 px sitzt die rechte
     Kante nach einem Durchlauf genau auf der Fensterkante — eine Rundung auf
     Subpixel reisst dort einen Haarriss auf, und die Schleife springt sichtbar.
     Mit 2400 px ist immer Material da. (Nachgemessen 04.09.2026.) */
  width: calc(100% + 2400px);
  height: 100%;
  pointer-events: none;
  background-repeat: repeat-x, repeat-x;
  background-size: 400px 200px, 600px 260px;
  background-position: 0 38%, 0 62%;
  background-image:
    /* Oberflaeche: engere Kachel, wirkt dadurch schneller */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='200' viewBox='0 0 400 200'><g fill='none' stroke='%23E5EFF5' stroke-width='0.7' opacity='0.20'><path d='M0,60 Q100,34 200,60 T400,60'/><path d='M0,110 Q100,84 200,110 T400,110'/></g></svg>"),
    /* Tiefe: breitere Kachel, wirkt dadurch langsamer */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='260' viewBox='0 0 600 260'><g fill='none' stroke='%23B8D4E3' stroke-width='0.8' opacity='0.13'><path d='M0,90 Q150,52 300,90 T600,90'/><path d='M0,170 Q150,132 300,170 T600,170'/></g></svg>");
  animation: hero-wellen 40s linear infinite;
}

@keyframes hero-wellen {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-1200px, 0, 0); }
}

/* Wer Bewegung systemweit abgeschaltet hat, sieht das ruhige Bild — so, wie
   die Barrierefreiheitserklaerung es zusichert. */
@media (prefers-reduced-motion: reduce) {
  .hero::after { animation: none; }
}

.hero-label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #B8D4E3;
  background: rgba(45,107,142,0.18);
  border: 1px solid rgba(184,212,227,0.25);
  padding: 0.4rem 1rem;
  border-radius: 50px;
  margin-bottom: 1.75rem;
  font-family: var(--font-sans);
}

.hero h1 {
  font-size: clamp(2.5rem, 5.5vw, 4.5rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin-bottom: 1.5rem;
  color: #fff;
  /* Fraunces Display-Variant: groessere Optical-Size, weichere Caps */
  font-variation-settings: 'opsz' 144, 'SOFT' 70, 'wght' 600;
}

.hero h1 span {
  color: #B8D4E3;
  font-style: italic;
  font-variation-settings: 'opsz' 144, 'SOFT' 100, 'wght' 500;
}

.hero-lead {
  font-size: 1.08rem;
  color: rgba(255,255,255,0.72);
  max-width: 480px;
  line-height: 1.7;
  margin-bottom: 2.5rem;
  font-family: var(--font-sans);
}

/* .btn-hero, .btn-hero-ghost: definiert in /css/buttons.css (Design-System) */

.hero-stats {
  display: flex;
  gap: 2rem;
  margin-top: 3.5rem;
  padding-top: 2.5rem;
  border-top: 1px solid rgba(255,255,255,0.08);
}

.hero-stat-num {
  font-size: 2.15rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.03em;
  line-height: 1;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 100, 'wght' 600;
}

.hero-stat-label {
  font-size: 0.75rem;
  color: rgba(255,255,255,0.5);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 0.3rem;
  font-family: var(--font-sans);
}

/* ── Sections ────────────────────────────────────────────── */
.section { padding: 5.5rem 0; }
.section-alt { background: var(--cream-dark); }
.section-white { background: var(--flaeche-warm); }

.eyebrow {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  /* Vorher --blue: damit war die ganze Seite einfarbig und der Akzent der
     Marke ungenutzt. Die Vorzeile ist die richtige Stelle dafuer — klein,
     wiederkehrend, nie als Flaeche. Das Blau bleibt den Knoepfen und
     Verweisen vorbehalten und wirkt dadurch wieder. (04.09.2026) */
  color: var(--akzent-warm);
  margin-bottom: 0.85rem;
  display: block;
  font-family: var(--font-sans);
}

.section-title {
  font-size: clamp(1.85rem, 3.5vw, 2.6rem);
  font-weight: 600;
  color: var(--dark);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin-bottom: 0.85rem;
  font-variation-settings: 'opsz' 80, 'SOFT' 60, 'wght' 600;
}

.section-sub {
  font-size: 1rem;
  color: var(--text-muted);
  max-width: 520px;
  line-height: 1.7;
  font-family: var(--font-sans);
}

/* ── Wohnung Cards ───────────────────────────────────────── */
.wohnung-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.wohnung-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 20px 48px rgba(21,36,60,0.1);
  border-color: var(--blue-mid);
}

.wohnung-img {
  height: 190px;
  background: var(--cream-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 2.75rem;
  position: relative;
}

.wohnung-badge {
  position: absolute;
  top: 1rem;
  left: 1rem;
  background: var(--blue);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
}

.wohnung-body { padding: 1.4rem; }

.wohnung-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--dark);
  margin-bottom: 0.3rem;
}

.wohnung-address {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.wohnung-specs {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.85rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  margin-bottom: 1rem;
}

.spec-pill {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--cream);
  border: 1px solid var(--border);
  padding: 0.25rem 0.65rem;
  border-radius: 50px;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--dark);
}

.spec-pill i { color: var(--blue); font-size: 0.75rem; }

.wohnung-price {
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--dark);
  letter-spacing: -0.02em;
  font-family: var(--font-display);
}

.wohnung-price small {
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--text-muted);
  font-family: var(--font-sans);
}

/* .btn-wohnung: definiert in /css/buttons.css */

/* ── Service Cards ───────────────────────────────────────── */
.service-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.85rem;
  height: 100%;
  transition: all 0.25s;
  position: relative;
}

.service-card:hover {
  border-color: var(--blue-mid);
  box-shadow: 0 8px 32px rgba(45,107,142,0.12);
  transform: translateY(-3px);
}

.service-icon {
  width: 48px;
  height: 48px;
  background: var(--blue-light);
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  color: var(--blue);
  margin-bottom: 1.15rem;
  transition: all 0.25s;
}

.service-card:hover .service-icon {
  background: var(--blue);
  color: #fff;
}

/* Service-Illustration: Custom-SVG-Block (2026-05-16). Eigenstaendiger
   Look statt generischer Bootstrap-Icons. Monoline-Stil passend zum Logo. */
.service-illustration {
  width: 88px;
  height: 88px;
  background: var(--blue-light);
  border-radius: var(--radius-lg, 14px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px;
  color: var(--blue);
  margin-bottom: 1.25rem;
  transition: background 0.25s, color 0.25s, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.service-illustration svg {
  width: 100%;
  height: 100%;
}
.service-card:hover .service-illustration {
  background: var(--blue);
  color: #fff;
  transform: rotate(-3deg) scale(1.05);
}

.service-cta {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--blue);
  margin-top: 1.15rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: gap 0.2s, color 0.2s;
  font-family: var(--font-sans);
}
.service-card:hover .service-cta {
  color: var(--blue-dark);
  gap: 0.6rem;
}

.service-card h5 {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 0.55rem;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 36, 'wght' 600;
}

.service-card p {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.65;
  margin: 0;
  font-family: var(--font-sans);
}

/* ── Why Numbers ─────────────────────────────────────────── */
.why-row {
  display: flex;
  gap: 1rem;
  padding: 1.5rem;
  border-radius: 12px;
  transition: background 0.2s;
}

.why-row:hover { background: var(--cream); }

.why-num {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--blue);
  letter-spacing: -0.02em;
  background: var(--blue-light);
  border: 1px solid var(--blue-mid);
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 0.1rem;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 36, 'wght' 600;
}

.why-row h5 {
  font-size: 1rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 0.3rem;
  font-family: var(--font-display);
}

.why-row p {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.65;
}

/* ── CTA ─────────────────────────────────────────────────── */
.cta-strip {
  background:
    radial-gradient(ellipse 60% 80% at 100% 0%, rgba(45,107,142,0.35), transparent 60%),
    linear-gradient(135deg, #15243C 0%, #0F1B2E 100%);
  border-radius: 18px;
  padding: 3rem 3.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem 3rem;
  flex-wrap: wrap;
  position: relative;
  overflow: hidden;
}
/* Der Textblock hatte keine Breitenbegrenzung, nahm die volle Zeile und
   draengte die Knoepfe in die naechste — rechts blieben rund 60 % der
   Flaeche leer, ausgerechnet an der Stelle, an der jemand anfragen soll.
   Jetzt teilen sich Text und Knoepfe die Leiste. (04.09.2026) */
.cta-strip > div:first-child { flex: 1 1 26rem; min-width: 0; }

.cta-strip h3 {
  font-size: 1.85rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.02em;
  margin-bottom: 0.4rem;
  font-variation-settings: 'opsz' 80, 'SOFT' 60, 'wght' 600;
}

.cta-strip p {
  color: rgba(255,255,255,0.6);
  font-size: 0.95rem;
  margin: 0;
  font-family: var(--font-sans);
}

/* ── Buttons ─────────────────────────────────────────────────────────────
   .btn-blue, .btn-outline-dark, .btn-hero(-ghost), .btn-nav,
   .btn-cta-(primary|secondary), .btn-cookie-(accept|decline), .btn-wohnung
   sind alle in /css/buttons.css definiert (Design-System).
   ──────────────────────────────────────────────────────────────────────── */

/* ── Footer ──────────────────────────────────────────────── */
.footer {
  background:
    linear-gradient(180deg, #15243C 0%, #0F1B2E 100%);
  color: rgba(255,255,255,0.72);
  padding: 4rem 0 2rem;
}

.footer-brand {
  font-size: 1.05rem;
  font-weight: 600;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-bottom: 0.95rem;
  font-variation-settings: 'opsz' 36, 'SOFT' 50;
}

.footer-brand-mark {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #B8D4E3;
}
.footer-brand-mark svg { width: 100%; height: 100%; }

.footer h6 {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  margin-bottom: 1rem;
  font-weight: 700;
  font-family: var(--font-sans);
}

.footer p { font-size: 0.88rem; line-height: 1.7; }

.footer-links { list-style: none; padding: 0; margin: 0; }
.footer-links li { margin-bottom: 0.55rem; }
.footer-links a {
  color: rgba(255,255,255,0.6);
  text-decoration: none;
  font-size: 0.88rem;
  transition: color 0.18s;
}
.footer-links a:hover { color: #fff; }

.portal-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  color: #B8D4E3;
  background: rgba(45,107,142,0.18);
  border: 1px solid rgba(184,212,227,0.25);
  padding: 0.35rem 0.85rem;
  border-radius: 50px;
  text-decoration: none;
  margin-top: 0.75rem;
  transition: all 0.2s;
}

.portal-link:hover {
  background: rgba(45,107,142,0.3);
  color: #fff;
}

.footer-hr {
  border-color: rgba(255,255,255,0.08);
  margin: 2.5rem 0 1.5rem;
}

.footer-copy {
  font-size: 0.8rem;
  color: rgba(255,255,255,0.32);
}

/* ── WhatsApp ────────────────────────────────────────────── */
.fab-whatsapp {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 52px;
  height: 52px;
  background: #25d366;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 1.5rem;
  text-decoration: none;
  box-shadow: 0 4px 20px rgba(37,211,102,0.35);
  z-index: 999;
  transition: all 0.25s;
}

.fab-whatsapp:hover {
  transform: scale(1.1);
  color: #fff;
  box-shadow: 0 8px 28px rgba(37,211,102,0.5);
}

/* ── Scroll Reveal ───────────────────────────────────────── */
/* Default SICHTBAR (No-JS-Fallback: ohne JS keine unsichtbaren Sektionen).
   Reveal-Animation nur wenn JS läuft — .js wird im <head> VOR dem ersten Paint
   gesetzt, daher kein Flash sichtbar→unsichtbar→eingeblendet. */
.reveal { opacity: 1; }
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.55s ease, transform 0.55s ease;
}
.js .reveal.visible { opacity: 1; transform: none; }
/* Touch-Press-Feedback: taktiles „gedrückt" auf Karten (Hover-Lift gibt's nur
   mit Maus). Nur bei aktivierter Motion. */
@media (prefers-reduced-motion: no-preference) {
  .service-card:active, .wohnung-card:active, .problem-card:active,
  .feature-card:active, .ratgeber-card:active { transform: scale(0.99); }
}
/* Beim Drucken muss ALLES sichtbar sein. Ohne diese Regel druckt der Browser
   nur, was der Besucher vorher in den Sichtbereich gescrollt hat — die
   Startseite kam zu rund 70 % leer aus dem Drucker (Befund 04.09.2026).
   Betrifft auch PDF-Export und jedes Vorschau-Werkzeug. */
@media print {
  .js .reveal,
  .js .reveal.visible {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  /* Bedienelemente gehoeren nicht aufs Papier. */
  .sticky-cta-mobile, .fab-whatsapp, .skip-link, .navbar-toggler { display: none !important; }
}
.reveal-delay-1 { transition-delay: 0.08s; }
.reveal-delay-2 { transition-delay: 0.16s; }
.reveal-delay-3 { transition-delay: 0.24s; }
.reveal-delay-4 { transition-delay: 0.32s; }
.reveal-delay-5 { transition-delay: 0.40s; }

/* ── Hero Payment Animation (Mock Dashboard, falls genutzt) ─ */
@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateX(12px); }
  to   { opacity: 1; transform: translateX(0); }
}

.hv-anim-1 { animation: fadeSlideIn 0.5s ease 0.8s both; }
.hv-anim-2 { animation: fadeSlideIn 0.5s ease 1.1s both; }
.hv-anim-3 { animation: fadeSlideIn 0.5s ease 1.4s both; }

/* ── Hero Trust ──────────────────────────────────────────── */
.hero-trust {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.25rem;
  font-size: 0.85rem;
  color: rgba(255,255,255,0.55);
}

/* ── Hero Visual (Mock Dashboard) ───────────────────────── */
.hero-visual { position: relative; padding: 1rem 0.5rem 2rem; }

.hv-card {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 14px;
  overflow: hidden;
  backdrop-filter: blur(8px);
}

.hv-card-header {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.75rem 1rem;
  background: rgba(255,255,255,0.04);
  border-bottom: 1px solid rgba(255,255,255,0.07);
}

.hv-dot { width: 10px; height: 10px; border-radius: 50%; }
.hv-card-body { padding: 1.25rem; }

.hv-stat-row { display: flex; gap: 1rem; margin-bottom: 1rem; }
.hv-stat { flex: 1; }

.hv-stat-n {
  font-size: 1.5rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.03em;
  line-height: 1;
  font-family: var(--font-display);
}

.hv-stat-l {
  font-size: 0.7rem;
  color: rgba(255,255,255,0.45);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 0.25rem;
  font-family: var(--font-sans);
}

.hv-divider {
  border: none;
  border-top: 1px solid rgba(255,255,255,0.08);
  margin: 0.85rem 0;
}

.hv-payment-row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.4rem 0;
}

.hv-avatar {
  width: 28px;
  height: 28px;
  background: rgba(45,107,142,0.4);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 700;
  color: #B8D4E3;
  flex-shrink: 0;
}

.hv-pname { font-size: 0.82rem; color: rgba(255,255,255,0.78); flex: 1; }
.hv-pamt { font-size: 0.82rem; font-weight: 700; font-family: var(--font-display); }
.hv-green { color: var(--color-success, #4ade80); }

.hv-total-row { display: flex; align-items: center; justify-content: space-between; }

.hv-total {
  font-size: 1.15rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.02em;
  font-family: var(--font-display);
}

.hv-badge-float {
  position: absolute;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 50px;
  padding: 0.45rem 0.9rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--dark);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  white-space: nowrap;
}

.hv-badge-1 { bottom: 0.5rem; left: -1rem; }
.hv-badge-2 { top: 0.5rem; right: -1rem; }

/* ── Trust Bar ───────────────────────────────────────────── */
.trust-bar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 1.15rem 0;
}

.trust-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  flex-wrap: wrap;
}

.trust-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.83rem;
  font-weight: 500;
  color: var(--text-muted);
  padding: 0.4rem 1.5rem;
}

.trust-item i { color: var(--blue); font-size: 0.9rem; }

.trust-sep {
  width: 1px;
  height: 1.2rem;
  background: var(--border);
}

/* ── Step Cards (How It Works) ───────────────────────────── */
.step-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 2.1rem 1.85rem;
  height: 100%;
  position: relative;
  transition: all 0.25s;
}

.step-card:hover {
  border-color: var(--blue-mid);
  box-shadow: 0 8px 32px rgba(45,107,142,0.12);
  transform: translateY(-3px);
}

.step-num {
  font-size: 2.4rem;
  font-weight: 600;
  color: var(--blue-mid);
  letter-spacing: -0.04em;
  line-height: 1;
  margin-bottom: 1rem;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144, 'wght' 600;
}

.step-card h5 {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 0.5rem;
  font-family: var(--font-display);
}

.step-card p {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.65;
  margin: 0;
  font-family: var(--font-sans);
}

/* ── CTA Strip Enhancements ──────────────────────────────── */
.cta-eyebrow {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #B8D4E3;
  margin-bottom: 0.5rem;
  font-family: var(--font-sans);
}

.cta-reassurance {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  font-size: 0.82rem;
  color: rgba(255,255,255,0.5);
}

.cta-reassurance span { display: flex; align-items: center; gap: 0.35rem; }
/* Die Haken standen in --color-success (#15803D, dunkelgruen) auf dunklem
   Marineblau — praktisch unsichtbar und ausserdem die einzige gruene Farbe
   auf der ganzen Seite. Jetzt Morgennebel-Hell aus der eigenen Palette. */
.cta-reassurance i { color: var(--color-brand-mist); }

.cta-actions {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  flex-shrink: 0;
}

/* .btn-cta-primary, .btn-cta-secondary: definiert in /css/buttons.css */

/* ── Stats Bar ───────────────────────────────────────────── */
.stats-bar {
  background:
    radial-gradient(ellipse 50% 100% at 50% 100%, rgba(45,107,142,0.35), transparent 70%),
    linear-gradient(180deg, #15243C 0%, #0F1B2E 100%);
  padding: 3rem 0;
}

.stats-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0;
}

.stat-item { text-align: center; padding: 0 3rem; }

.stat-n {
  font-size: clamp(2.2rem, 4vw, 3.2rem);
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.04em;
  line-height: 1;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144, 'wght' 600;
}

.stat-l {
  font-size: 0.78rem;
  color: rgba(255,255,255,0.5);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-top: 0.5rem;
  font-family: var(--font-sans);
}

.stat-sep { width: 1px; height: 3rem; background: rgba(255,255,255,0.1); }

/* ── Problem Section ─────────────────────────────────────── */
.problem-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 2rem 1.85rem;
  height: 100%;
  transition: all 0.25s;
}

.problem-card:hover {
  /* War #fca5a5 — ein Rot aus einem fremden Baukasten, das in dieser Palette
     nicht vorkommt. Jetzt der eigene Apfelblueten-Akzent, passend zum
     Schatten darunter, der ihn ohnehin schon benutzt hat. */
  border-color: color-mix(in srgb, var(--color-accent) 45%, var(--border));
  box-shadow: 0 8px 32px rgba(200,85,61,0.1);
  transform: translateY(-3px);
}

.problem-icon {
  width: 50px;
  height: 50px;
  background: #FBEAE5;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.35rem;
  color: var(--accent-spark);
  margin-bottom: 1.15rem;
}

.problem-card h5 {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 0.5rem;
  font-family: var(--font-display);
}

.problem-card p {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.65;
  margin: 0;
  font-family: var(--font-sans);
}

.problem-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--blue);
}

.problem-arrow i { font-size: 1.4rem; }

/* ── Portrait ────────────────────────────────────────────── */
.portrait-wrap {
  position: relative;
  display: inline-block;
  width: 100%;
}

.portrait-placeholder {
  width: 100%;
  aspect-ratio: 3/4;
  max-width: 380px;
  background:
    /* Wenn ein Foto im Element ist, sieht man dieses statt des Patterns */
    var(--portrait-bg-color, var(--cream-dark));
  border-radius: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 6rem;
  color: var(--border);
  border: 1px solid var(--border);
  overflow: hidden;
  position: relative;
}

/* Wenn ein <img>-Element drin ist, soll es das Quadrat ausfuellen */
.portrait-placeholder img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Subtiler Hauch von Bodensee-Atmosphaere im Placeholder */
.portrait-placeholder::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 50% 30%, rgba(184,212,227,0.5), transparent 70%),
    radial-gradient(ellipse 50% 40% at 80% 80%, rgba(214,156,92,0.25), transparent 60%);
  pointer-events: none;
}
.portrait-placeholder.has-image::before { display: none; }

.portrait-badge {
  position: absolute;
  bottom: -1rem;
  right: -1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 0.95rem 1.2rem;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  box-shadow: 0 8px 24px rgba(21,36,60,0.1);
}

.portrait-badge-avatar {
  width: 42px;
  height: 42px;
  background: var(--blue);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 600;
  color: #fff;
  flex-shrink: 0;
  font-family: var(--font-display);
}

.portrait-badge-name {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--dark);
  font-family: var(--font-display);
}

.portrait-badge-role {
  font-size: 0.78rem;
  color: var(--text-muted);
  font-family: var(--font-sans);
}

/* ── Testimonials ────────────────────────────────────────── */
.testimonial-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.85rem;
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: all 0.25s;
}

.testimonial-card:hover {
  border-color: var(--blue-mid);
  box-shadow: 0 8px 32px rgba(45,107,142,0.12);
  transform: translateY(-3px);
}

.testimonial-stars {
  font-size: 1rem;
  color: var(--accent-spark);
  letter-spacing: 0.05em;
  margin-bottom: 1rem;
}

.testimonial-text {
  font-size: 0.95rem;
  color: var(--dark);
  line-height: 1.7;
  font-style: italic;
  flex: 1;
  margin-bottom: 1.25rem;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 36, 'SOFT' 100;
}

.testimonial-author {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.testimonial-avatar {
  width: 40px;
  height: 40px;
  background: var(--blue-light);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--blue);
  flex-shrink: 0;
  font-family: var(--font-display);
}

.testimonial-name {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--dark);
  font-family: var(--font-display);
}

.testimonial-role {
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* ── Stat-Headlines (massive Display-Schrift fuer USP-Zahlen) ────────────
   Ersetzt die alten .step-card-Boxen in section.section-stats — die
   Zahlen sind dein staerkster USP, also typografisches Statement statt
   gleicher Card wie alle anderen Sections. */
.section-stats {
  background: var(--cream-dark);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.stat-headline {
  text-align: center;
  padding: 1rem 0.5rem;
  position: relative;
}

.stat-headline__num {
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 8vw, 6rem);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: -0.04em;
  color: var(--dark);
  font-variation-settings: 'opsz' 144, 'SOFT' 30, 'wght' 600;
  margin-bottom: 1rem;
  display: inline-flex;
  align-items: baseline;
  gap: 0.05em;
}

.stat-headline__unit {
  font-size: 0.55em;
  font-weight: 500;
  color: var(--blue);
  letter-spacing: -0.02em;
  font-variation-settings: 'opsz' 80, 'SOFT' 30, 'wght' 500;
}

.stat-headline__label {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 0.5rem;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 36, 'wght' 600;
}

.stat-headline__caption {
  font-size: 0.88rem;
  color: var(--text-muted);
  line-height: 1.65;
  margin: 0;
  max-width: 280px;
  margin-left: auto;
  margin-right: auto;
  font-family: var(--font-sans);
}

/* Counter-Up wird beim Scroll-Reveal von public-init.js getriggert.
   reduced-motion: kein Counter, nur Final-Wert. */
@media (prefers-reduced-motion: reduce) {
  .stat-headline__num { transition: none !important; }
}

/* ── FAQ ─────────────────────────────────────────────────── */
.faq-accordion { display: flex; flex-direction: column; gap: 0; }

.faq-item { border-bottom: 1px solid var(--border); }
.faq-item:first-child { border-top: 1px solid var(--border); }

.faq-question {
  width: 100%;
  background: none;
  border: none;
  padding: 1.15rem 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--dark);
  text-align: left;
  cursor: pointer;
  transition: color 0.18s;
  font-family: var(--font-display);
}

.faq-question:hover { color: var(--blue); }
.faq-question:not(.collapsed) { color: var(--blue); }

.faq-icon {
  font-size: 0.85rem;
  transition: transform 0.25s;
  flex-shrink: 0;
  color: var(--text-muted);
}

.faq-question:not(.collapsed) .faq-icon {
  transform: rotate(180deg);
  color: var(--blue);
}

.faq-answer {
  padding: 0 0 1.15rem;
  font-size: 0.92rem;
  color: var(--text-muted);
  line-height: 1.7;
  font-family: var(--font-sans);
}

/* ── Sticky Mobile CTA ───────────────────────────────────── */
.sticky-cta-mobile {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 990;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 0.75rem 1rem;
  gap: 0.6rem;
  box-shadow: 0 -4px 20px rgba(0,0,0,0.08);
}

/* ── Cookie Banner ───────────────────────────────────────── */
.cookie-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  background: var(--dark);
  color: rgba(255,255,255,0.82);
  padding: 1rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  border-top: 1px solid rgba(255,255,255,0.08);
  transform: translateY(100%);
  transition: transform 0.4s ease;
}

.cookie-banner.visible { transform: translateY(0); }

.cookie-banner p {
  font-size: 0.84rem;
  margin: 0;
  line-height: 1.5;
  flex: 1;
  min-width: 200px;
}

.cookie-banner a { color: #B8D4E3; text-decoration: none; }

.cookie-actions { display: flex; gap: 0.6rem; flex-shrink: 0; }

/* .btn-cookie-accept, .btn-cookie-decline: definiert in /css/buttons.css */

/* ── Mobile ──────────────────────────────────────────────── */
@media (max-width: 768px) {
  .hero { padding: 4.5rem 0 3.5rem; }
  .hero h1 { font-size: 2.4rem; }
  .hero-stats { gap: 1.5rem; }
  .section { padding: 3.5rem 0; }
  .cta-strip { padding: 2rem; flex-direction: column; align-items: flex-start; }
  .hero::before { display: none; }
  .hv-badge-1, .hv-badge-2 { display: none; }
  .trust-sep { display: none; }
  .trust-item { padding: 0.4rem 0.75rem; }
  .cta-actions { width: 100%; }
  .btn-cta-primary, .btn-cta-secondary { width: 100%; justify-content: center; }
  .stat-item { padding: 1rem 1.5rem; }
  .stat-sep { width: 100%; height: 1px; }
  .stats-inner { flex-direction: row; flex-wrap: wrap; }
  .stat-item { flex: 1 1 40%; }
  .stat-sep { display: none; }
  .portrait-placeholder { max-width: 100%; aspect-ratio: 4/3; }
  .portrait-badge { right: 0; }
  .sticky-cta-mobile { display: flex; }
  .cookie-banner { flex-direction: column; align-items: flex-start; }
  .cookie-actions { width: 100%; }
  .btn-cookie-accept, .btn-cookie-decline { flex: 1; text-align: center; }
}

/* ── Mobile-Overflow-Fix: g-5-Gutter sprengt Container-Padding ────────────────
   Bootstrap-.row.g-5/.gx-5 setzt --bs-gutter-x:3rem → negative Außen-Margins
   von je 24px. Der umschließende .container gibt aber nur 12px Padding je Seite.
   Auf Viewports <576px (Container = 100% breit, kein zentrierter Rest-Rand als
   Puffer) ragt jede g-5-Row genau 12px pro Seite über die Viewport-Breite →
   horizontaler Scrollbalken auf ALLEN öffentlichen Seiten (Footer-Row im
   geteilten Layout + mehrere Inhalts-Rows in Kontakt/Index/Eigentümer/WEG/…).
   Fix: horizontalen Gutter dieser Rows auf Mobile auf Container-Niveau (1.5rem)
   senken → Row-Ränder fluchten mit der Viewport-Kante, kein Überhang. Der
   vertikale Gutter (--bs-gutter-y) bleibt unberührt; die Spalten stapeln <576px
   ohnehin, also kein sichtbarer Layout-Verlust. Desktop bleibt bei 3rem. */
@media (max-width: 575.98px) {
  .row.g-5,
  .row.gx-5 {
    --bs-gutter-x: 1.5rem;
  }
}

/* Danger-Icon der Notfall-/Schadens-„problem-card" (Warndreieck) — als Klasse,
   damit die Notfall-/Schadensmeldung-Views ohne Inline-Style auskommen. */
.problem-icon-danger { background: #fef2f2; color: #ef4444; }

/* Honeypot-Feld (Bot-Falle) — aus dem Viewport geschoben statt display:none,
   weil manche Bots display:none-Felder erkennen und auslassen. Für Menschen
   unsichtbar und nicht fokussierbar (tabindex="-1" + aria-hidden im Markup).
   Als Klasse, damit die Views ohne Inline-Style auskommen (CI-Gate
   scripts/check-inline-styles.js blockt neue style="…"-Werte). */
.hp-feld {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

