/* =============================================================
   Vollweiler & Niederberger GmbH — Stylesheet
   -------------------------------------------------------------
   INHALT
   0.  Design-Tokens (:root)
   1.  Reset & Basis
   2.  Typografie & Hilfsklassen
   3.  Layout (Container, Sections, Grids)
   4.  Buttons & Formulare
   5.  Header & Navigation
   6.  Mobile-Drawer (Geschwister von <header>, nie darin)
   7.  Hero (nur Startseite)
   8.  Vertrauensleiste
   9.  Karten (Leistung, Objekt, Schritt, Stimme)
   10. Objektfilter & Exposé  ·  10b. Bewertungsrechner (Klick zum Laden)
   11. FAQ (details/summary)
   12. Kontakt & Footer
   13. Cookie-Banner & Toast
   14. Rechtsseiten & 404
   15. Animationen (Reveal)
   16. Zugänglichkeit & Fallbacks
   17. Pflichtangaben Energieausweis (§ 87 GEG)
   18. Seitenkopf & Bildbänder
   19. Grafiken & Seitenrhythmus
   20. Kundenstimmen & Vertrauens-Siegel
   21. Bild und Text nebeneinander
   22. Farbe für Signale
   23. Hilfsklassen statt Inline-Styles
   24. Google-Plakette
   25. Handy-Feinschliff
   ============================================================= */

/* ---------- 0. DESIGN-TOKENS ---------- */
:root {
  color-scheme: light;

  /* Palette — abgeleitet aus dem monochromen V&N-Monogramm.
     Ein einziger warmer Akzent (gedecktes Messing) statt Makler-Blau. */
  --ink:        #15171b;
  --ink-soft:   #3d424b;
  /* Abgedunkelt: auf dem warmen Grund #f1ebe1 erreichte der alte Ton nur
     3,86 : 1, gefordert sind 4,5. Jetzt 4,80 dort und 5,70 auf Weiß. */
  --muted:      #616771;
  --line:       #e4e1db;
  --line-soft:  #efede8;
  /* Randfarbe beim Ueberfahren — stand vorher viermal als #d6d1c7 im Text. */
  --line-stark: #d6d1c7;
  --paper:      #ffffff;
  --paper-warm: #f7f5f1;
  --paper-deep: #101216;
  --accent:     #9a7b4f;
  /* Signalfarben — Bewertungssterne gehoeren gold, Bestaetigungen gruen.
     Vorher trug alles denselben Messington und die Seite wirkte einfarbig. */
  --gold:       #e8a317;
  --gold-tief:  #b57d0a;
  --gold-soft:  #fdf4e3;
  --gruen:      #2f7d52;
  --accent-deep:#7d6340;
  --accent-soft:#f1ebe1;
  /* Fehlermeldungen und Feldrand im Fehlerfall: 6,54 : 1 auf Weiß, 6,0 : 1 auf --paper-warm.
     Stand vorher als var(--fehler) auf sich selbst und war damit ohne Wert. */
  --fehler:     #b3261e;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Hoehe der fixierten Kopfleiste. Jede Seite, die oben beginnt, rechnet damit;
     der Wert stand vorher neunmal einzeln im Stylesheet.
     --header-bar-h ist die Navigationsleiste selbst, --header-h der gesamte
     Versatz nach oben. Ab 72rem kommt die Kopfzeile (.topbar) dazu, dann sind
     die beiden Werte NICHT mehr gleich — siehe Abschnitt 5a. */
  --header-bar-h: 4.4rem;
  --header-h: var(--header-bar-h);

  /* Abstand zwischen Abschnitten (.section, Ende des Exposé-Kopfs) */
  --abschnitt-y: clamp(2.75rem, 5.5vw, 4.5rem);
  --radius-sm: 0.5rem;
  --radius-md: 0.875rem;
  --radius-lg: 1.25rem;
  --radius-xl: 1.75rem;
  --radius-pill: 9999px;

  --container: 74rem;
  --container-narrow: 46rem;
  --gutter: 1.25rem;

  --shadow-sm: 0 1px 2px rgba(21, 23, 27, .05), 0 4px 14px rgba(21, 23, 27, .05);
  --shadow-md: 0 2px 6px rgba(21, 23, 27, .06), 0 18px 40px rgba(21, 23, 27, .09);
  --shadow-lg: 0 30px 70px rgba(21, 23, 27, .16);

  --ease: cubic-bezier(.22, .61, .36, 1);
  --t-fast: .18s var(--ease);
  --t-base: .32s var(--ease);

  /* z-Skala — Reihenfolge ist nicht beliebig:
     Header ÜBER dem Drawer (er trägt den Schließen-Knopf),
     Drawer ÜBER dem Cookie-Banner. */
  --z-cookie: 120;
  --z-nav-mobile: 130;
  --z-header: 140;
  --z-toast: 210;
}

/* ---------- 1. RESET & BASIS ---------- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
  /* Aus --header-h abgeleitet, nicht fest: mit der Kopfzeile ab 72rem waere
     ein starrer Wert zu klein und Ankerziele landeten hinter dem Header. */
  scroll-padding-top: calc(var(--header-h) + 1.1rem);
}
/* Weiches Scrollen erst NACH dem initialen Ankersprung (JS setzt die Klasse),
   sonst fährt index.html#footer sichtbar durch die ganze Seite. */
html.smooth-scroll { scroll-behavior: smooth; }

body {
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink-soft);
  background: var(--paper);
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
img { background: var(--paper-warm); }

a { color: inherit; text-decoration: none; }
button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

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

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

/* ---------- 2. TYPOGRAFIE & HILFSKLASSEN ---------- */
h1, h2, h3, h4 {
  color: var(--ink);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.022em;
  text-wrap: balance;
  /* Bewusst NICHT overflow-wrap:anywhere — das zerreißt deutsche Komposita.
     hyphens ebenfalls NICHT auto: das trennte "Premium-Mehrfami-lienhaus" und
     "erfolgrei-che" mitten im Wort. Komposita brechen am Bindestrich von selbst. */
  overflow-wrap: break-word;
  hyphens: manual;
}
h1 { font-size: clamp(2.1rem, 6.4vw, 3.9rem); }
/* Unter 20 rem (320-px-Handy mit Zoom, 288 px) etwas kleiner: „Immobilienmakler“ maß mit 2,1 rem 259 px bei 240 px
   Platz, brach mitten im Wort oder schob den Seitenkopf über den Rand (T11). Mit 1,8 rem passt jedes Wort der h1 bis
   auf „Datenschutzerklärung“ und „Maisonettewohnung“, die ein weiches Trennzeichen tragen. */
@media (max-width: 19.99rem) { h1 { font-size: 1.8rem; } }
/* Weiche Trennzeichen (&shy;) in langen Wörtern wirken nur unter 375 px. Darüber passt jedes Wort, und die
   ausgeglichenen Zeilen (text-wrap: balance) sollen dort nicht trennen. */
@media (min-width: 23.4375rem) { h1, h2, h3, h4 { hyphens: none; } }
/* Ausnahme: „Entwicklungsgrundstück“ passt auch über 375 px weder in die h1 noch in die schmale Objektkarte
   der Startseite (dort wurde es abgeschnitten). Solche Überschriften tragen .trennbar; das Trennzeichen wirkt
   nur, wenn das Wort nicht in die Zeile passt. */
h1.trennbar, h2.trennbar, h3.trennbar { hyphens: manual; }
h2 { font-size: clamp(1.7rem, 4.2vw, 2.65rem); }
h3 { font-size: clamp(1.15rem, 2.2vw, 1.4rem); line-height: 1.25; }
h4 { font-size: 1.03rem; }

p, li, dd, figcaption { overflow-wrap: anywhere; }

.lead + .lead { margin-top: .8rem; }
.lead {
  font-size: clamp(1.05rem, 2vw, 1.24rem);
  line-height: 1.6;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.eyebrow {
  display: inline-block;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin-bottom: 1rem;
}
.eyebrow--light { color: var(--accent); }

.num { font-variant-numeric: tabular-nums; }
.center { text-align: center; }
.mt-1 { margin-top: .5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.75rem; }
.mt-4 { margin-top: 2.5rem; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* ---------- 3. LAYOUT ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--container-narrow); }

.section { padding-block: var(--abschnitt-y); }
.section--warm { background: var(--paper-warm); }
.section--dark {
  background: var(--paper-deep);
  color: #c9ccd3;
}
/* Dunkler Abschnitt: ALLE Textelemente durchdeklarieren. h4 erbte sonst die
   dunkle Grundfarbe und wurde auf schwarzem Grund praktisch unsichtbar. */
.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4,
.section--dark strong,
.section--dark dt { color: #fff; }
.section--dark p,
.section--dark li,
.section--dark dd,
.section--dark .lead { color: #c9ccd3; }
.section--dark .form-note,
.section--dark figcaption { color: #9aa0aa; }
.section--dark .eyebrow { color: var(--accent); }
.section--dark a:not(.btn) { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.section--dark .card {
  background: rgba(255,255,255,.05);
  border-color: rgba(255,255,255,.14);
}
.section--dark .card:hover { border-color: rgba(255,255,255,.3); box-shadow: none; }
.section--dark .card-icon { background: #fff; color: var(--accent-deep); }
.section--dark .kontakt-liste svg { color: var(--accent); }
.section--dark .rule { background: rgba(255,255,255,.14); }
.section--tight { padding-block: clamp(2rem, 3.5vw, 2.75rem); }
/* Direkt nach dem Hero: dessen unterer Abstand reicht bereits. */
.hero + .section--tight { padding-top: clamp(.75rem, 1.5vw, 1.25rem); }

/* Der Header ist fixiert (--header-h) — die erste Sektion einer Seite muss
   das ausgleichen. .hero, .seitenkopf, .legal, .expose-hero und .page-404
   bringen ihren eigenen calc() mit; Seiten, die schlicht mit .section starten,
   hatten nur clamp(3.5rem, 8vw, …) und damit unter 880 px Breite zu wenig:
   Die Überschrift lag hinter dem Header. Betraf Kontakt, Objektübersicht,
   Verkaufen, Renditerechner und Über uns. */
main > .section:first-child { padding-top: calc(var(--header-h) + clamp(2rem, 5vw, 3.5rem)); }

.section-head { max-width: 44rem; margin-bottom: clamp(1.5rem, 2.5vw, 2.25rem); }
.section-head--center { margin-inline: auto; text-align: center; }

.grid { display: grid; gap: 1.25rem; }
.grid > * { min-width: 0; }

.rule {
  height: 1px;
  background: var(--line);
  border: 0;
}

/* ---------- 4. BUTTONS & FORMULARE ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .7rem 1.35rem;
  border-radius: var(--radius-pill);
  font-size: .9rem;
  /* Jeder Knopf traegt denselben 1-px-Rahmen — auch der gefuellte, dort
     unsichtbar. Ohne das ist ein umrandeter Knopf exakt 2 px hoeher als der
     gefuellte daneben und kein Knopfpaar der Seite fluchtet. */
  border: 1px solid transparent;
  min-height: 3rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-align: center;
  touch-action: manipulation;
  transition: background-color var(--t-fast), color var(--t-fast),
              border-color var(--t-fast), transform var(--t-fast),
              box-shadow var(--t-fast);
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 1.05em; height: 1.05em; flex: none; }

.btn--primary { background: var(--ink); color: #fff; }
.btn--primary:hover { background: #000; box-shadow: var(--shadow-md); }

/* --accent traegt Weiss nur mit 3,95:1 — unter der AA-Schwelle von 4,5:1.
   --accent-deep liefert 5,63:1 bei gleicher Farbfamilie. */
.btn--accent { background: var(--accent-deep); color: #fff; }
.btn--accent:hover { background: var(--accent-deep); box-shadow: var(--shadow-md); }

.btn--ghost {
  border: 1px solid var(--line);
  color: var(--ink);
  background: var(--paper);
}
.btn--ghost:hover { border-color: var(--ink); }

.btn--auf-dunkel {
  border: 1px solid rgba(255,255,255,.28);
  color: #fff;
}
.btn--auf-dunkel:hover { border-color: #fff; background: rgba(255,255,255,.08); }

.btn--sm { padding: .6rem 1.1rem; font-size: .87rem; }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; }
/* Zentrierte Knopfreihen: justify-content allein zentriert nur in Zeilenrichtung.
   Sobald die Knoepfe umbrechen oder stapeln, braucht es align-items — sonst stand
   der eine Knopf links und der andere mittig. */
@media (max-width: 30rem) {
  /* Auf schmalen Geraeten stapeln die Knoepfe; unterschiedlich breite Knoepfe
     mit nicht fluchtenden Kanten sehen nach Versehen aus. */
  .btn-row { flex-direction: column; align-items: stretch; }
  .btn-row > .btn { width: 100%; justify-content: center; }
}

.field { display: grid; gap: .4rem; margin-bottom: 1rem; }
.field label { font-size: .84rem; font-weight: 600; color: var(--ink); }
.field input, .field textarea, .field select {
  width: 100%;
  padding: .8rem .95rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(154,123,79,.16);
}
.field textarea { min-height: 8rem; resize: vertical; }
.field-error {
  display: none;
  font-size: .8rem;
  color: var(--fehler);
}
.field.is-invalid input,
.field.is-invalid textarea { border-color: var(--fehler); }
.field.is-invalid .field-error { display: block; }

.check {
  display: flex;
  gap: .65rem;
  align-items: flex-start;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--muted);
  margin-bottom: 1.1rem;
}
.check input { width: 1.05rem; height: 1.05rem; margin-top: .2rem; flex: none; accent-color: var(--accent); }
.check a { text-decoration: underline; text-underline-offset: 2px; }

/* Honeypot — für Menschen unsichtbar, für Bots verlockend */
.hp {
  position: absolute !important;
  left: -9999px;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.form-note { font-size: .8rem; color: var(--muted); }

/* ---------- 5. HEADER & NAVIGATION ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  background: rgba(255,255,255,.82);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-base), box-shadow var(--t-base), background-color var(--t-base);
}
.site-header.is-scrolled {
  border-bottom-color: var(--line);
  box-shadow: 0 1px 20px rgba(21,23,27,.06);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  /* Bewusst --header-bar-h, nicht --header-h: sonst waere die Navigationsleiste
     ab 72rem so hoch wie Kopfzeile und Leiste zusammen. */
  min-height: var(--header-bar-h);
}

/* Ab 64rem schrumpft das Logo nicht (siehe unten, sonst lief der Schriftzug bei 1.024 px unter das Menü).
   Darunter darf es schrumpfen, damit die Notbremse des Namens greift statt die Knöpfe aus dem Bild zu schieben. */
.brand { display: flex; align-items: center; gap: .7rem; min-width: 0; min-height: 44px; position: relative; isolation: isolate; }
/* Hinter Logo und Name bleibt der Grund weiß und läuft nach außen weich aus, ohne Rahmen und Schatten (Leonard,
   16.10.2026). Das Logo-Bild hat selbst einen weißen Grund; über Bildern und dunklen Abschnitten wurde der leicht
   durchsichtige Kopf grau, und das Bild stand als eckiges Feld darin. Der weiche Rand ist ein Schein (box-shadow);
   clip-path schneidet ihn an Ober- und Unterkante der Kopfleiste ab, damit er weder die dunkle Kopfzeile noch die
   Seite darunter aufhellt. */
.brand::before {
  content: "";
  position: absolute;
  left: -4px; right: -4px; top: 50%;
  height: 2.5rem;
  transform: translateY(-50%);
  z-index: -1;
  background: var(--paper);
  border-radius: 8px;
  box-shadow: 0 0 12px 6px var(--paper);
  clip-path: inset(calc((2.5rem - var(--header-bar-h)) / 2) -2rem);
  pointer-events: none;
}
.brand img { width: 2.3rem; height: auto; }
/* Der Name bleibt auf jeder Breite ganz (T12, Leonard 09.10.2026). Notbremse nur, damit er nie unter die Knöpfe
   läuft: höchstens zwei Zeilen, dann „…“. Greift sie, meldet layout-check einen FEHLER. 2 px Polster links,
   damit der Beschnitt den ersten Buchstaben nicht anschneidet; der Text steht unverändert. */
.brand-text {
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-inline-start: -2px;
  padding-inline-start: 2px;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.2;
}

.nav-desktop { display: none; }
.nav-desktop > ul { display: flex; align-items: center; gap: .1rem; list-style: none; }
.nav-desktop a,
.nav-desktop .nav-toggle {
  display: flex;
  align-items: center;
  gap: .3rem;
  padding: .5rem .7rem;
  border-radius: var(--radius-pill);
  font-size: .88rem;
  font-weight: 500;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: color var(--t-fast), background-color var(--t-fast);
}
.nav-desktop a:hover,
.nav-desktop .nav-toggle:hover { color: var(--ink); background: var(--paper-warm); }
.nav-desktop a[aria-current="page"],
.nav-desktop .nav-toggle.is-active { color: var(--ink); background: var(--accent-soft); }

/* Untermenü — klappt per Hover und per Tastatur/Klick auf */
.hat-untermenue { position: relative; }
.nav-pfeil {
  width: .38rem; height: .38rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform var(--t-fast);
}
.nav-toggle[aria-expanded="true"] .nav-pfeil { transform: rotate(-135deg) translate(-1px, -1px); }
.untermenue {
  position: absolute;
  top: calc(100% + .5rem);
  left: 0;
  min-width: 13rem;
  padding: .4rem;
  list-style: none;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
}
.hat-untermenue:hover .untermenue,
.hat-untermenue:focus-within .untermenue,
.untermenue.is-open { opacity: 1; visibility: visible; transform: none; }
.untermenue a { border-radius: var(--radius-sm); padding: .55rem .7rem; }

.header-actions { display: flex; align-items: center; gap: .5rem; flex: none; position: relative; z-index: 1; }
/* position/z-index: Der weiße Schein hinter dem Logo (.brand::before) liegt sonst bei 320 px mit großer Schrift über
   dem Rand des Anruf-Knopfs. */
/* Der Anruf-Knopf im Kopf bleibt inhaltsbreit. Ohne dies griff auf dem Handy die
   Regel `.btn { width: 100% }` und quetschte den Burger daneben zur Pille. */
.header-actions .btn { width: auto; flex: none; }
/* Handy: Anruf-Knopf nur mit Hörer (48 × 48 px, rund), die Beschriftung bleibt für Vorleseprogramme (T12).
   Muster wie .visually-hidden, aber ohne !important. Der Hörer steht als SVG im HTML, damit der Knopf auch
   ohne script.js nicht leer ist (T20). Grenze gemessen am 10.10.2026: Name, beschrifteter Knopf und Menü-Knopf
   brauchen in einer Zeile 386 px (Systemschrift), 389 px (Arial) und 409 px (Verdana); ab 26 rem (416 px) hat
   jede davon Luft, bei großer Browserschrift (20 px) ebenso (520 px gegen 482 px). */
@media (max-width: 25.99rem) {
  .header-actions .kopf-anruf { width: 48px; height: 48px; min-height: 48px; padding: 0; }
  .header-actions .kopf-anruf svg { width: 20px; height: 20px; }
  .kopf-knopf-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}
/* 320-px-Handys (unter 22,5 rem) und Zoom bis 288 px (unter 20 rem): Logo und Abstände kleiner, unter 20 rem
   auch der Name, damit er ganz bleibt (T12). In px, damit eine große Browserschrift nur den Namen vergrößert.
   Gemessen bis 288 px mit Systemschrift, Arial und Roboto, bei Schrift 20 ab 320 px. */
@media (max-width: 22.49rem) {
  .header-inner { gap: 12px; }
  .brand { gap: 8px; }
  .brand img { width: 32px; }
  .header-actions { gap: 6px; }
}
@media (max-width: 19.99rem) {
  .header-inner { gap: 8px; }
  .brand { gap: 6px; }
  .brand img { width: 28px; }
  .brand-text { font-size: .7rem; letter-spacing: .1em; }
}
/* Unter 18 rem (280-px-Klappdisplay) 2 px enger, unter 16 rem (288 bis 319 px mit großer Browserschrift)
   der Name kleiner mit wenig Laufweite, damit er ganz bleibt (T12). */
@media (max-width: 17.99rem) {
  .header-inner { gap: 6px; }
}
@media (max-width: 15.99rem) {
  .brand-text { font-size: .6rem; letter-spacing: .02em; }
}
/* Unter 14,5 rem (280 px mit großer Browserschrift) fehlten dem Namen 3,7 px: Logo 24 px, Name ohne Laufweite (T12). */
@media (max-width: 14.49rem) {
  .brand img { width: 24px; }
  .brand-text { letter-spacing: 0; }
}

.burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem; height: 2.6rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  color: var(--ink);
  touch-action: manipulation;
  /* aspect-ratio haelt den Knopf rund, auch wenn der Platz eng wird */
  aspect-ratio: 1;
  flex: none;
}
.burger:hover { border-color: var(--ink); }
.burger svg { width: 1.25rem; height: 1.25rem; }

/* ---------- 5a. KOPFZEILE (nur Desktop) ----------
   Adressen beider Standorte, Kontaktdaten und die Kanäle über der Navigation.
   Sie gehoert zum fixierten Header, deshalb waechst --header-h um ihre Hoehe
   mit — sonst laege die erste Ueberschrift jeder Seite dahinter.

   Warum erst ab 72rem und nicht ab 64rem (wo die Desktop-Navigation beginnt):
   Die Zeile traegt zwei ausgeschriebene Adressen, Telefon, E-Mail und drei
   Symbole; das sind gemessen 1.012 px Inhalt, mit den 4 rem Aussenabstand also
   rund 1.076 px. Bei 64rem stehen nur 960 px zur Verfuegung — sie wuerde
   umbrechen und den Header hoeher machen, als --header-h annimmt. Die Adressen
   werden bewusst NICHT abgekuerzt: sie muessen mit den strukturierten Daten und
   dem Impressum wortgleich sein (NAP-Konsistenz fuer die lokale Suche). */
.topbar { display: none; }

@media (min-width: 72rem) {
  :root { --header-h: calc(var(--header-bar-h) + 2.2rem); }

  .topbar {
    display: block;
    background: var(--paper-deep);
    color: #c9ccd3;
    font-size: .78rem;
    /* Faehrt beim Scrollen ein. --header-h bleibt auf der vollen Hoehe: Der
       Wert haelt oben auf der Seite Platz frei, und genau dort ist die Zeile
       ausgefahren. Weiter unten schadet der zusaetzliche Platz nicht.
       max-height statt height, weil der Inhalt keine feste Hoehe hat;
       prefers-reduced-motion setzt alle Uebergaenge ohnehin auf 0. */
    overflow: hidden;
    max-height: 2.2rem;
    transition: max-height var(--t-base), opacity var(--t-fast);
  }
  .site-header.is-scrolled .topbar { max-height: 0; opacity: 0; }
  .topbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    min-height: 2.2rem;
  }
  .topbar-orte,
  .topbar-kontakt { list-style: none; display: flex; align-items: center; gap: 1.25rem; }
  .topbar li { display: flex; align-items: center; gap: .4rem; white-space: nowrap; }
  .topbar svg { width: .88rem; height: .88rem; color: var(--accent); flex: none; }
  .topbar a { color: inherit; display: inline-flex; align-items: center; gap: .4rem; }
  .topbar a:hover { color: #fff; text-decoration: underline; text-underline-offset: 3px; }

  .topbar-rechts { display: flex; align-items: center; gap: 1.5rem; }
  .topbar-social { display: flex; align-items: center; gap: .7rem; }
  .topbar-social a:hover { text-decoration: none; }
  .topbar-social svg { width: 1rem; height: 1rem; color: #c9ccd3; transition: color var(--t-fast); }
  .topbar-social a:hover svg { color: #fff; }
}

/* ---------- 6. MOBILE-DRAWER ---------- */
/* Liegt als Geschwister neben <header> im <body>: der backdrop-filter des
   Headers würde ein fixed-Kind auf Headergröße einsperren. */
/* Abgedunkelter Hintergrund — die Seite bleibt dahinter sichtbar.
   Das Menü selbst ist eine schwebende Karte darauf, nicht die ganze Fläche. */
.nav-mobile {
  position: fixed;
  inset: 0;
  z-index: var(--z-nav-mobile);
  background: rgba(16, 18, 22, .55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  /* flex-start + margin:auto an der Karte — zentriert bei kurzem Menü,
     scrollt sauber ab Überlänge, statt oben abzuschneiden. */
  display: flex;
  justify-content: flex-start;
  padding: calc(var(--header-h) + .5rem) 1rem calc(1rem + env(safe-area-inset-bottom));
  overscroll-behavior: contain;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-base), visibility 0s linear .32s;
}
/* Beim Öffnen sofort sichtbar, damit der Fokus auf den ersten Eintrag gehen kann (T13) */
.nav-mobile.is-open { opacity: 1; visibility: visible; transition: opacity var(--t-base), visibility 0s; }

.nav-mobile-inner {
  margin: auto;          /* die eigentliche Zentrierung */
  width: 100%;
  max-width: 24rem;
  padding: 1.4rem 1.25rem 1.6rem;
  text-align: center;
  background: var(--paper);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  transform: scale(.97);
  transition: transform var(--t-base);
}
.nav-mobile.is-open .nav-mobile-inner { transform: none; }

.nav-mobile ul { list-style: none; display: grid; gap: .05rem; }

/* Bewusst eng auf Listenelemente gescopt — ein breites `.nav-mobile a`
   würde die Knöpfe darunter zerlegen. */
.nav-mobile ul a {
  display: block;
  padding: .5rem .25rem;
  font-size: .98rem;
  font-weight: 500;
  color: var(--ink-soft);
}
.nav-mobile ul a:hover,
.nav-mobile ul a[aria-current="page"] { color: var(--accent-deep); }
.nav-mobile-inner > ul > li > a {
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--ink);
  padding-block: .65rem;
}

/* Ausklappbare Gruppe im mobilen Menü */
.mobil-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  width: 100%;
  padding: .65rem .25rem;
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--ink);
  touch-action: manipulation;
}
.mobil-toggle .nav-pfeil {
  border-color: var(--accent);
  border-width: 1.8px;
}
.mobil-toggle[aria-expanded="true"] .nav-pfeil { transform: rotate(-135deg) translate(-1px, -1px); }
/* grid-template-rows 0fr→1fr animiert das Aufklappen ohne feste Höhe */
.mobil-untermenue {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--t-base);
}
.mobil-untermenue > ul { overflow: hidden; min-height: 0; }
.mobil-gruppe.is-open .mobil-untermenue { grid-template-rows: 1fr; }
.mobil-untermenue ul { padding-bottom: .5rem; }

.nav-mobile .btn-row {
  margin-top: 1.5rem;
  flex-direction: column;
  align-items: stretch;
}

/* ---------- 7. HERO ---------- */
.hero {
  padding-top: calc(var(--header-h) + clamp(2.5rem, 7vw, 5rem));
  padding-bottom: clamp(2.5rem, 6vw, 4.5rem);
  background: linear-gradient(180deg, var(--paper-warm) 0%, var(--paper) 100%);
}
.hero-grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: center; }
.hero h1 { margin-bottom: 1.1rem; }
.hero .lead { max-width: 34rem; }
.hero .btn-row { margin-top: 1.9rem; }
.hero-media { position: relative; }
.hero-media img {
  width: 100%;
  /* Das Hausbild ist 820 × 549 px. Größer als die Datei wird es nirgends gezeigt (G9):
     am Handy 4:3, ab 64 rem 6:5 in der breiteren Bildspalte (Leonard, 13.10.2026:
     „hero bild bitte größer machen“). */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
}
/* Bei großer Browserschrift wird die Bildspalte breiter; der Zuschnitt vergrößerte das Bild dann über die Datei
   hinaus (T9). Höchstbreite so, dass die Bildhöhe 549 px nicht übersteigt: 4:3 → 732 px, ab 64 rem 6:5 → 659 px. */
.hero-media img { max-width: 732px; }
/* Google-Bewertung direkt unter den Knöpfen (Güney Nil, 13.10.2026), rechts daneben das Telefon als Knopf, auch am
   Handy (Leonard, 13.10.2026), damit die Nummer im ersten Bildschirm bleibt (G7, verkaufstexte A3). Unter 22,5 rem
   reicht die Breite nicht für beide; dann steht der Knopf in voller Breite darunter. */
.hero-belege { margin-top: 1.25rem; display: flex; flex-wrap: wrap; align-items: stretch; gap: .5rem; }
.hero-belege .hero-badge { flex: 1 1 9rem; min-width: 0; }
.hero-anruf {
  flex: 0 0 auto;
  touch-action: manipulation;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: .35rem;
  min-height: 2.75rem;
  padding: .7rem .95rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  color: var(--ink);
  transition: border-color var(--t-base), transform var(--t-fast);
}
.hero-anruf:hover { border-color: var(--ink); }
.hero-anruf:active { transform: translateY(1px); }
.hero-anruf svg { width: 2.1rem; height: 2.1rem; padding: .5rem; border-radius: 50%; background: var(--ink); color: #fff; flex: none; }
.hero-anruf-text { display: grid; gap: .1rem; }
.hero-anruf-label { font-size: .76rem; font-weight: 500; color: var(--ink); }
.hero-anruf-nummer { font-size: .95rem; font-weight: 700; color: var(--ink); white-space: nowrap; }
/* Am Handy etwas weniger Innenabstand, damit Note, Sterne und Anzahl neben dem Knopf in zwei Zeilen passen. */
@media (max-width: 39.99rem) {
  .hero-belege .hero-badge { padding: .65rem .8rem; }
  .hero-belege .hero-badge-kopf { column-gap: .35rem; }
  .hero-belege .stars svg { width: .82rem; height: .82rem; }
  .hero-anruf { padding-inline: .8rem; }
}
@media (max-width: 22.49rem) {
  .hero-anruf { flex: 1 0 100%; min-width: 0; flex-direction: row; align-items: center; gap: .7rem; }
  /* Bei großer Browserschrift darf die Nummer umbrechen, sonst erzwingt sie seitliches Scrollen (T11). */
  .hero-anruf-nummer { white-space: normal; }
}
@media (min-width: 40rem) {
  .hero-belege .hero-badge { flex: 0 1 auto; }
  .hero-anruf { flex: 0 0 auto; flex-direction: row; align-items: center; gap: .7rem; padding-inline: 1rem 1.3rem; }
}
/* Ab 64 rem ist die Textspalte bei 1.024 bis 1.119 px schmaler als Plakette und Knopf zusammen: nicht umbrechen,
   sondern die Plakette schmaler werden lassen; ihr Kopf bricht dann selbst um. */
@media (min-width: 64rem) {
  .hero-belege { flex-wrap: nowrap; }
  .hero-belege .hero-badge { min-width: 0; }
}
.hero-badge {
  display: grid;
  width: fit-content;
  max-width: 100%;
  align-items: start;
  gap: .5rem;
  padding: .7rem 1.05rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.hero-badge strong { display: block; color: var(--ink); font-size: 1.05rem; }
.hero-badge span { font-size: .76rem; color: var(--muted); }
.stars { display: flex; gap: .1rem; color: var(--gold); }
.stars svg { width: .95rem; height: .95rem; }

/* ---------- 8. VERTRAUENSLEISTE ---------- */
.trustbar { border-block: 1px solid var(--line); background: var(--paper); }
.trustbar ul {
  list-style: none;
  display: grid;
  gap: 1.1rem;
  padding-block: 1.6rem;
}
.trustbar li { display: flex; gap: .7rem; align-items: flex-start; font-size: .9rem; }
.trustbar svg { width: 1.15rem; height: 1.15rem; color: var(--accent); flex: none; margin-top: .15rem; }
.trustbar strong { display: block; color: var(--ink); }

/* ---------- 9. KARTEN ---------- */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.6rem;
  transition: border-color var(--t-base), box-shadow var(--t-base), transform var(--t-base);
}
.card:hover { border-color: var(--line-stark); box-shadow: var(--shadow-sm); }
.card h3 { margin-bottom: .5rem; }
.card p { font-size: .94rem; }
.card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.85rem; height: 2.85rem;
  margin-bottom: 1.1rem;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--accent-deep);
}
.card-icon svg { width: 1.35rem; height: 1.35rem; }
.card-link {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin-top: 1rem;
  font-size: .89rem;
  font-weight: 600;
  color: var(--accent-deep);
}
.card-link svg { width: .95rem; height: .95rem; transition: transform var(--t-fast); }
.card:hover .card-link svg { transform: translateX(3px); }

/* Ablauf-Schritte */
.step { display: flex; gap: 1.1rem; }
.step-num {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.4rem; height: 2.4rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--accent);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: .92rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.step h3 { font-size: 1.05rem; margin-bottom: .3rem; }
.step p { font-size: .92rem; }

/* Kundenstimmen: siehe Abschnitt 20 (.stimme) */

/* ---------- 10. OBJEKTE ---------- */
.filterbar {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 1.75rem;
}
.chip {
  padding: .5rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--paper);
  font-size: .87rem;
  font-weight: 500;
  color: var(--ink-soft);
  touch-action: manipulation;
  transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.chip:hover { border-color: var(--ink); color: var(--ink); }
.chip[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
.filter-count { font-size: .87rem; color: var(--muted); margin-bottom: 1.25rem; }

.objekt {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color var(--t-base), box-shadow var(--t-base), transform var(--t-base);
}
.objekt:hover { border-color: var(--line-stark); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.objekt.is-hidden { display: none; }
.objekt-media { position: relative; overflow: hidden; background: var(--paper-warm); }
.objekt-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  transition: transform .5s var(--ease);
}
.objekt:hover .objekt-media img { transform: scale(1.03); }
.objekt-tag {
  position: absolute;
  top: .8rem; left: .8rem;
  padding: .3rem .7rem;
  border-radius: var(--radius-pill);
  background: rgba(21,23,27,.86);
  color: #fff;
  font-size: .71rem;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.objekt-body { display: flex; flex-direction: column; flex: 1; padding: 1.25rem 1.35rem 1.45rem; }
.objekt-ort {
  display: flex; align-items: center; gap: .35rem;
  font-size: .82rem; color: var(--muted); margin-bottom: .45rem;
}
.objekt-ort svg { width: .9rem; height: .9rem; flex: none; }
.objekt h3 { font-size: 1.08rem; margin-bottom: .7rem; }
.objekt-meta {
  display: flex; flex-wrap: wrap; gap: .4rem .9rem;
  font-size: .84rem; color: var(--muted);
  padding-top: .85rem; margin-top: auto;
  border-top: 1px solid var(--line-soft);
}
.objekt-meta span { display: inline-flex; align-items: center; gap: .3rem; }
.objekt-meta svg { width: .9rem; height: .9rem; }
.objekt-preis {
  font-size: 1.22rem;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.objekt-preis small { font-size: .78rem; font-weight: 500; color: var(--muted); }
/* Verkaufte Objekte: Marke unten links im Bild (oben links steht die Objektart, auf
   schmalen Karten passen beide nicht nebeneinander), „Verkauft“ statt Preis. */
.objekt-status {
  position: absolute;
  left: .8rem; bottom: .8rem;
  padding: .3rem .7rem;
  border-radius: var(--radius-pill);
  background: var(--accent-deep);
  color: #fff;
  font-size: .71rem;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.objekt-preis--verkauft { color: var(--accent-deep); }

/* Exposé-Detailseite */
/* Unten derselbe Abstand wie zwischen zwei Abschnitten; ohne ihn klebte der Hinweis „ohne Gewähr“ am nächsten
   Abschnitt (Leonard, 13.10.2026). */
.expose-hero { padding-top: calc(var(--header-h) + 1.75rem); padding-bottom: var(--abschnitt-y); }
.breadcrumb { font-size: .82rem; color: var(--muted); margin-bottom: 1.25rem; }
.breadcrumb ol { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; }
.breadcrumb li::after { content: "›"; margin-left: .4rem; color: var(--line); }
.breadcrumb li:last-child::after { content: none; }
.breadcrumb a:hover { color: var(--ink); text-decoration: underline; }

.expose-bild img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-lg);
}
/* Plakat der Firma (Baugrundstück Mosbach) und Luftbild mit eingezeichneter
   Grundstücksgrenze (Weinsberg, nur 629 px breit): Beides darf man nicht
   beschneiden — sonst fehlt der halbe Text oder die Grenze. Es steht deshalb
   vollständig und hochkant, in Lesebreite zentriert, und wird nie größer als die Datei. */
.expose-bild--plakat img {
  aspect-ratio: auto;
  object-fit: contain;
  max-width: min(30rem, 100%);
  margin-inline: auto;
  background: var(--paper-warm);
}
.expose-fakten {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin: 1.75rem 0;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.expose-fakten div { background: var(--paper); padding: 1rem 1.1rem; }
.expose-fakten > div:last-child:nth-child(odd) { grid-column: span 2; }
.expose-fakten dt {
  font-size: .73rem; font-weight: 600; letter-spacing: .06em;
  overflow-wrap: anywhere;
  text-transform: uppercase; color: var(--muted); margin-bottom: .25rem;
}
.expose-fakten dd { font-size: 1.02rem; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }

.expose-aside {
  background: var(--paper-warm);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
}
.expose-aside .objekt-preis { font-size: 1.65rem; display: block; margin-bottom: .3rem; }
/* Am Handy steht der Kasten unter dem Text; ohne Abstand stieß er an den Hinweis darüber. */
@media (max-width: 63.99rem) { .expose-aside { margin-top: 2.5rem; } }

/* ---------- 10c. BILDERGALERIE (Exposé) ----------
   Vorschaubilder im natürlichen Format, in Spalten gestapelt: nichts wird
   beschnitten, auch nicht das Zeichen eines KI-Werkzeugs in der Bildecke.
   Jedes Bild ist ein Link auf die große Datei; ohne JavaScript öffnet der
   Browser sie direkt, mit JavaScript zeigt sie ein <dialog> (script.js, 6c). */
.galerie { list-style: none; columns: 2; column-gap: .75rem; margin-top: 1rem; }
.galerie > li { break-inside: avoid; margin-bottom: .75rem; }
.galerie-bild a {
  display: block;
  overflow: hidden;
  border-radius: var(--radius-md);
  cursor: zoom-in;
  touch-action: manipulation;
}
.galerie-bild img { width: 100%; transition: transform var(--t-base); }
.galerie-bild a:hover img { transform: scale(1.03); }
/* Pflichthinweis direkt am Bild (Art. 50 Abs. 4 KI-VO, § 5 UWG): 4,75 : 1 */
.ki-hinweis {
  display: inline-block;
  margin-top: .4rem;
  padding: .2rem .6rem;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: .76rem;
  font-weight: 600;
  line-height: 1.35;
}
@media (min-width: 40rem) { .galerie { columns: 3; } }

/* Großansicht: der Dialog füllt den Schirm, das Bild passt sich ein. */
.galerie-dialog {
  margin: 0;
  padding: 0;
  border: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  background: transparent;
  overflow: hidden;
  overscroll-behavior: contain;
}
.galerie-dialog[open] { display: flex; align-items: center; justify-content: center; }
.galerie-dialog::backdrop { background: rgba(16, 18, 22, .94); }
.galerie-dialog-buehne {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .55rem;
  max-width: 100%;
  max-height: 100%;
  padding: 4.25rem 1rem 1.25rem;
}
.galerie-dialog-bild {
  max-width: min(100%, 1400px);
  max-height: calc(100vh - 12rem);
  max-height: calc(100dvh - 12rem);
  border-radius: var(--radius-md);
  background: transparent;
}
.galerie-dialog-unterschrift { display: flex; flex-direction: column; align-items: center; gap: .3rem; text-align: center; }
.galerie-dialog-text { color: #fff; font-size: .92rem; max-width: 40rem; }
.galerie-dialog-zaehler { color: #c9ccd3; font-size: .8rem; font-variant-numeric: tabular-nums; }
.galerie-dialog .ki-hinweis { margin-top: 0; }
.galerie-knopf {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, .94);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
  touch-action: manipulation;
}
.galerie-knopf:hover { background: #fff; }
.galerie-knopf:active { transform: scale(.96); }
.galerie-knopf svg { width: 1.4rem; height: 1.4rem; }
.galerie-knopf--zu { top: 1rem; right: 1rem; }
.galerie-knopf--zurueck { left: .75rem; top: 50%; margin-top: -1.5rem; }
.galerie-knopf--weiter { right: .75rem; top: 50%; margin-top: -1.5rem; }
.galerie-dialog [hidden] { display: none; }
/* Seite hinter der Großansicht scrollt nicht mit */
html.galerie-offen { overflow: hidden; }

/* ---------- 10b. BEWERTUNGSRECHNER (Klick zum Laden) ----------
   Der fremde Rahmen wird erst nach dem Klick geladen. Bis dahin steht hier
   eine einladende Fläche statt eines gesperrten Hinweiskastens. */
.bewertung-tool {
  background: var(--accent-soft);
  border: 1px solid #e5dbc9;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.bewertung-facade { padding: 1.1rem 1.25rem; text-align: center; }
.bewertung-facade .card-icon { background: var(--paper); margin-bottom: .7rem; }
.bewertung-facade h3 { font-size: clamp(1.1rem, 2.2vw, 1.3rem); margin-bottom: .35rem; }
.bewertung-facade p { max-width: 40rem; margin-inline: auto; font-size: .92rem; }
.bewertung-facade .btn { margin-top: .9rem; }
.bewertung-facade .form-note { margin-top: .7rem; font-size: .76rem; }
/* Ab Tablet eine flache Zeile: Symbol, Text, Knopf nebeneinander. Als hoher
   Kasten nahm die Flaeche ein Drittel des ersten Schirms ein, obwohl der
   Rechner selbst erst nach dem Klick erscheint. */
@media (min-width: 48rem) {
  .bewertung-facade {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: .35rem 1.25rem;
    text-align: left;
    padding: 1.1rem 1.4rem;
  }
  .bewertung-facade .card-icon { margin-bottom: 0; grid-row: 1 / span 2; }
  .bewertung-facade .bewertung-text { min-width: 0; }
  .bewertung-facade p { margin-inline: 0; }
  /* Der Knopf stand in der ersten Zeile und damit oben rechts; über beide Zeilen
     gespannt sitzt er senkrecht in der Mitte des Kastens (Leonard, 09.10.2026). */
  .bewertung-facade .btn { margin-top: 0; white-space: nowrap; width: auto; grid-column: 3; grid-row: 1 / span 2; }
  .bewertung-facade .form-note { grid-column: 2; margin-top: 0; }

  /* Steht die Kachel in einer halben Rasterspalte (Verkaufen: rund 480 px),
     bleiben fuer den Text zwischen Symbol und Knopf keine 200 px. Dort bleibt
     die gestapelte Fassung — die Medienabfrage kennt nur den Schirm, nicht die
     Spalte, in der die Kachel tatsaechlich sitzt. */
  .bewertung-tool--schmal .bewertung-facade {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    gap: 0;
  }
  .bewertung-tool--schmal .bewertung-facade .card-icon { margin-bottom: .7rem; grid-row: auto; }
  .bewertung-tool--schmal .bewertung-facade p { margin-inline: auto; }
  .bewertung-tool--schmal .bewertung-facade .btn { margin-top: .9rem; grid-column: 1; grid-row: auto; }
  .bewertung-tool--schmal .bewertung-facade .form-note { grid-column: 1; margin-top: .7rem; }
}
.bewertung-tool.is-geladen { background: var(--paper); border-color: var(--line); }
/* Nach dem Klick klappt der Rechner auf seine volle Arbeitshoehe auf — die
   flache Flaeche davor ist nur die Einladung, nicht das Werkzeug. */
.bewertung-rahmen {
  display: block;
  width: 100%;
  min-height: 32rem;
  border: 0;
  animation: aufklappen .45s var(--ease);
}
@media (min-width: 48rem) { .bewertung-rahmen { min-height: 44rem; } }
@keyframes aufklappen {
  from { opacity: 0; max-height: 9rem; }
  to   { opacity: 1; max-height: 60rem; }
}

/* ---------- 11. FAQ ---------- */
.faq { display: grid; gap: .65rem; }
.faq details {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.faq details[open] { border-color: var(--line-stark); box-shadow: var(--shadow-sm); }
.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem 1.25rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
  touch-action: manipulation;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  flex: none;
  width: .7rem; height: .7rem;
  margin-top: .35rem;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform var(--t-fast);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq .faq-body { padding: 0 1.25rem 1.25rem; }
.faq .faq-body p + p { margin-top: .75rem; }
.faq .faq-body strong { color: var(--ink); }

/* ---------- 12. KONTAKT & FOOTER ---------- */
.kontakt-grid { display: grid; gap: 2.25rem; align-items: start; }
.kontakt-karte {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
}
/* Der Abstand zwischen gestapelten Karten gehoert dem Elternteil (gap).
   Als margin-top schob er im Raster die zweite Karte 16 px nach unten —
   nebeneinander stehende Kaesten fluchteten dadurch nicht. */
.kontakt-karte + .kontakt-karte { margin-top: 1rem; }
.grid > .kontakt-karte + .kontakt-karte,
.grid .kontakt-karte { margin-top: 0; }
.kontakt-karte h3 { font-size: 1rem; margin-bottom: .55rem; }
/* Formular-Ueberschrift: gleiche Groesse wie eine Kartenueberschrift, egal
   ob sie als h2 (Kontaktseite) oder h3 (Startseite) im Dokument steht. */
.kontakt-form > h2,
.kontakt-form > h3 { font-size: 1.15rem; margin-bottom: .2rem; }
.kontakt-karte address { font-style: normal; font-size: .93rem; }
.kontakt-liste { list-style: none; display: grid; gap: .6rem; margin-top: 1rem; font-size: .93rem; }
.kontakt-liste li { display: flex; align-items: flex-start; gap: .55rem; }
.kontakt-liste li > svg { margin-top: .18em; }
.kontakt-liste a { display: inline-flex; align-items: center; gap: .55rem; }
.kontakt-liste a:hover { color: var(--accent-deep); text-decoration: underline; }
.kontakt-liste svg { width: 1rem; height: 1rem; color: var(--accent); flex: none; }
/* Bestaetigungs-Haekchen gruen, damit die Liste als Zusage lesbar wird */
svg[data-icon-name="check"] { color: var(--gruen); }
svg[data-icon-name="star"] { color: var(--gold); }
svg[data-icon-name="shield-check"] { color: var(--gruen); }

.site-footer {
  background: var(--paper-deep);
  color: #9aa0aa;
  padding-block: clamp(2.75rem, 6vw, 4rem) 2rem;
  font-size: .89rem;
}
.footer-grid { display: grid; gap: 2rem; margin-bottom: 2.25rem; }
.site-footer .footer-titel {
  color: #fff;
  font-size: .76rem;
  font-weight: 600;
  letter-spacing: .15em;
  text-transform: uppercase;
  margin-bottom: .9rem;
}
.site-footer ul { list-style: none; display: grid; gap: .5rem; }
.site-footer ul a:hover { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.site-footer address { font-style: normal; }
.footer-brand img { width: 2.6rem; filter: invert(1) brightness(2); margin-bottom: .9rem; border-radius: var(--radius-sm); }
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255,255,255,.1);
  font-size: .82rem;
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: 1.1rem; }
.footer-credit { width: 100%; padding-top: .9rem; font-size: .78rem; color: #7d838d; }
.footer-credit a { text-decoration: underline; text-underline-offset: 3px; }
.footer-credit a:hover { color: #fff; }
.footer-social { display: flex; gap: .6rem; }
.footer-social a {
  display: grid; place-items: center;
  width: 2.2rem; height: 2.2rem;
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--radius-pill);
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.footer-social a:hover { border-color: #fff; background: rgba(255,255,255,.08); }
.footer-social svg { width: 1rem; height: 1rem; }

/* ---------- 13. COOKIE-BANNER & TOAST ---------- */
.cookie-banner {
  position: fixed;
  left: 50%;
  bottom: calc(1rem + env(safe-area-inset-bottom));
  z-index: var(--z-cookie);
  width: calc(100% - 2rem);
  max-width: 56rem;
  transform: translate(-50%, 130%);
  padding: 1rem 1.15rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  transition: transform var(--t-base), opacity var(--t-base), visibility var(--t-base);
  opacity: 0;
  visibility: hidden;
}
.cookie-banner.is-visible { transform: translate(-50%, 0); opacity: 1; visibility: visible; }
.cookie-banner h2 { font-size: .98rem; margin-bottom: .2rem; }
.cookie-banner p { font-size: .82rem; line-height: 1.45; }
.cookie-banner a { text-decoration: underline; text-underline-offset: 2px; }
.cookie-actions { display: flex; gap: .6rem; margin-top: .75rem; }
.cookie-actions .btn { flex: 1 1 0; padding-inline: 1rem; }
/* Schmale Handys (unter 24 rem): etwas breitere Karte, engerer Innenabstand und Knopfrand. Ab 320 px bleiben
   die Knopftexte einzeilig und der Text vierzeilig: 181 statt 229 px bei 320, 181 statt 191 px bei 360 und 375 (T14).
   Unter 20 rem (Zoom) etwas kleinere Knopfschrift, damit die Knöpfe einzeilig bleiben: 200 statt 229 px bei 288. */
@media (max-width: 23.99rem) {
  .cookie-banner { width: calc(100% - 1.5rem); padding: .85rem; }
  .cookie-banner p { line-height: 1.4; }
  .cookie-actions { margin-top: .6rem; }
  .cookie-actions .btn { padding-inline: .5rem; }
}
@media (max-width: 19.99rem) {
  .cookie-actions { gap: .5rem; }
  .cookie-actions .btn { padding-inline: .35rem; font-size: .8rem; }
}
@media (max-width: 17.99rem) {
  .cookie-banner { width: calc(100% - 1rem); padding: .75rem; }
  .cookie-actions .btn { padding-inline: .25rem; font-size: .76rem; }
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(1.25rem + env(safe-area-inset-bottom));
  z-index: var(--z-toast);
  transform: translate(-50%, 150%);
  max-width: min(28rem, calc(100% - 2rem));
  padding: .85rem 1.25rem;
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius-pill);
  font-size: .89rem;
  text-align: center;
  box-shadow: var(--shadow-lg);
  transition: transform var(--t-base), opacity var(--t-base);
  opacity: 0;
}
.toast.is-visible { transform: translate(-50%, 0); opacity: 1; }

/* ---------- 14. RECHTSSEITEN & 404 ---------- */
.legal {
  padding-top: calc(var(--header-h) + clamp(2rem, 5vw, 3.5rem));
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.legal h2 { font-size: clamp(1.3rem, 2.6vw, 1.6rem); margin-top: 2.5rem; margin-bottom: .8rem; }
.legal h3 { font-size: 1.05rem; margin-top: 1.6rem; margin-bottom: .45rem; }
.legal p, .legal li { font-size: .95rem; }
.legal p + p { margin-top: .8rem; }
.legal ul, .legal ol { margin: .8rem 0 .8rem 1.25rem; display: grid; gap: .35rem; }
.legal dl { display: grid; gap: .6rem; margin: .9rem 0; }
.legal dt { font-weight: 600; color: var(--ink); }
.legal a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 2px; }
/* Die Anschrift der Aufsichtsbehörde trägt eine lange Adresse: bei großer Browserschrift (20 px) auf 280 und 288 px
   lief sie 3 px über den Rand (T11). Umbrechen darf sie nur, wo sie sonst nicht passt. */
.legal address { overflow-wrap: anywhere; }
.legal table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: .89rem; }
.legal th, .legal td { text-align: left; padding: .6rem .7rem; border: 1px solid var(--line); vertical-align: top; }
.legal th { background: var(--paper-warm); color: var(--ink); }

.page-404 {
  min-height: 70vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-top: var(--header-h);
}

/* Tabellen im Inhalt (AEO: Kosten-/Vergleichsfragen) */
.table-wrap { overflow-x: auto; margin: 1.25rem 0; }
.table-wrap table { width: 100%; min-width: 32rem; border-collapse: collapse; font-size: .92rem; }
.table-wrap th, .table-wrap td { text-align: left; padding: .75rem .85rem; border-bottom: 1px solid var(--line); }
.table-wrap th { color: var(--ink); font-weight: 600; background: var(--paper-warm); }
.table-wrap td:last-child { font-variant-numeric: tabular-nums; }

/* ---------- 15. ANIMATIONEN ---------- */
.reveal-element {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.reveal-element.is-visible { opacity: 1; transform: none; }

/* ---------- 16. ZUGÄNGLICHKEIT & FALLBACKS ---------- */
@media (prefers-reduced-motion: reduce) {
  html, html.smooth-scroll { scroll-behavior: auto; }
  .reveal-element { opacity: 1 !important; transform: none !important; transition: none !important; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* Ohne JavaScript darf nichts unsichtbar bleiben. */
@media (scripting: none) {
  .reveal-element { opacity: 1 !important; transform: none !important; }
  .nav-mobile { display: none !important; }
  .cookie-banner { display: none !important; }
  /* Der Menü-Knopf öffnet ohne Skript nichts und sein Symbol kommt aus script.js: Er entfällt (T8). Das Häuschen
     ebenso; zur Startseite führt der Name. */
  .burger, .nav-haus { display: none !important; }
  /* Kopf im Fluss: Mit ausgeschriebener Navigation ist er höher als --header-h und läge fixiert über Seitenkopf und
     h1 (T8). Der Inhalt beginnt dann direkt unter dem Kopf. */
  :root { --header-h: 0px; }
  .site-header { position: relative; }
}
/* Unter 64 rem steht die Navigation ohne Skript ausgeschrieben unter Name und Anruf-Knopf: alle Unterseiten als
   Knöpfe in einer umbrechenden Reihe, die Gruppenknöpfe entfallen, weil sie ohne Skript nichts aufklappen (T8, T12).
   Die erste Zeile bleibt so hoch wie mit Skript. */
@media (scripting: none) and (max-width: 63.99rem) {
  .header-inner { flex-wrap: wrap; }
  .header-inner > .brand { min-height: var(--header-bar-h); }
  .nav-desktop { display: block; order: 3; flex: 1 0 100%; border-top: 1px solid var(--line); padding-block: .6rem .8rem; }
  .nav-desktop > ul { flex-wrap: wrap; gap: .35rem; }
  .nav-desktop > ul > li, .nav-desktop .untermenue, .nav-desktop .untermenue > li { display: contents; }
  .nav-desktop .untermenue { visibility: visible; }
  .nav-desktop .nav-toggle { display: none; }
  .nav-desktop a { min-height: 44px; padding: .5rem .7rem; border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--paper); }
}
/* Unter 20 rem etwas schmalere Knöpfe, damit meist zwei in eine Zeile passen */
@media (scripting: none) and (max-width: 19.99rem) {
  .nav-desktop > ul { gap: .3rem; }
  .nav-desktop a { padding-inline: .55rem; font-size: .82rem; }
}

/* ---------- BREAKPOINTS ---------- */
@media (min-width: 40rem) {
  .trustbar ul { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .expose-fakten { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Angefangene letzte Zeile auffuellen — sonst steht neben "Preis" bis zu
     zwei Drittel graue Leerflaeche und die Tabelle wirkt unfertig. */
  .expose-fakten > div:last-child:nth-child(3n + 1) { grid-column: span 3; }
  .expose-fakten > div:last-child:nth-child(3n + 2) { grid-column: span 2; }
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 48rem) {
  .cookie-banner { display: flex; align-items: center; gap: 1.5rem; }
  .cookie-banner-copy { flex: 1 1 auto; min-width: 0; }
  .cookie-actions { margin-top: 0; flex: none; flex-wrap: nowrap; }
  .cookie-actions .btn { flex: none; white-space: nowrap; }
}

@media (min-width: 64rem) {
  :root { --gutter: 2rem; }
  /* Nicht schrumpfen: Bei 1.024 px schob sich der Schriftzug sonst unter das Menü. */
  .brand { flex-shrink: 0; }
  .nav-desktop { display: block; }
  .burger { display: none; }
  .hero-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); }
  .hero-media img { aspect-ratio: 6 / 5; max-width: 659px; margin-inline-start: auto; }
  .trustbar ul { grid-template-columns: repeat(4, minmax(0, 1fr)); padding-block: 1.9rem; }
  .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .kontakt-grid { grid-template-columns: 1.1fr .9fr; gap: 3rem; }
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1.2fr; }
  .expose-grid { display: grid; grid-template-columns: 1.55fr .95fr; gap: 2.5rem; align-items: start; }
  /* .expose-aside bewusst nicht sticky — siehe oben. */
  .section-head { margin-bottom: 3rem; }
}

/* ---------- 17. PFLICHTANGABEN ENERGIEAUSWEIS (§ 87 GEG) ----------
   Bis die Werte aus dem Energieausweis vorliegen, sind die Felder sichtbar
   offen — nicht weggelassen. Fehlende Angaben sind bußgeldbewehrt. */
.geg-block {
  margin-top: 1rem;
  padding: 1.25rem 1.4rem;
  background: var(--paper-warm);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
}
.geg-block dl { display: grid; gap: .7rem; }
.geg-block dt {
  font-size: .73rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin-bottom: .15rem;
}
.geg-block dd { font-size: .97rem; font-weight: 600; color: var(--ink); }
.geg-block dd.offen { color: var(--accent-deep); font-weight: 500; font-style: italic; }
@media (min-width: 40rem) { .geg-block dl { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- 18. SEITENKOPF & BILDBÄNDER ----------
   Jede Unterseite beginnt gleich: Überschrift und Einleitung, dazu ein Bild.
   Auf dem Handy liegt das Bild als Streifen darüber, ab 64rem steht es rechts
   daneben — dasselbe Muster wie der Hero der Startseite. Ein Kopfbild über die
   volle Breite wirkte auf dem Desktop wie ein abgeschnittenes Banner. */
.seitenkopf {
  position: relative;
  padding-top: var(--header-h);
  background: linear-gradient(180deg, var(--paper-warm) 0%, var(--paper) 100%);
}
.seitenkopf-inner { display: grid; }
/* Die Spalte richtet sich nach dem Schirm, nicht nach dem längsten Wort der h1: Sonst wurde sie breiter, und das
   randlose Bild lief bei 280 und 288 px 3 bis 11 px über den Rand (T11). */
.seitenkopf-inner > * { min-width: 0; }
.seitenkopf-bild {
  position: relative;
  overflow: hidden;
  /* Handy: randlos über die volle Schirmbreite, deshalb aus dem Container heraus */
  order: -1;
  margin-inline: calc(var(--gutter) * -1);
}
.seitenkopf-bild img {
  width: 100%;
  height: clamp(11rem, 26vw, 19rem);
  object-fit: cover;
  /* Gesichter sitzen im oberen Bilddrittel — mittig zentriert schneidet der
     schmale Ausschnitt sie ab. */
  object-position: center 30%;
}
.seitenkopf-text { padding-block: clamp(2rem, 4vw, 3rem); }
.seitenkopf-text .lead { max-width: 36rem; }
.seitenkopf-text .btn-row { margin-top: 1.75rem; }

/* Der Seitenkopf bringt unten schon reichlich Luft mit. Zusammen mit der vollen
   Sektionspolsterung darunter standen auf Verkaufen und Home Staging 142 px
   Leere zwischen Ueberschriftenblock und erster Kartenreihe.
   Nur fuer helle Sektionen: bei einem farbigen Band faellt die Luft nicht als
   Loch auf, weil die Flaeche dort ohnehin die Farbe wechselt. */
.seitenkopf + .section:not(.section--warm):not(.section--dark) {
  padding-top: clamp(1rem, 2vw, 1.75rem);
}

@media (min-width: 64rem) {
  .seitenkopf-inner {
    grid-template-columns: 1.05fr .95fr;
    gap: clamp(2rem, 5vw, 3.5rem);
    align-items: center;
    padding-block: clamp(2.75rem, 6vw, 4.5rem);
  }
  .seitenkopf-bild {
    order: 0;
    margin-inline: 0;
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
  }
  .seitenkopf-bild img {
    height: auto;
    aspect-ratio: 4 / 3;
    object-position: center 40%;
  }
  .seitenkopf-text { padding-block: 0; }
}

/* Die Quellbilder sind teils nur 326–551 px breit (Bildschirmfotos). Auf
   Spaltenbreite gezogen werden sie matschig — deshalb nie ueber die native
   Breite strecken, lieber kleiner und scharf, mittig gesetzt. Wer ein grosses
   Bild hat, vergibt --gross und bekommt die volle Spalte. */
.band-bild img {
  /* KEIN width:auto — Chrome uebersetzt die width/height-Attribute nur in ein
     aspect-ratio. Mit width:auto ist ein noch nicht geladenes lazy-Bild 0 px
     breit und der Text darunter springt beim Nachladen. Ohne die Angabe gilt
     die Attributbreite als Ausgangsmass: Platz ist reserviert, und ueber die
     native Breite hinaus (also unscharf) wird trotzdem nie gestreckt. */
  max-width: 100%;
  margin-inline: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.band-bild--gross img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}



/* Häuschen statt „Start" in der Desktop-Leiste */
.nav-haus { padding-inline: .6rem; }
.nav-haus svg { width: 1.15rem; height: 1.15rem; }
.nav-mobile ul a { display: flex; align-items: center; justify-content: center; gap: .5rem; }
.nav-mobile ul a svg { width: 1.05rem; height: 1.05rem; }

/* ---------- 19. GRAFIKEN & SEITENRHYTHMUS ----------
   Textseiten waren eine einzige schmale Spalte. Jetzt wechseln sich breite
   Sektionen, Bild-Text-Bänder und Grafiken ab; Lesebreite gilt nur noch für
   den Fließtext selbst, nicht für die ganze Seite. */
.grafik {
  margin: 0;
  padding: clamp(1.25rem, 3vw, 2rem);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* Nur die Zeichenflaeche scrollt, nicht die ganze Figur — sonst wandert die
   Bildunterschrift beim Schieben mit aus dem Bild. */
.grafik-flaeche { overflow-x: auto; }
/* Grid-Items schrumpfen ohne dies nicht unter ihre Inhaltsbreite — sonst schiebt
   eine breite Grafik die ganze Seite waagerecht auf (war auf renditerechner und
   immobilienrecht der Fall: 606 px Inhalt bei 375 px Viewport). */
.text-mit-bild > * { min-width: 0; }
.grafik svg {
  width: 100%;
  /* KEIN min-width mehr: das erzwang auf dem Handy Seitwaertsscrollen, 39 % der
     Grafik lagen ausserhalb und Saetze brachen mitten im Wort ab. Stattdessen
     bekommt die Grafik unten die volle Schirmbreite und traegt groessere
     Beschriftungen. */
  max-width: 45rem;
  height: auto;
  display: block;
  margin-inline: auto;
}

/* Auf schmalen Schirmen bleibt die Grafik im Kasten und im Raster.
   Der frühere Versuch, sie randlos über die volle Schirmbreite zu ziehen, hat
   nichts gebracht: Die Kästen stießen an den Bildschirmrand, und lesbar wurde
   trotzdem nichts. Gemessen bei 375 px lagen die Beschriftungen zwischen 4,7
   und 11 px — eine 900-Einheiten-Zeichnung auf 341 px ist Maßstab 0,33. */
@media (max-width: 40rem) {
  .grafik { padding-inline: 1rem; }

  /* Das Kontaktformular nahm auf dem Handy fast zwei Bildschirme ein: Felder
     54 px hoch, 16 px Abstand darunter, Textfeld 165 px. Enger gesetzt —
     Innenabstand, Zeilenabstand und Texthöhe. Die Schriftgröße bleibt bei
     16 px: darunter zoomt Safari beim Antippen in die Seite hinein. */
  .field { gap: .3rem; margin-bottom: .7rem; }
  .field label { font-size: .8rem; }
  .field input, .field select, .field textarea { padding: .62rem .8rem; }
  /* height, nicht min-height: das rows-Attribut steht sonst dagegen. */
  .field textarea { height: 7rem; min-height: 7rem; }
}

/* ---------- 19a. ZWEI FASSUNGEN JE ERKLÄRGRAFIK ----------
   Jede der sechs Zeichnungen liegt zweimal vor: quer für den Schirm, hochkant
   fürs Handy. Der Zwischenschritt — eine Mindestbreite und seitliches
   Verschieben — war zwar lesbar, schob aber genau das aus dem Bild, worum es
   geht: die +15 %, die 5,0 %, die zweite Karte. Wer eine Grafik ändert, muss
   BEIDE Fassungen anfassen; der Prüflauf zählt sie deshalb gegeneinander. */
.nur-schmal { display: none; }
@media (max-width: 51.99rem) {
  .nur-breit { display: none; }
  .nur-schmal { display: block; }
  /* Die Hochkant-Fassungen sind auf 320 Einheiten gezeichnet. Ohne Deckel
     würden sie bis 45rem hochskaliert und die Schrift grotesk groß. */
  .nur-schmal .grafik-flaeche svg { max-width: 24rem; }
}
.grafik img {
  /* min(), nicht 45rem allein: das schlug sonst das globale max-width:100% und
     das Foto war auf dem Handy 720 px breit in einem 355-px-Kasten. */
  max-width: min(45rem, 100%);
  margin-inline: auto;
  border-radius: var(--radius-md);
}
.grafik figcaption {
  margin-top: 1rem;
  padding-top: .9rem;
  border-top: 1px solid var(--line-soft);
  font-size: .84rem;
  color: var(--muted);
}
.section--warm .grafik { background: var(--paper); }
.grafik--breit { max-width: 60rem; margin-inline: auto; }
/* Eine breite Grafik darf auch breit gezeichnet werden. Bei den generellen
   45rem schrumpfte die 900er-Ablaufgrafik auf 0,8 — die 12,5-px-Beschriftungen
   kamen mit 10 px an und waren zu klein zum Lesen. */
.grafik--breit svg { max-width: 56rem; }

/* Fließtext in Lesebreite, aber in einer breiten Sektion sitzend */
.prosa { max-width: 42rem; }
.prosa--mitte { margin-inline: auto; }
.prosa > h2:first-child,
.prosa > h3:first-child { margin-top: 0; }
.prosa h2 { margin-top: 2.25rem; margin-bottom: .7rem; }
.prosa h3 { margin-top: 1.6rem; margin-bottom: .4rem; }
.prosa p + p { margin-top: .85rem; }
.prosa ul, .prosa ol { margin: .9rem 0 .9rem 1.2rem; display: grid; gap: .45rem; }
.prosa dl { display: grid; gap: .8rem; margin: 1rem 0; }
.prosa dt { font-weight: 600; color: var(--ink); }

/* Zweispaltig: Text links, Grafik/Bild rechts klebend */
.text-mit-bild { display: grid; gap: clamp(1.75rem, 4vw, 3.25rem); align-items: start; }

/* Abstände zwischen den Blöcken einer Seite — vorher uneinheitlich */
.section > .container > * + .grafik { margin-top: clamp(2rem, 4vw, 3rem); }

@media (min-width: 56rem) {
  .text-mit-bild { grid-template-columns: 1fr 1fr; }
  .text-mit-bild--breit-links { grid-template-columns: 1.2fr .8fr; }
  .text-mit-bild--breit-rechts { grid-template-columns: .8fr 1.2fr; }
  /* Kein Klebe-Effekt: mitscrollende Bilder wirken unruhig und lassen unter
     sich ein Loch, wenn die Textspalte laenger ist. */

  /* Beginnt die Textspalte mit einem Eyebrow, startet die Nachbarspalte
     oberhalb der eigentlichen Ueberschrift und liest sich als versetzt.
     4.8rem = 77 px: Zeilenkasten des Eyebrows samt margin-bottom (41 px) plus
     margin-top der h2 (2.25rem). Alle drei Werte haengen nicht am Schirm,
     der Versatz stimmt deshalb auf jeder Breite — nachgemessen bei 1.440 px. */
  .text-mit-bild > .beginnt-bei-h2 { margin-top: 4.8rem; }
}

/* ---------- 20. KUNDENSTIMMEN & SIEGEL (überarbeitet) ---------- */
.stimme {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 2rem 1.75rem 1.6rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color var(--t-base), box-shadow var(--t-base), transform var(--t-base);
}
.stimme:hover { border-color: var(--line-stark); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.stimme::before {
  content: "„";
  position: absolute;
  /* Sass rechts oben statt auf dem ersten Wort: vorher lag das Zeichen bei
     top .35 / left 1.4 direkt auf „War…", „Sehr…", „Bin…". */
  top: .1rem; right: 1.1rem; left: auto;
  font-size: 3.4rem;
  line-height: 1;
  color: var(--accent);
  opacity: .14;
  pointer-events: none;
}
.stimme-sterne { display: flex; gap: .12rem; color: var(--gold); margin-bottom: .9rem; }
.stimme-sterne svg { width: .92rem; height: .92rem; }
.stimme blockquote { margin: 0; font-size: .97rem; line-height: 1.62; color: var(--ink-soft); }
.stimme footer {
  display: flex;
  align-items: center;
  gap: .7rem;
  /* auto statt fester Wert: sonst rutscht die Autorenzeile bei kuerzerem Zitat
     nach oben und die Karten einer Reihe fransen aus. */
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
}
.stimme-initial {
  display: grid;
  place-items: center;
  width: 2.4rem; height: 2.4rem;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: .92rem;
  font-weight: 700;
}
.stimme cite { font-style: normal; font-weight: 600; color: var(--ink); font-size: .92rem; }
.stimme .stimme-rolle { display: block; font-size: .8rem; color: var(--muted); font-weight: 500; }

/* Siegel als eingebundener Vertrauensblock statt loser Bildreihe */
.vertrauensblock {
  display: grid;
  gap: 1.25rem;
  align-items: center;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.vertrauens-item {
  display: flex;
  align-items: center;
  gap: .95rem;
  min-width: 0;
}
.vertrauens-item + .vertrauens-item {
  padding-top: 1.25rem;
  border-top: 1px solid var(--line-soft);
}
.vertrauens-item img { width: 3.1rem; height: auto; flex: none; }
.vertrauens-item strong { display: block; color: var(--ink); font-size: .95rem; }
.vertrauens-item span { font-size: .84rem; color: var(--muted); }
.vertrauens-item a { text-decoration: underline; text-underline-offset: 2px; }
.vertrauens-item a:hover { color: var(--accent-deep); }
/* Gold statt Messing — der Kreis zeigt eine Sternebewertung. */
.vertrauens-bewertung {
  display: grid;
  place-items: center;
  width: 3.1rem; height: 3.1rem;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--gold-soft);
  color: var(--gold-tief);
  font-size: 1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Dreispaltig NUR mit --breit. Vorher hing das an einem @media auf die
   Fensterbreite: in der schmalen Seitenspalte (426 px) wurden daraus drei
   Spalten a 156 px, das IHK-Logo lag ueber dem Text. Wer den Block ueber die
   volle Breite setzt, vergibt --breit; sonst bleibt er einspaltig. */
@media (min-width: 52rem) {
  .vertrauensblock--breit { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; }
  .vertrauensblock--breit .vertrauens-item + .vertrauens-item {
    padding-top: 0; border-top: 0;
    border-left: 1px solid var(--line-soft); padding-left: 2rem;
  }
}


/* Kein Rand, kein Verlauf, kein Schatten um Tabellen — jeder Versuch eines
   Scroll-Hinweises hat auf farbigem Grund sichtbare Kanten erzeugt. Die Tabelle
   sitzt bündig im Text. */

/* ---------- 21. BILD UND TEXT NEBENEINANDER ----------
   Bild und Text sollen zusammen abschliessen. Ohne dies endete das Bild bis zu
   210 px vor dem Text und der Block wirkte unfertig. */
@media (min-width: 56rem) {
  .text-mit-bild { align-items: stretch; }
  .text-mit-bild > .band-bild--gross { display: flex; }
  .text-mit-bild > .band-bild--gross img {
    width: 100%;
    height: 100%;
    min-height: 20rem;
    object-fit: cover;
    object-position: center 45%;
  }
  /* Die Person sitzt links im Bild und bleibt beim Zuschnitt ganz drin. */
  .text-mit-bild > .band-bild--gross img.bild-fokus-links { object-position: 20% center; }
}

/* ---------- 22. FARBE FUER SIGNALE ----------
   Die Seite trug ueberall denselben Messington. Signale bekommen eigene Farben. */
.section--dark .card-icon svg[data-icon-name="trending-up"] { color: var(--gold-tief); }
.section--dark .card-icon svg[data-icon-name="map-pin"] { color: var(--gold-tief); }

/* Vertrauensleiste: jedes Symbol eine eigene Farbe statt viermal Messing */
.trustbar li:nth-child(1) svg { color: var(--gold); }
.trustbar li:nth-child(2) svg { color: var(--accent); }
.trustbar li:nth-child(3) svg { color: var(--gruen); }
.trustbar li:nth-child(4) svg { color: var(--accent-deep); }

/* Gleichartige Kaesten in einer Rasterzeile gleich hoch — die Adresskaesten
   Heilbronn/Fellbach waren 184 vs. 168 px und sassen 16 px versetzt. */
.grid > .kontakt-karte,
.grid > .card { height: 100%; }
.grid--2, .grid--3, .grid--4 { align-items: stretch; }

/* ---------- 23. HILFSKLASSEN STATT INLINE-STYLES ----------
   Die Seite liefert ein Meta-CSP mit `style-src 'self'` — OHNE 'unsafe-inline'.
   Damit blockiert sie ihre eigenen style="..."-Attribute: zentrierte Knopfreihen
   standen links, der Kopfausgleich fehlte, das Logo hatte keine Groesse.
   Jede Layout-Anweisung gehoert deshalb in eine Klasse. */
.marke-bild { width: 2.3rem; }
.btn-row--mitte { justify-content: center; }
.oben-buendig { align-items: start; }
.mittig-buendig { align-items: center; }
.text-mitte-schmal { text-align: center; max-width: 44rem; margin-inline: auto; }
.abstand-unten-gross { margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.abstand-unten-klein { margin-bottom: 1.5rem; }
.linie-oben { border-top: 1px solid var(--line); }
.linie-oben-unten { border-block: 1px solid var(--line); }

/* Kennzahl-Kacheln (»bis 15 %«) sind Zahlen, keine Gliederungsebene. Als <h3>
   direkt unter der <h1> rissen sie ein Loch in die Ueberschriftenfolge. */
.kennzahl {
  display: block;
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.022em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---------- 24. GOOGLE-PLAKETTE ----------
   Das G ist ein Markenzeichen: klein, unveraendert, neben der Note. Die beiden
   Wege muessen unterscheidbar sein — einer fuehrt zu Google, einer bleibt hier. */
.google-g { width: 1.05rem; height: 1.05rem; flex: none; }
.hero-badge-kopf { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .45rem; }
.hero-badge-kopf .num { font-size: 1.05rem; color: var(--ink); }
.hero-badge-anzahl { font-size: .74rem; color: var(--muted); }
.hero-badge-links { display: flex; flex-wrap: wrap; gap: .3rem .9rem; }
.hero-badge-links a {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  font-size: .76rem;
  font-weight: 600;
  color: var(--accent-deep);
  /* Der Link selbst traegt KEINE Unterstreichung — eine geerbte Dekoration
     laesst sich am Kind nicht abschalten und lief sonst unter dem Pfeil durch.
     Unterstrichen wird nur der Text im inneren span. */
  text-decoration: none;
}
.hero-badge-links .u { text-decoration: underline; text-underline-offset: 2px; }
.hero-badge-links .pfeil { text-decoration: none; font-size: .72rem; opacity: .8; }
.hero-badge-links a:hover { color: var(--ink); }

/* ---------- 25. HANDY-FEINSCHLIFF ---------- */
@media (max-width: 40rem) {
  /* Gestapelte Knoepfe hatten zwei Breiten (285 vs. 335 px) — die uneinheitliche
     Kante faellt auf schmalem Schirm sofort auf. Gilt auch fuer Knoepfe, die
     nicht in einer .btn-row stecken. */
  .btn { width: 100%; justify-content: center; }
  .btn-row { flex-direction: column; align-items: stretch; }
  /* Ausgenommen: Knoepfe, die bewusst nebeneinander in einer Zeile stehen */
  .hero-badge-links a, .card-link, .breadcrumb a { width: auto; }

  /* Footer-Links waren 17 px hohe Tippziele bei 23 Links je Seite */
  .site-footer li a,
  .site-footer .footer-bottom a,
  .site-footer .footer-bottom button {
    display: inline-block;
    padding-block: .45rem;
    min-height: 2.75rem;
    line-height: 1.9;
  }
  /* Zweispaltiger Footer spart rund die halbe Hoehe (war 1.381 px je Seite) */
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 1.25rem 1rem; }
  .footer-brand { grid-column: 1 / -1; }

  /* Kopf-/Burger-Tippziele auf 44 px, in px, damit eine große Browserschrift den Kopf nicht sprengt (T12) */
  .burger { width: 44px; height: 44px; }

  /* Kostentabelle: dritte Spalte lag ausserhalb, ohne Hinweis */
  .table-wrap table { min-width: 0; font-size: .86rem; }
  .table-wrap th, .table-wrap td { padding: .6rem .4rem; -webkit-hyphens: auto; hyphens: auto; overflow-wrap: break-word; }   /* passt ohne Abschneiden (T11, T31) */
  /* Tabelle mit einer Zeile und langen Texten (Datenschutz): Zellen untereinander, Spaltenname davor */
  .table-wrap--stapel thead { display: none; }
  .table-wrap--stapel tr, .table-wrap--stapel td { display: block; }
  .table-wrap--stapel td::before { content: attr(data-label); display: block; font-weight: 600; color: var(--ink); }

  /* Objektreihe der Startseite zweispaltig: sechs Karten untereinander sind
     auf dem Handy rund 2.900 px Scrollweg, nebeneinander noch 1.450 px.
     Gilt bewusst NUR fuer die Startseite — auf der Objektuebersicht ist die
     Karte die Hauptsache und behaelt die volle Breite. */
  .grid--mobil-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .7rem;
  }
  .grid--mobil-2 .objekt-body { padding: .75rem .8rem .9rem; }
  .grid--mobil-2 .objekt-ort { font-size: .74rem; margin-bottom: .3rem; }
  .grid--mobil-2 .objekt-ort svg { width: .8rem; height: .8rem; }
  .grid--mobil-2 .objekt h3 { font-size: .92rem; line-height: 1.3; margin-bottom: .5rem; }
  .grid--mobil-2 .objekt-preis { font-size: 1rem; }
  .grid--mobil-2 .objekt-meta {
    font-size: .74rem;
    gap: .25rem .5rem;
    padding-top: .6rem;
  }
  .grid--mobil-2 .objekt-meta svg { width: .8rem; height: .8rem; }
  .grid--mobil-2 .objekt-tag {
    top: .5rem; left: .5rem;
    padding: .22rem .5rem;
    font-size: .62rem;
    letter-spacing: .05em;
  }
  .grid--mobil-2 .objekt-status {
    left: .5rem; bottom: .5rem;
    padding: .22rem .5rem;
    font-size: .62rem;
    letter-spacing: .05em;
  }
}

/* Zwei gleichfarbige Sektionen aneinander lasen sich als ein Block mit 140 px
   totem Raum in der Mitte — eine feine Linie trennt sie. */
.section--warm + .section--warm { border-top: 1px solid var(--line); }
.section:not([class*="--"]) + .section:not([class*="--"]) { border-top: 1px solid var(--line-soft); }

/* In schmalen Spalten stapeln zwei CTAs sauber statt mit 13 px Fehlbreite
   umzubrechen und ungleich lange Kanten zu bilden. */
.btn-row--gestapelt { flex-direction: column; align-items: stretch; }
.btn-row--gestapelt > .btn { width: 100%; }

/* ============================================================
   DRUCKANSICHT — vor allem für die Exposé-Seiten
   ============================================================
   Ein Exposé wird ausgedruckt und mit an die Besichtigung genommen; deshalb
   muss das Blatt für sich stehen. Sichtbar bleiben Objekt, Eckdaten, der
   GEG-Block (Pflichtangaben) und die Kontaktwege — alles Bedienbare fällt weg.
   Der Knopf [data-drucken] ist nur ein Auslöser: Wer über das Browsermenü
   druckt, bekommt dasselbe Blatt. */
/* Tippflächen mindestens 24 px (T7): Brotkrumen, Objekttitel in Karten, Bewertungs- und Kartenlinks */
.breadcrumb a, .card-link, .hero-badge-links a, .vertrauens-item a { display: inline-flex; align-items: center; min-height: 1.5rem; }
.objekt h3 a { display: inline-block; min-height: 1.5rem; }

/* Bilder nie größer anzeigen als die Datei (T9, G9). Die Rahmen dieser Motive sind ab
   30rem auf die Dateibreite begrenzt und mittig gesetzt; auf dem Handy bleibt der
   Seitenkopf randlos. Mit größeren Originalen entfallen die Klassen. */
@media (min-width: 30rem) {
  .bild-max-530, .bild-max-560, .bild-max-750, .bild-max-760, .bild-max-880 { margin-inline: auto; }
  .bild-max-530 { max-width: 530px; }
  .bild-max-560 { max-width: 560px; }
  .bild-max-750 { max-width: 750px; }   /* Exposé-Titelbilder nie größer als die Datei (T9) */
  .bild-max-760 { max-width: 760px; }
  .bild-max-880 { max-width: 880px; }
  /* Ein fester Bildausschnitt (4:3) würde das Motiv wieder vergrößern: natürliches Format */
  .hero-media[class*="bild-max-"] img { aspect-ratio: auto; }
}
@media (min-width: 64rem) {
  .seitenkopf-bild[class*="bild-max-"] img { aspect-ratio: auto; }
}

@media print {
  @page { size: A4; margin: 16mm 14mm; }

  html, body {
    background: #fff !important;
    color: #000 !important;
    font-size: 10.5pt;
    line-height: 1.45;
  }

  /* Alles Bedienbare und alles Wiederkehrende raus. */
  .site-header, .topbar, .nav-desktop, .nav-mobile, .burger, .header-actions,
  .breadcrumb, .cookie-banner, .site-footer, .btn, .btn-row,
  .footer-social, form, .reveal-element .btn, [data-drucken] { display: none !important; }

  /* Der Reveal-Effekt blendet Abschnitte per Deckkraft ein — im Druck läuft
     kein Scroll-Ereignis, ohne diese Zeile bliebe das halbe Blatt unsichtbar. */
  .reveal-element { opacity: 1 !important; transform: none !important; }

  /* Kopfzeile des Blattes: Wer das Exposé in der Hand hält, muss sehen,
     von wem es kommt. Ersetzt das ausgeblendete Seiten-Menü. */
  .expose-hero::before {
    content: "Vollweiler & Niederberger GmbH · Immobilienmakler in Heilbronn · 07131 266 2233 · info@vollweiler-niederberger.de";
    display: block;
    font-size: 8.5pt;
    letter-spacing: .2pt;
    border-bottom: 1pt solid #000;
    padding-bottom: 4pt;
    margin-bottom: 10pt;
  }

  .section, .expose-hero { padding: 0 0 10pt !important; background: none !important; }
  .container { width: auto !important; max-width: none !important; padding: 0 !important; }

  /* Zweispaltiges Bildschirmraster auf eine Spalte, sonst quetscht es
     Eckdaten und Beschreibung in zwei schmale Säulen. */
  .expose-grid, .grid, .grid--3 { display: block !important; }

  .expose-aside {
    border: .8pt solid #000;
    padding: 8pt;
    margin-top: 10pt;
    background: none !important;
    page-break-inside: avoid;
  }

  .expose-bild img, .expose-hero img {
    max-height: 85mm;
    width: auto;
    max-width: 100%;
    object-fit: contain;
  }

  /* Die Pflichtangaben dürfen nicht über den Seitenrand fallen — ein
     zerrissener Energieausweis-Block ist der Fehler, den § 87 GEG meint. */
  .geg-block, .expose-fakten, .objekt { page-break-inside: avoid; }

  h1 { font-size: 17pt; }
  h2 { font-size: 13pt; page-break-after: avoid; }
  h3 { font-size: 11.5pt; page-break-after: avoid; }

  /* Verweise im Fließtext sind auf Papier tot — die Adresse dahinterschreiben,
     außer bei mailto/tel, wo der Text schon die Adresse ist. */
  main a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 8.5pt; }

  .objekt-preis { font-size: 15pt; font-weight: 700; }
}
