/* ==========================================================================
   Mobile Lackaufbereitung S&G — Stylesheet
   Wird von index.html, impressum.html und datenschutz.html gemeinsam genutzt.

   Schriftart: bewusst KEINE externe Webfont-Einbindung (Google Fonts o.ä.),
   aus Datenschutz- (keine Anfrage an Drittserver) und Performance-Gründen.
   Stattdessen ein hochwertiger System-Font-Stack — jedes Betriebssystem
   liefert damit automatisch eine moderne, saubere Schrift ohne Ladezeit.
   ========================================================================== */

:root {
  --bg: #0c0b0a;
  --surface: #171512;
  --surface-2: #211e1a;
  --text: #f4f1ec;
  --text-muted: #a09a92;
  /* Marke: warmes Anthrazit / Weiß / Rot nach Orange

     Die Akzentfarbe ist ein Verlauf von tiefem Autorot ins Orange. Beide Töne
     sind benachbart, deshalb bleibt der Übergang durchgehend gesättigt; ein
     Verlauf über den halben Farbkreis würde in der Mitte grau kippen.

     Ein Verlauf kann aber nur Flächen füllen. Für Schrift, Rahmen, Symbole
     und den Tastatur-Fokusrahmen braucht es einen festen Ton, dafür steht
     --accent-ink. Deshalb gibt es hier beides:
       --verlauf        Flächen: Knöpfe, Linien, Kartennadel
       --verlauf-hover  dieselbe Fläche beim Überfahren, dunkler
       --accent         fester Startton, Rückfall und Flächen ohne Verlauf
       --accent-hover   dunkler dazu
       --accent-ink     Schrift, Rahmen, Fokus */
  --accent: #b3241c;
  --accent-hover: #8f1c16;
  --accent-ink: #b3241c;
  --verlauf: linear-gradient(100deg, #b3241c, #c2560f);
  --verlauf-hover: linear-gradient(100deg, #8f1c16, #9e440c);
  --accent-text: #ffffff;
  --border: #2f2b26;
  --shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.6);


  --info-bg: color-mix(in srgb, var(--surface-2) 80%, transparent);
  --info-border: var(--border);

  /* WhatsApp-Grün eine Spur tiefer als das Original-Neongrün: Neben dem
     Türkis lagen die beiden Töne sonst so dicht beieinander, dass sie sich
     gegenseitig störten. Erkennbar bleibt es trotzdem. */
  --whatsapp: #15833f;
  --whatsapp-dark: #0f6530;
  /* Eigener Ton für Grün als SCHRIFT. Das dunkle Grün oben ist für Flächen
     gedacht; als Text auf dunklem Grund wäre es zu kontrastarm zum Lesen.
     Im Hellmodus dreht sich das um – siehe unten. */
  --whatsapp-text: #4fce7f;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Roboto Mono", Menlo, monospace;

  --header-h: 86px;
}

:root[data-theme="light"] {
  --bg: #f6f4f2;
  --surface: #fffefb;
  --surface-2: #efece9;
  --text: #191715;
  --text-muted: #5c5751;
  --accent: #b3241c;
  --accent-hover: #8f1c16;
  --accent-ink: #b3241c;
  --verlauf: linear-gradient(100deg, #b3241c, #c2560f);
  --verlauf-hover: linear-gradient(100deg, #8f1c16, #9e440c);
  --accent-text: #ffffff;
  --border: #e2ded9;
  --shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.18);
  --info-bg: var(--surface-2);
  --whatsapp-text: #0f6a33;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #f6f4f2;
    --surface: #fffefb;
    --surface-2: #efece9;
    --text: #191715;
    --text-muted: #5c5751;
    --accent: #b3241c;
    --accent-hover: #8f1c16;
    --accent-ink: #b3241c;
    --verlauf: linear-gradient(100deg, #b3241c, #c2560f);
    --verlauf-hover: linear-gradient(100deg, #8f1c16, #9e440c);
    --accent-text: #ffffff;
    --border: #e2ded9;
    --shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.18);
    --info-bg: var(--surface-2);
    --whatsapp-text: #0f6a33;
  }
}

/* ---------- Reset / Base ---------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
section, [id] { scroll-margin-top: calc(var(--header-h) + 14px); }
img { max-width: 100%; display: block; }
a { color: inherit; }
.container { max-width: 1180px; margin: 0 auto; padding: 0 24px; }
::selection { background: var(--accent); color: #fff; }
:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }

h1, h2, h3, h4 { text-wrap: balance; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
/* Überschriften bewusst NICHT durchgehend in Großbuchstaben: acht
   Versalien-Überschriften untereinander wirken schablonenhaft. Die
   Versalien bleiben dem Hero vorbehalten – dort sind sie eine Aussage. */
h2 {
  font-size: clamp(30px, 4.2vw, 44px);
  letter-spacing: -0.03em;
  line-height: 1.08;
}
/* Feiner Polier-Schwung unter der Überschrift – greift die Bewegung aus
   dem Logo auf und gibt den Abschnitten eine eigene Handschrift. */
.section-head h2, h2.has-rule { position: relative; display: inline-block; padding-bottom: 14px; }
.section-head h2::after, h2.has-rule::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 64px; height: 3px;
  border-radius: 3px;
  background: var(--verlauf);
}
h3 { letter-spacing: -0.01em; }
p { color: var(--text-muted); max-width: 62ch; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}

/* ---------- Icons (einheitliches Inline-SVG-System, keine externe Bibliothek) ---------- */
.icon {
  width: 1.15em;
  height: 1.15em;
  display: inline-block;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.2em;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 13px 24px;
  border-radius: 7px;
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s, background 0.15s, border-color 0.15s;
  min-height: 48px;
}
.btn-primary { background: var(--verlauf); color: var(--accent-text); }
.btn-primary:hover { background: var(--verlauf-hover); transform: translateY(-1px); }
.btn-ghost { border-color: var(--border); color: var(--text); background: transparent; }
.btn-ghost:hover { border-color: var(--accent-ink); color: var(--accent-ink); }
.btn-block { width: 100%; justify-content: center; }

/* ==========================================================================
   Header / Navigation
   ========================================================================== */
/* Die Kopfzeile liegt ÜBER dem Hero, nicht darüber. Deshalb fixed statt
   sticky: Das Bild läuft bis unter den oberen Bildschirmrand durch.

   Auf der Startseite ist sie durchsichtig, damit das Bild auch hinter der
   Navigation weiterläuft. Damit die dunklen Menüpunkte dort lesbar bleiben,
   hellt .hero-media::before den obersten Streifen des Bildes auf – siehe dort.

   Auf Seiten ohne Hero bleibt sie deckend, dort gibt es kein Bild dahinter.
   Das steuert :has(), ganz ohne JavaScript. */
header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  transition: background 0.25s ease, border-color 0.25s ease;
}
/* Startseite: durchsichtig, das Bild läuft dahinter durch — aber nur so
   lange das Bild wirklich hinter der Leiste liegt. Ist der Hero nach oben
   herausgescrollt, wird sie wieder deckend, sonst läuft der Seiteninhalt
   quer durch Logo und Symbole.
   Umgeschaltet wird über die Klasse .ueber-hero aus script.js. Deckend ist
   der Ausgangszustand, damit die Leiste auch ohne JavaScript lesbar bleibt. */
/* Durchsichtig, solange wirklich das Bild dahinter liegt. Umgeschaltet wird
   über .ueber-hero aus script.js, und zwar anhand der Bildfläche, nicht des
   ganzen Hero. Auf dem Handy ist der Hero viel höher als das Bild; ohne diese
   Unterscheidung liefen Überschrift und Anfrage beim Scrollen durch Logo und
   Symbole. */
body.ueber-hero header {
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
/* Über dem Bild dunkle statt graue Menüpunkte. Grau kam dort nachgemessen
   nur auf Kontrast 2,8 bis 4,3, vor Fensterstreben und Dachkante bis hinab
   auf 1,0. Zusammen mit dem hellen Streifen aus .hero-media::before bleiben
   sie auch dort lesbar. */
body.ueber-hero nav.links a { color: var(--text); }
/* Seiten ohne Hero brauchen Platz, sonst läuft ihr Inhalt unter die nun
   schwebende Kopfzeile. Die Startseite regelt das im Hero selbst. */
main { padding-top: var(--header-h); }
main:has(> .hero) { padding-top: 0; }
.nav-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  max-width: 1180px;
  margin: 0 auto;
  gap: 20px;
  min-height: var(--header-h);
}
@media (min-width: 1180px) {
  .nav-wrap { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; column-gap: 14px; }
  .brand { justify-self: start; }
  nav.links { justify-self: center; }
  .nav-right { justify-self: end; }
}
.brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  flex-shrink: 0;
}
/* Die Wortmarke steht bewusst frei auf dem Hintergrund – ohne Kästchen
   drumherum wirkt sie wie ein echtes Logo und nicht wie ein App-Symbol. */
.brand-logo {
  /* Das Logo liegt freigestellt vor, der weisse Hintergrund ist in der Datei
     entfernt. mix-blend-mode waere hier wirkungslos: die Kopfzeile ist fixiert
     und bildet damit einen eigenen Stapelkontext, in dem nichts zum Mischen
     liegt. */
  /* Freigestellt und auf den Inhalt zugeschnitten: kein weißer Rand, kein
     Kasten über dem Hero-Foto. Die Wortmarke ist mit rund 3,2:1 deutlich
     breiter als das frühere Wappen und trägt fast nur Schrift. Sie braucht
     daher weniger Höhe für dieselbe Lesbarkeit: bei 58px ist "MOBILE" etwa
     23px hoch. */
  height: 58px;
  width: auto;
  /* Ohne das greift die allgemeine Regel img { max-width: 100% } und deckelt
     die Breite auf die des Elternelements. Zusammen mit der festen Höhe wird
     das Logo dann horizontal gestaucht statt gleichmäßig skaliert. */
  max-width: none;
  display: block;
}
.brand:hover .brand-logo { opacity: 0.9; }
/* Kopfzeilenhöhe ist Logohöhe plus dem senkrechten Innenabstand von
   .nav-wrap: 2x14px, unter 640px 2x10px. Wächst das Logo, muss dieser Wert
   mitwachsen, sonst schiebt sich der Inhalt der Unterseiten unter die Leiste.
   Die kleinste Stufe greift erst unter 360px: 375px ist die Breite vieler
   verbreiteter Telefone und soll noch die größere Größe bekommen. */
@media (max-width: 860px) { :root { --header-h: 78px; } }
@media (max-width: 640px) { :root { --header-h: 64px; } }
@media (max-width: 360px) { :root { --header-h: 58px; } }

@media (max-width: 860px) { .brand-logo { height: 50px; } }
@media (max-width: 640px) { .brand-logo { height: 44px; } }
@media (max-width: 360px) { .brand-logo { height: 38px; } }

.nav-right { display: flex; align-items: center; gap: 6px; }

.phone-link {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: 7px;
  text-decoration: none;
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
  white-space: nowrap;
  transition: color 0.15s, background 0.15s;
}
.phone-link:hover { color: var(--accent-ink); background: var(--surface-2); }
.phone-link .icon { color: inherit; }

.hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  /* 44px ist die uebliche Mindestgroesse fuer eine Flaeche, die mit dem Daumen
     sicher getroffen wird. Der Strich bleibt optisch bei 22px. */
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
}
.hamburger span {
  display: block; width: 22px; height: 2px; margin: 0 auto;
  background: var(--text); border-radius: 2px;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.hamburger[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

nav.links { display: flex; gap: 1px; flex-wrap: nowrap; align-items: center; }
nav.links a {
  position: relative;
  text-decoration: none; font-size: 13.5px; font-weight: 600; color: var(--text-muted);
  padding: 8px 9px; border-radius: 6px; transition: color 0.15s, background 0.15s;
  white-space: nowrap;
}
nav.links a:hover { color: var(--text); background: var(--surface-2); }
/* "Über uns" führt als einziger Punkt auf eine eigene Seite statt weiter
   nach unten. Früher stand es ganz am Ende der Leiste und trug dort einen
   Trennstrich. Seit es zwischen "Häufige Fragen" und "Kontakt" steht, ist
   der Strich weg: Er hätte "Über uns" und "Kontakt" optisch zu einer Gruppe
   zusammengefasst, die es nicht gibt. Dass ein Menüpunkt eine Seite lädt
   statt zu scrollen, muss man ohnehin niemandem ankündigen.
   Die Klasse bleibt – sie markiert auf der Über-uns-Seite die aktive Seite. */
/* Bewertungen wird bewusst wie jeder andere Punkt dargestellt – eine
   Sonderfarbe würde die Leiste unruhig wirken lassen. */

/* Aktiver Bereich beim Scrollen: unterstreicht den Punkt, in dem sich der
   Besucher gerade befindet (wird von js/script.js gesetzt). */
nav.links a::after {
  content: "";
  position: absolute;
  left: 9px; right: 9px; bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.25s ease;
}
nav.links a.is-active { color: var(--text); }
nav.links a.is-active::after { transform: scaleX(1); }

.nav-cta { display: none; white-space: nowrap; }
/* Der Button erscheint erst, wenn wirklich Platz ist – sonst drückt er die
   Kopfleiste über die Fensterkante. */
@media (min-width: 1280px) { .nav-cta { display: inline-flex; } }
/* Ab 1280px stehen rechts die ausgeschriebene Nummer und der Knopf. Mit
   sieben Punkten in der Leiste passte das auf den Pixel genau in die 1132px
   der Kopfzeile. Seit dem 12.10.2026 hat die Leiste mit "Home" acht Punkte
   (Wunsch von Eliah) und wäre rund 60px zu breit: Die rechte Gruppe ragte
   über den Rand des Inhalts hinaus.
   Deshalb bekommt die Navigation hier die ganze Mitte und verteilt ihre
   Punkte darin gleichmäßig, mit schmalerem Innenabstand. So hängt nichts mehr
   an einer festen Pixelzahl: Fällt die Schrift auf einem anderen Gerät etwas
   breiter aus, rücken die Punkte nur enger zusammen. Der Knopf gibt dafür
   seitlich je 4px ab. Unter 1280px bleibt alles wie vorher. */
@media (min-width: 1280px) {
  .nav-wrap { grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 10px; }
  nav.links { justify-self: stretch; justify-content: space-between; gap: 0; }
  nav.links a { padding-left: 5px; padding-right: 5px; }
  nav.links a::after { left: 5px; right: 5px; }
  .nav-right .nav-cta { padding-left: 20px; padding-right: 20px; }
}

/* ---------- Geräteabstufung der Kopfleiste ----------
   Ab 1180px (Laptop/Desktop): alles nebeneinander – Navigation zentriert,
     Telefonnummer ausgeschrieben, "Termin anfragen"-Button.
   1000–1179px (iPad quer, kleine Laptops): Navigation bleibt sichtbar,
     dafür Telefon nur als Symbol und ohne Button – so passt die Reihe
     ohne Umbruch.
   Unter 1000px (iPad hoch, Handy): Navigation klappt ins Vollbildmenü, der
     Anruf bleibt als einziger Knopf neben dem Logo stehen. */
@media (min-width: 1000px) and (max-width: 1279px) {
  .phone-link { width: 40px; height: 40px; padding: 0; justify-content: center; }
  .phone-link .phone-number { display: none; }
}
@media (max-width: 999px) {
  nav.links { display: none; }
  .hamburger { display: flex; }
  /* Seit die feste Leiste unten weg ist, ist das hier der einzige
     Anruf-Knopf. Er traegt deshalb die Akzentfarbe, damit er als Handlung
     erkennbar ist und nicht wie ein weiteres graues Symbol wirkt.

     Auf Wunsch von David (15.09.2026) ein flaches Rechteck mit runden Ecken
     statt eines Kreises, und niedriger als das Logo: Als 44er Kreis war der
     Knopf das groesste Element der Kopfleiste und zog mehr Aufmerksamkeit auf
     sich als das Logo selbst. Erst trug er die Beschriftung "Kontakt", die
     ist auf Wunsch von David wieder raus, jetzt steht nur das Telefonsymbol
     darin.

     Breite und Hoehe stehen fest bei 44 zu 30 px: Ohne feste Breite haengt
     sie am Symbol und der Knopf waere fast quadratisch. Laenglich soll er
     bleiben, sonst wirkt er wieder wie ein Kreis mit Ecken. */
  .phone-link {
    width: 44px; height: 30px; padding: 0; justify-content: center;
    background: var(--verlauf); color: var(--accent-text);
    border-radius: 8px;
  }
  .phone-link:hover, .phone-link:active {
    background: var(--verlauf-hover); color: var(--accent-text);
  }
  .phone-link .icon { width: 15px; height: 15px; }
  .phone-link .phone-number { display: none; }
}
@media (min-width: 1000px) { .hamburger, .mobile-menu { display: none; } }

/* Vollbild-Ausklappmenü (mobil) — eigener Layer außerhalb des Headers,
   da position:fixed sonst durch header{backdrop-filter} eingeschränkt würde */
.mobile-menu {
  position: fixed;
  top: var(--header-h);
  left: 0; right: 0; bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Mittig steht das Menü über die beiden auto-Ränder weiter unten, nicht
     über justify-content: center. Mit center ragt zu hoher Inhalt oben und
     unten gleich weit heraus, und der obere Teil ist dann auch durch Scrollen
     nicht mehr zu erreichen: Er liegt unter der Kopfzeile. Mit auto-Rändern
     beginnt das Menü in dem Fall einfach oben und lässt sich scrollen. */
  justify-content: flex-start;
  text-align: center;
  gap: 6px;
  padding: 24px 24px 48px;
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(22px);
  -webkit-backdrop-filter: blur(22px);
  border-top: 1px solid var(--border);
  opacity: 0;
  transform: translateY(-10px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 49;
  overflow-y: auto;
}
.mobile-menu.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.mobile-menu a {
  width: 100%; max-width: 320px; padding: 17px 10px; border-radius: 10px;
  text-decoration: none; font-weight: 700; font-size: 19px; color: var(--text);
}
.mobile-menu a:active, .mobile-menu a:hover { background: var(--surface-2); }
/* Aktiver Bereich auch im mobilen Menü sichtbar markieren */
.mobile-menu a.is-active {
  color: var(--accent-ink);
  box-shadow: inset 0 -2px 0 var(--accent-ink);
}
.mobile-menu .mobile-menu-divider { width: 100%; max-width: 320px; height: 1px; background: var(--border); margin: 10px 0; }
.mobile-menu > :first-child { margin-top: auto; }
.mobile-menu > :last-child { margin-bottom: auto; }
/* Niedrige Bildschirme. Seit dem 12.10.2026 hat das Menü mit "Home" neun
   Punkte (Wunsch von Eliah) und ist in voller Größe rund 660px hoch. So viel
   Platz hat ein Handy oft nicht: Mit eingeblendeter Adressleiste bleiben auf
   einem iPhone 13 rund 600px unter der Kopfzeile, auf einem iPhone SE rund
   490px. Deshalb rücken die Punkte dort in zwei Schritten zusammen, bis
   alles ohne Scrollen passt. Die Tippfläche bleibt dabei über 44px hoch. */
@media (max-height: 740px) {
  .mobile-menu { gap: 2px; padding: 12px 24px 20px; }
  .mobile-menu a { padding: 12px 10px; font-size: 18px; }
  .mobile-menu .mobile-menu-divider { margin: 6px 0; }
}
@media (max-height: 600px) {
  .mobile-menu a { padding: 9px 10px; }
}

/* ==========================================================================
   Bild-Fallback ("media-frame") — Sicherheitsnetz fuer die Fotos in Buehne,
   Team und Galerie. Fehlt eine Bilddatei, greift js/script.js
   (Fehlerbehandlung) und blendet dieses dezente, markenkonforme Fallback ein
   statt eines kaputten Bild-Icons.
   ========================================================================== */
.media-frame {
  position: relative;
  overflow: hidden;
  /* Bewusst neutral: Ein türkis eingefärbter Schimmer hinter dem Inhalt ist
     eines der auffälligsten Baukasten-Merkmale. Die Tiefe kommt hier aus
     Helligkeit, nicht aus Farbe. */
  background:
    radial-gradient(120% 140% at 20% 0%, color-mix(in srgb, var(--text) 6%, transparent), transparent 62%),
    linear-gradient(150deg, var(--surface-2), var(--bg));
}
.media-frame .media-fallback {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
}
.media-frame .media-fallback .icon { width: 2.4em; height: 2.4em; opacity: 0.5; }
.media-frame img[data-fallback-img] {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
/* Global: sobald JS ein Bild als fehlend erkannt hat, ausblenden (egal wo verschachtelt) */
img[data-fallback-img].is-broken { display: none; }

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  /* Ton des aufhellenden Schleiers: Seitenhintergrund mit einem Schuss
     Markentuerkis. Hoeher als etwa 14 % wirkt es wie ein Farbfilter. */
  /* Warmer Hauch aus dem Startton des Verlaufs. Bei Rot reicht weniger als
     bei Tuerkis, sonst legt sich ein rosa Schleier ueber das Bild. */
  --hero-schleier: color-mix(in srgb, var(--accent) 7%, var(--bg));

  /* Frueher standen hier eigene dunkle Farbwerte, weil das Hintergrundbild
     dunkel war und die Schrift hell sein musste. Das Bild ist jetzt ein helles
     Studio, also gelten wieder die normalen Werte der Seite: dunkle Schrift.
     Genau das macht den Uebergang nach unten fliessend statt hart. */
  position: relative;
  overflow: hidden;
  /* Volle Bildschirmhoehe. svh statt vh, weil vh auf dem Handy die Adresszeile
     mitrechnet und der Hero beim Ein- und Ausblenden sonst springt. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  /* Platz fuer die schwebende Kopfzeile darueber. */
  padding-top: var(--header-h);
  border-bottom: none;
  /* Fallback, falls das Bild fehlt: heller Verlauf statt dunklem. */
  background: linear-gradient(180deg, var(--surface), var(--bg));
  color: var(--text);
}
.hero-media {
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg, var(--bg) 0%, color-mix(in srgb, var(--bg) 55%, transparent) 46%, color-mix(in srgb, var(--bg) 20%, transparent) 100%),
    /* Ein schmaler, schräg laufender Lichtstreifen – die Andeutung einer
       Spiegelung auf polierter Fläche. Ohne ihn wirkt der Hero wie eine
       leere Platte. */
    linear-gradient(118deg, transparent 40%, color-mix(in srgb, var(--text) 7%, transparent) 52%, transparent 64%),
    radial-gradient(85% 130% at 78% 6%, color-mix(in srgb, var(--text) 13%, transparent), transparent 62%),
    linear-gradient(150deg, #1d1a16, var(--bg));
  z-index: 0;
}
/* Echtes Hero-Bild (falls vorhanden) legt sich als weitere Ebene darüber */
/* Das Auto steht rechts im Bild, links liegt dunkle Freifläche – genau
   dort sitzt die Überschrift. Der Ausschnitt ist deshalb links verankert:
   Was rechts nicht mehr passt, fällt aus dem Rahmen. Nebeneffekt: Kühler-
   grill und Markenemblem liegen außerhalb, das Auto bleibt anonym.

   Der Filter senkt die Tiefen leicht ab, damit der Text auf dem dunklen
   Teil sicher lesbar bleibt. */
.hero-media img[data-fallback-img] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 78 % statt Mitte: Bei vollem Bildschirm ist nur rund ein Drittel der
     Bildbreite sichtbar. Bei 78 % liegt das Auto mittig im Rahmen, Flanke,
     Rad und Scheinwerfer sind zu sehen, und der Kuehlergrill mit dem
     Markenemblem bleibt knapp ausserhalb. */
  object-position: 44% center;
  /* Kein Filter: Das Foto soll im Farbton genau wie das Original aussehen.
     Der fruehere Kontrastfilter war fuer das helle KI-Bild gedacht und machte
     den schwarzen BMW sichtbar dunkler (Hinweis von Eliah, 15.09.2026). */
}
/* Abdunkelnder Schleier ÜBER dem Bild.

   Der Verlauf von .hero-media liegt hinter dem Bild und schützt die Schrift
   deshalb nicht – die Überschrift lief direkt über die helle Fahrzeugfront.
   Dieser Schleier liegt als ::after darüber: links fast deckend, damit der
   Text sicher trägt, nach rechts hin offen, damit Lack und Spiegelungen
   sichtbar bleiben. */
/* Wandernder Lichtreflex über dem Lack.

   Absicht: Glanz nimmt man in Bewegung wahr, nicht im Standbild. Ein sehr
   schmaler, sehr schwacher Streifen zieht langsam über die Fläche, so wie
   eine Werkstattlampe, an der man vorbeigeht.

   Bewusst zurückhaltend gehalten:
   - 9 Sekunden je Durchlauf, dazu eine lange Pause. Schnelleres wirkt wie
     ein Werbebanner.
   - Höchstens 9 % Weiß. Alles darüber sieht nach Glanzeffekt aus statt nach
     Licht auf Lack.
   - Schräg im Winkel der Karosserie, nicht senkrecht.
   - Nur transform wird bewegt, das läuft auf der Grafikkarte und kostet
     keine Rechenzeit beim Scrollen.
   Wer im System reduzierte Bewegung eingestellt hat, sieht ihn gar nicht. */
.hero-glanz {
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: 0;
  width: 26%;
  z-index: 2;
  pointer-events: none;
  transform: translateX(-140%) rotate(9deg);
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 255, 255, 0.045) 38%,
    rgba(255, 255, 255, 0.09) 50%,
    rgba(255, 255, 255, 0.045) 62%,
    transparent 100%
  );
  animation: glanz-zug 14s cubic-bezier(0.4, 0, 0.35, 1) 2.5s infinite;
}
@keyframes glanz-zug {
  0%   { transform: translateX(-140%) rotate(9deg); }
  /* Der Zug selbst dauert rund 9 s, der Rest ist Pause. */
  64%  { transform: translateX(520%)  rotate(9deg); }
  100% { transform: translateX(520%)  rotate(9deg); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-glanz { display: none; }
}

/* Heller Streifen hinter der durchsichtigen Kopfzeile. Oben im Bild liegen
   Hallenfenster mit dunklen Streben und die Dachkante des Fahrzeugs, davor
   waren die Menüpunkte stellenweise kaum zu sehen. Der Verlauf hellt nur
   diesen Streifen auf und läuft nach unten weich aus, das Fahrzeug bleibt
   unberührt. */
.hero-media::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--header-h) + 40px);
  z-index: 1;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--bg) 84%, transparent) 0%,
    color-mix(in srgb, var(--bg) 62%, transparent) 55%,
    transparent 100%
  );
  pointer-events: none;
}

/* Duenner Schleier ueber dem Bild.

   Die Schrift traegt seit dem Umbau auf die weiche Blende (.hero-blende) eine
   eigene Flaeche. Dieser Schleier muss sie deshalb nicht mehr lesbar machen,
   er zieht den Ton nur noch leicht ins Warme und bindet das Bild an die Marke.
   Nach rechts laeuft er aus, damit der Lack dort voll durchkommt. */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(96deg,
    color-mix(in srgb, var(--hero-schleier) 30%, transparent) 0%,
    color-mix(in srgb, var(--hero-schleier) 14%, transparent) 46%,
    transparent 74%);
  pointer-events: none;
}
/* Handy und Tablet hochkant.

   Am Desktop steht der Text links auf der Blende, das Auto rechts daneben.
   Hochkant geht das nicht nebeneinander. Dafuer gibt es ein eigenes hochkantes
   Bild (siehe <picture> in index.html): Die Ueberschrift steht oben auf der
   Blende, das Auto darunter. Die Blende laeuft deshalb hochkant von oben nach
   unten aus statt von links nach rechts.

   Zwei Werte haengen am Bild (1200 zu 2122): die Hoehe der Buehne (176.8vw)
   und die Verankerung des Bildes. Wird das Bild getauscht, beide pruefen,
   die Begruendung steht unten im Block. */
@media (max-width: 999px) {
  /* Die Buehne ist so hoch, dass das hochkante Bild ganz hineinpasst, statt
     sich nach der Texthoehe zu richten. Vorher war sie 540 px hoch, das Bild
     780: Die unteren 240 px samt des weichen Auslaufs wurden abgeschnitten,
     das Foto endete mit einer harten Kante quer durch die Raeder. Bild und
     Blende fuellen jetzt genau diese Hoehe, nichts wird mehr beschnitten.
     Der Deckel von 720 px gilt fuer Tablets hochkant, sonst wuerde die
     Buehne dort ueber den ganzen Bildschirm wachsen. */
  /* padding-top 0: main haelt den Platz fuer die feste Kopfzeile schon frei.
     Das zusaetzliche padding-top des Heros liess auf dem Handy rund 2 cm
     leere Flaeche ueber dem Text. Die Buehne ist dafuer um dieselben 64 px
     niedriger, damit das Auto direkt unter dem Text steht. */
  .hero { align-items: flex-start; min-height: min(calc(176.8vw - 64px), 720px); padding-top: 0; }
  /* Mit .hero davor: Die Grundregel für .hero-inner steht weiter unten in
     der Datei und würde den oberen Abstand sonst wieder überschreiben. */
  /* Der Abstand nach unten macht die Buehne hoeher als der Text allein. Genau
     dieser Streifen zeigt das Fahrzeug: Der Text sitzt oben auf der Blende,
     das Auto steht darunter frei im Bild.

     Der Abstand nach oben ist auf Wunsch von David (15.09.2026) kleiner:
     Zwischen Kopfzeile und "MOBILE LACKAUFBEREITUNG" stand noch ein leerer
     Streifen. Die Buehne bleibt dabei gleich hoch, der Text rueckt nur nach
     oben und gibt dem Foto darunter mehr Platz. */
  .hero > .hero-inner { padding: clamp(14px, 3.6vw, 26px) 20px 190px; }

  /* Das Bild beginnt ganz oben und läuft hinter der Kopfzeile durch. Etwas
     höher als das reine Seitenverhältnis: Dadurch wird es am Rand leicht
     beschnitten, das Auto steht größer im Bild und über ihm bleibt weniger
     leere Halle. */
  .hero .hero-media {
    top: 0;
    bottom: 0;
    height: auto;
    /* Der Auslauf faellt jetzt in die Buehne selbst, deshalb sieht man ihn
       auch: Das Foto geht unten weich in den Abschnitt darunter ueber. */
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 92%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 92%, transparent 100%);
  }
  /* Oben verankert, damit unten nichts vom Auto wegfaellt.

     Die Montage besteht aus zwei Teilen: oben rund 41 Prozent leere
     Seitenfarbe fuer den Text, darunter das Foto. Was nicht in die Buehne
     passt, soll deshalb oben wegfallen, nicht unten. Mit den frueheren 38
     Prozent wurde von beiden Seiten geschnitten: Das Auto rutschte nach oben
     unter die Blende, und auf einem schmalen Handy blieb davon wenig uebrig.

     176.8vw ist die volle Hoehe der Montage (1200 zu 2122). Abzueglich der
     64 px, die die Kopfzeile ohnehin verdeckt, passt sie damit fast genau in
     die Buehne. Wird das Bild getauscht, beide Werte pruefen. */
  .hero .hero-media img[data-fallback-img] { object-position: center 0%; }
  /* Tablets hochkant: Die Buehne ist auf 720 px gedeckelt, das hochkante Bild
     aber viel hoeher. Oben verankert laege das Auto unterhalb der Buehne,
     deshalb hier weiter unten verankern. */
  @media (min-width: 600px) {
    .hero .hero-media img[data-fallback-img] { object-position: center 77%; }
  }
  /* .hero davor, wie bei .hero-inner: Die Grundregeln stehen weiter unten in
     der Datei und wuerden diese Werte sonst wieder ueberschreiben. */
  .hero .hero-media::after {
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--hero-schleier) 24%, transparent) 0%,
      transparent 60%);
  }

  /* Die Blende deckt hochkant den ganzen Textbereich ab und laeuft erst
     darunter aus. So steht jede Zeile auf ruhigem Grund und die vier Punkte
     brauchen keinen eigenen Kasten. Der Wert 68 % liegt knapp unter dem
     letzten Punkt; aendert sich die Texthoehe, hier nachziehen. */
  .hero .hero-blende {
    width: 100%;
    height: auto;
    bottom: 0;
    opacity: 0.96;
    /* Oben deckend fuer die Ueberschrift, darunter nur noch zu gut zwei
       Dritteln: Hinter Unterzeile und den vier Punkten scheint das Foto
       schon durch, die dunkle Schrift bleibt trotzdem gut lesbar. */
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 186px, rgba(0, 0, 0, 0.72) 236px, rgba(0, 0, 0, 0.72) 300px, transparent 340px);
    mask-image: linear-gradient(180deg, #000 0%, #000 186px, rgba(0, 0, 0, 0.72) 236px, rgba(0, 0, 0, 0.72) 300px, transparent 340px);
  }
}

/* ==========================================================================
   Schnellanfrage

   Ein Kasten, der in drei Schritten durch die Anfrage führt. Er steht im
   Abschnitt direkt unter der Bühne (siehe .anfrage-band weiter unten). Wer
   lange scrollen muss, um anzufragen, fragt oft gar nicht an.

   Wichtig für die Grundhaltung: OHNE JavaScript sind alle drei Schritte
   sichtbar und das Formular voll benutzbar. Erst js/script.js blendet sie
   einzeln ein. Andersherum wäre der Kasten ohne Skript unbrauchbar.
   ========================================================================== */
.schnell {
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(14px);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 400px;
}
.schnell-kopf { display: flex; flex-direction: column; gap: 4px; }
.schnell-titel {
  font-family: var(--font-sans);
  font-size: 17px; font-weight: 800; letter-spacing: -0.01em;
  color: var(--text); margin: 0;
}
.schnell-sub { font-size: 12.5px; color: var(--text-muted); margin: 0; }
/* Fortschritt: drei Segmente, das aktuelle trägt den Verlauf. */
.schnell-balken { display: flex; gap: 5px; margin-top: 8px; }
.schnell-balken span {
  flex: 1; height: 3px; border-radius: 3px;
  background: var(--surface-2);
  transition: background 0.3s ease;
}
.schnell-balken span.an { background: var(--verlauf); }

.schritt { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
/* Muss sein: Das eingebaute [hidden] { display: none } der Browser hat
   niedrigere Rangfolge als die Klassenregel darüber. Ohne diese Zeile setzt
   das Skript zwar hidden, sichtbar bleibt der Schritt trotzdem. */
.schritt[hidden] { display: none; }
/* Die drei Schritte liegen übereinander in derselben Rasterzelle, der Kasten
   ist dadurch immer so hoch wie der längste Schritt. Vorher wuchs und
   schrumpfte er bei jedem Klick um bis zu 30 px. Der Hero wuchs mit, und das
   Hintergrundbild, das auf die Hero-Höhe skaliert wird, sprang jedes Mal.
   Die Klasse .gestuft setzt js/script.js; ohne Skript stehen die Schritte
   wie gehabt untereinander. */
.schritte { display: flex; flex-direction: column; gap: 16px; }
.schnell.gestuft .schritte { display: grid; }
.schnell.gestuft .schritt { grid-area: 1 / 1; }
.schnell.gestuft .schritt[hidden] { display: flex; visibility: hidden; }
.schritt legend {
  padding: 0; font-size: 14.5px; font-weight: 700; color: var(--text);
}
.wahl { display: flex; flex-direction: column; gap: 7px; }
.wahl label { position: relative; display: block; cursor: pointer; }
/* Der echte Radioknopf bleibt bedienbar und fokussierbar, liegt aber
   unsichtbar über der Fläche. Sichtbar ist die Karte darunter. */
.wahl input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.wahl span {
  display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--border); border-radius: 9px;
  padding: 11px 13px; font-size: 14px; font-weight: 600; color: var(--text);
  background: var(--surface);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.wahl small { font-size: 11.5px; font-weight: 400; color: var(--text-muted); }
.wahl label:hover span { border-color: var(--accent-ink); }
.wahl input:focus-visible + span { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.wahl input:checked + span {
  border-color: var(--accent-ink);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
}

.felder { display: flex; flex-direction: column; gap: 10px; }
.schnell .f { display: flex; flex-direction: column; gap: 5px; }
.schnell .f span { font-size: 12.5px; color: var(--text-muted); font-weight: 600; }
.schnell .f input {
  font: inherit; font-size: 14px; padding: 11px 13px;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--surface); color: var(--text); width: 100%;
}
.schnell .f input:focus { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.zustimmung { display: flex; gap: 9px; align-items: flex-start; font-size: 12px;
  color: var(--text-muted); line-height: 1.45; }
.zustimmung input { margin-top: 1px; width: 20px; height: 20px; flex-shrink: 0;
  accent-color: var(--accent); }
.zustimmung a { color: var(--accent-ink); }

/* Honigtopf: für Menschen unsichtbar, für automatische Eintragshelfer nicht. */
.falle { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

.schnell-fuss { display: flex; gap: 9px; }
/* "Zurück" nur so breit wie nötig, den Rest bekommt der Hauptknopf. Auf dem
   Handy brach "Anfrage senden" sonst in zwei Zeilen um, der Kasten wurde im
   letzten Schritt 15 px höher und der Hero sprang doch wieder. */
.schnell-fuss .btn { flex: 1; justify-content: center; min-height: 46px; font-size: 14.5px;
  padding-inline: 18px; white-space: nowrap; }
.schnell-fuss .schnell-zurueck { flex: 0 0 auto; }
@media (max-width: 360px) {
  .schnell-fuss .btn { padding-inline: 12px; font-size: 14px; }
}
/* Gleiche Rangfolge-Falle wie beim Schritt: .btn setzt display, das
   ueberstimmt das eingebaute [hidden]. */
.schnell-fuss .btn[hidden] { display: none; }

.hero-inner {
  position: relative;
  z-index: 2;
  /* width: 100% ist noetig, weil .hero display:flex ist und dieser Kasten
     darin als Flex-Element auf seine Inhaltsbreite schrumpft. Ohne die
     Angabe war er nur 1115 statt 1180 breit, zentrierte sich dadurch enger
     und die Ueberschrift stand 33 px weiter rechts als Logo und alle
     Abschnitte darunter. */
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding: 60px 24px 72px;
}
.hero-text { max-width: 540px; }

/* Helle Flaeche hinter dem Text.

   Frueher lag der Text direkt auf dem Foto und brauchte dafuer einen breiten
   aufhellenden Verlauf ueber dem halben Bild. Der liess den Lack fahl wirken.
   Diese Flaeche deckt stattdessen nur die linke Haelfte ab und laeuft ueber
   eine Maske weich aus: links traegt sie die Schrift, rechts ist das Foto
   unberuehrt. */
.hero-blende {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: min(58%, 780px);
  z-index: 1;
  pointer-events: none;
  background: var(--surface);
  opacity: 0.93;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 52%, transparent 100%);
  mask-image: linear-gradient(90deg, #000 0%, #000 52%, transparent 100%);
}

.hero .eyebrow { display: block; margin-bottom: 16px; }
.hero h1 {
  /* Auf eine schmale Spalte begrenzt, damit die Zeile umbricht statt quer
     ueber das ganze Bild zu laufen. Drei kurze Zeilen wirken staerker als
     eine lange. */
  font-size: clamp(32px, 4.3vw, 48px);
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--text);
}
/* Der Verlauf laeuft durch die Schrift. background-clip braucht eine
   durchsichtige Schriftfarbe; als Rueckfall fuer alte Browser steht die
   feste Farbe davor, sonst waere das Wort dort unsichtbar. */
.hero h1 span.accent {
  color: var(--accent-ink);
  background: var(--verlauf);
  -webkit-background-clip: text;
  background-clip: text;
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .hero h1 span.accent { color: transparent; }
}
.hero-sub { font-size: 18px; margin-top: 18px; max-width: 32ch; color: var(--text-muted); }

/* Vier Punkte unter den Knoepfen. Frueher standen sie als Kachelreihe mit
   Rahmen darunter; das war ein zweiter Kasten im ersten Bildschirm. Als
   blosse Zeilen mit Symbol wiegen sie leichter. */
.hero-punkte {
  list-style: none;
  margin: 32px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
}
.hero-punkte li { display: flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 600; }
.hero-punkte .icon { width: 19px; height: 19px; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Vierter Punkt: die Innenaufbereitung (Wunsch von David, 27.09.2026).

   Er steht ueber die volle Breite unter den drei anderen, nicht daneben:
   flex-basis 100 Prozent schiebt ihn in eine eigene Zeile. Er ist ein Link auf
   den Abschnitt weiter unten, denn der hat sonst keinen Einstieg, weder in der
   Navigation noch ueber einen Knopf.

   Die Marke traegt dieselbe volle Akzentflaeche wie die Marke an der
   Ueberschrift des Abschnitts, nur kleiner: Es soll erkennbar dasselbe sein.
   -------------------------------------------------------------------------- */
.hero-punkte .hero-punkt-neu { flex: 0 0 100%; margin-top: 4px; }
.hero-punkt-neu a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
  border-radius: 999px;
}
.hero-punkt-neu a:hover span:last-child { text-decoration: underline; }
.hero-neu-marke {
  flex-shrink: 0;
  padding: 4px 11px 3px;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent-text);
  background: var(--verlauf);
  border-radius: 999px;
}
/* Auf schmalen Geraeten liegt der Punkt schon ueber dem Foto. Damit die Zeile
   dort nicht dreimal umbricht, faellt der zweite Halbsatz weg. */
@media (max-width: 560px) {
  .hero-punkt-neu a { gap: 8px; }
  .hero-punkt-neu span:last-child { font-size: 14px; }
}

/* ==========================================================================
   Anfrage-Band unter der Buehne

   Das Formular stand frueher als Kasten im Hero ueber der Fahrzeugfront.
   Hier hat es einen eigenen ruhigen Abschnitt.

   Bis zum 15.09.2026 stand links eine Ansage mit der Ueberschrift und rechts
   das Formular. Auf Wunsch von David traegt jetzt die Kachel selbst die
   Ueberschrift, der beschreibende Satz steht darunter. Damit faellt die
   zweite Spalte weg und alles steht mittig untereinander.
   ========================================================================== */
.anfrage-band {
  padding: 60px 0 68px;
  /* Derselbe Ton wie "Was wir fuer Ihren Lack tun" darunter. Das Grau von
     --surface-2 setzte hier einen Riegel zwischen Buehne und Seite. */
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.anfrage-grid { display: grid; }
/* Kachel, Hinweis und Telefonzeile stehen als eine mittige Spalte. Die Breite
   entspricht der Kachel, sonst liefen die beiden Zeilen darunter ueber die
   ganze Seite. */
.anfrage-spalte {
  display: flex; flex-direction: column; gap: 10px;
  width: 100%; max-width: 400px; margin-inline: auto;
}
/* Klammer um beide Zeilen. Hochkant faellt sie nicht auf: Der Abstand ist
   derselbe wie zwischen Kachel und Zeilen vorher. */
.anfrage-fuss { display: flex; flex-direction: column; gap: 10px; }
/* Beide Zeilen unter der Kachel sind bewusst klein: Sie erklaeren und bieten
   einen Nebenweg an, die Hauptaufforderung ist die Kachel selbst. */
.anfrage-hinweis {
  font-size: 14.5px; color: var(--text-muted); margin: 0; text-align: center;
}
.anfrage-tel { font-size: 13px; color: var(--text-muted); margin: 0; text-align: center; }
.anfrage-tel a { color: var(--accent-ink); font-weight: 700; }
.anfrage-band .schnell { margin: 0; max-width: none; }
/* Die Kachel traegt hier die Ueberschrift des Abschnitts, deshalb etwas
   groesser als der Kachel-Titel sonst. */
.anfrage-band .schnell-titel { font-size: 20px; }
.anfrage-band .schnell-balken { margin-top: 0; }
/* --------------------------------------------------------------------------
   Nur Rechner: Anfrage-Kachel neben dem Slogan

   Auf Wunsch von David (15.09.2026) steht die Kachel auf dem Rechner rechts
   in der Buehne statt in einem eigenen Abschnitt darunter. Sie wird dafuer
   aus dem Fluss genommen und in .buehne gehaengt, die Buehne selbst behaelt
   dadurch ihre Hoehe.

   Alles hier steht bewusst hinter (min-width: 1000px): Auf Handygroesse
   aendert sich nichts, dort bleibt der Abschnitt genau wie er ist.

   Die Klammer laesst Klicks durch (pointer-events), sonst laege sie als
   unsichtbare Flaeche ueber der ganzen Buehne. Nur die Kachel selbst faengt
   sie wieder ein.
   -------------------------------------------------------------------------- */
@media (min-width: 1000px) {
  .buehne { position: relative; }
  .buehne .anfrage-band {
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    transform: translateY(-50%);
    padding: 0;
    background: none;
    border-bottom: none;
    pointer-events: none;
    z-index: 3;
  }
  .buehne .anfrage-spalte {
    margin-inline: auto 0;
    pointer-events: auto;
  }
  /* Eigene helle Flaeche, im selben Material wie die Kachel darueber: Die
     beiden Zeilen liegen hier ueber dem Foto, mal auf hellem Hallenboden,
     mal auf dem dunklen Rad. Ohne die Flaeche waeren sie stellenweise nicht
     zu lesen. */
  .buehne .anfrage-fuss {
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 10px 14px;
    gap: 6px;
  }
  /* Der Text links braucht die Breite der Kachel nicht mehr zu teilen, sonst
     liefe die Ueberschrift unter die Kachel. */
  .buehne .hero-text { max-width: min(540px, calc(100% - 440px)); }
}

/* Hochkant enger: Der Abschnitt hatte viel Luft zwischen Ansage und Kachel,
   dazu grosse Raender oben und unten und reichlich Polster in der Kachel.
   Die Auswahlfelder tragen den groessten Anteil, drei Stueck zu je 67 px.
   Von 719 ueber 598 auf rund 500 px. */
@media (max-width: 999px) {
  .anfrage-band { padding: 26px 0 28px; }
  .anfrage-band .schnell-titel { font-size: 18px; }
  .anfrage-hinweis { font-size: 13.5px; }
  .anfrage-band .schnell { padding: 16px; gap: 12px; }
  .anfrage-band .wahl { gap: 6px; }
  .anfrage-band .wahl span { padding: 8px 12px; font-size: 13.5px; }
  .anfrage-band .wahl small { font-size: 11px; }
  .anfrage-band .schnell legend { font-size: 14px; }
  .anfrage-band .schnell-fuss .btn { min-height: 42px; }
  .anfrage-spalte, .anfrage-fuss { gap: 8px; }
}

/* ==========================================================================
   Generic section
   ========================================================================== */
.section { padding: 84px 0; border-bottom: 1px solid var(--border); }
.section-head { max-width: 680px; margin-bottom: 48px; }
.section-head p { margin-top: 14px; }
.section-alt { background: var(--surface); }

/* Scroll-Reveal (dezent, respektiert prefers-reduced-motion)
   WICHTIG: Der unsichtbare Ausgangszustand gilt nur, wenn JavaScript läuft
   (Klasse .js wird von js/script.js sofort gesetzt). Ohne JavaScript ist
   alles von Anfang an sichtbar – sonst bliebe die halbe Seite bei einem
   Skriptfehler dauerhaft leer. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.js [data-reveal].is-visible { opacity: 1; transform: translateY(0); }
.js [data-reveal-group] > * { transition-delay: calc(var(--reveal-i, 0) * 60ms); }

/* ==========================================================================
   Leistungen
   ========================================================================== */
.grid-services {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
.service-card {
  flex: 1 1 270px;
  background: var(--surface);
  padding: 15px 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Drei Kacheln: ab mittlerer Breite alle drei nebeneinander. Bis zum
   17.09.2026 waren es vier, die standen zu zweit in zwei Reihen. Mit drei
   Kacheln ergäbe dieselbe Regel zwei oben und eine allein über die volle
   Breite darunter. */
@media (min-width: 900px) {
  .service-card { flex-basis: calc(33.333% - 1px); }
}
.section-alt .service-card { background: var(--bg); }
/* Icon frei stehend statt im getönten Quadrat – das Kachel-im-Kästchen-
   Muster ist eines der deutlichsten Vorlagen-Merkmale. So wirkt die Karte
   ruhiger und die Überschrift führt. */
.service-icon {
  color: var(--text-muted);
  display: flex; align-items: center;
  width: fit-content;
  margin-bottom: 2px;
}
.service-icon .icon { width: 26px; height: 26px; stroke-width: 1.5; }
.service-card h3 { font-size: 19px; text-transform: none; }
/* Empfehlungsmarke an der Leistung, die wir am häufigsten raten. Es ist die
   einzige Stelle, an der wir dem Kunden eine Richtung geben, deshalb darf sie
   die Akzentfarbe tragen. Nach den Farbregeln aber nur als Schrift und Linie
   auf einer sehr blassen Fläche, nicht als volle Farbfläche. */
/* Hervorgehobene Kachel: Die Lackversiegelung ist in jeder Aufbereitung
   enthalten und kostet nichts extra. Das soll auffallen (Wunsch von David,
   17.09.2026). Die Kachel bekommt dafür eine sehr blasse Fläche in der
   Akzentfarbe, genau wie die hervorgehobene Zeile in der Preistafel, und ihr
   Symbol die Akzentfarbe. Die Marke daneben bleibt bewusst ruhig und grau:
   Die Akzentfarbe als Schrift gehört der Empfehlung bei der Lackkorrektur,
   zwei farbige Marken nebeneinander schwächen beide. */
.service-card.kachel-hervor { background: color-mix(in srgb, var(--accent) 7%, var(--surface)); }
.section-alt .service-card.kachel-hervor { background: color-mix(in srgb, var(--accent) 7%, var(--bg)); }
.service-card.kachel-hervor .service-icon { color: var(--accent-ink); }
.service-inklusive {
  display: inline-block;
  vertical-align: 2px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
}

.service-tipp {
  display: inline-block;
  vertical-align: 2px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent-ink);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: 999px;
}
/* Überschrift und Marke als umbrechende Reihe: Passt die Marke nicht mehr
   daneben, beginnt sie in der nächsten Zeile bündig links, statt um ihren
   Abstand eingerückt zu stehen. */
:is(h3, dt):has(> .service-tipp), :is(h3, dt):has(> .service-inklusive) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
}
.service-card p { font-size: 14.5px; margin: 0; }
/* Schlichter Zusatz unter der Beschreibung. Der graue Kasten von früher
   stammte aus der Platzhalter-Kennzeichnung und wirkte wie ein Fremdkörper.
   Der Hinweis steht vor der Ergebniszeile, damit diese wie in den anderen
   Karten unten abschließt. */
.service-card .service-note { font-size: 13.5px; color: var(--text-muted); }

/* Aufklappbare Kacheln (Vor-Ort-Service, Versiegelung): Symbol und Überschrift
   sind der Schalter, der Text erscheint erst nach dem Aufklappen. Derselbe
   Pfeil wie im FAQ. */
.kachel-klapp summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  row-gap: 10px;
  column-gap: 12px;
}
.kachel-klapp summary::-webkit-details-marker { display: none; }
.kachel-klapp summary .service-icon { grid-column: 1 / -1; }
.kachel-klapp summary:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 6px; border-radius: 4px; }
.kachel-klapp .kachel-pfeil { width: 20px; height: 20px; color: var(--text-muted); transition: transform 0.2s ease, color 0.2s ease; }
.kachel-klapp summary:hover .kachel-pfeil { color: var(--text); }
.kachel-klapp[open] .kachel-pfeil { transform: rotate(180deg); }
.kachel-text { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }

/* ==========================================================================
   Preise
   ========================================================================== */
.price-intro { max-width: 74ch; }


/* Preisklassen: vier Karten statt einer Tabelle mit fünfzehn Feldern.

   Der Kunde kann von sich aus nicht beurteilen, ob sein Lack ein-, zwei-
   oder mehrstufig behandelt werden muss. Eine Auswahl an dieser Stelle
   bremst ihn nur – er soll lediglich seine Fahrzeuggröße wiederfinden.
   Der Umfang wird bei der kostenlosen Sichtprüfung vor Ort festgelegt.

   Gleiche Bauweise wie die Leistungskarten: ein zusammenhängender Block
   mit Haarlinien dazwischen, statt einzeln schwebender Kacheln. */
.preis-klassen {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
/* flex-basis statt fester Spaltenzahl: Die letzte Reihe füllt damit
   immer die volle Breite, es bleiben keine leeren Felder stehen. */
.preis-klasse {
  flex: 1 1 260px;
  background: var(--surface);
  padding: 24px 22px;
}
.section-alt .preis-klasse { background: var(--bg); }
.preis-klasse h3 { font-size: 16px; text-transform: none; margin-bottom: 3px; }
.preis-klasse .beispiele {
  display: block;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted);
  margin-bottom: 18px;
}
/* Stufen je Klasse. Links ein Balken aus drei Teilen, gefüllt so viele wie
   Stufen, in der Mitte Leistung und Stufenzahl, rechts der Betrag. So erfasst
   man den Aufbau, ohne zu lesen: Jede Stufe mehr heisst ein Balken mehr und
   90 € mehr. */
.stufen { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.stufen li {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
  margin: 0 -10px;
  padding: 9px 10px;
  border-radius: 8px;
  transition: background 0.15s, scale 0.18s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.18s ease;
}
.stufen li.hervorgehoben { background: color-mix(in srgb, var(--accent) 7%, transparent); }
/* Jede Zeile ist ein Link auf das Kontaktformular (seit 12.10.2026, Wunsch von
   Eliah): anklicken, unten ankommen, die Auswahl steht schon im Formular. Der
   Link sitzt am Namen der Leistung, sein ::after deckt die ganze Zeile ab. So
   bleibt der Aufbau der Zeile, wie er war, und trotzdem lässt sie sich
   überall anklicken. Der Fokusrahmen liegt deshalb ebenfalls um die ganze
   Zeile und nicht nur um den Namen. */
a.stufen-name { text-decoration: none; }
a.stufen-name::after { content: ""; position: absolute; inset: 0; border-radius: 8px; }
a.stufen-name:focus-visible { outline: none; }
a.stufen-name:focus-visible::after { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.stufen li:active, .stufen li.gedrueckt { background: var(--surface-2); }
.stufen li.hervorgehoben:active, .stufen li.hervorgehoben.gedrueckt { background: color-mix(in srgb, var(--accent) 13%, transparent); }
/* Die angeklickte Zeile wird kurz etwas größer und hebt sich ab (Wunsch von
   Eliah, 13.10.2026). Beim Drücken greift :active, danach hält die Klasse
   .gedrueckt den Zustand einen Moment fest: initPreisWahl in js/script.js
   setzt sie und springt erst kurz danach zum Formular, sonst wäre die Zeile
   schon aus dem Bild, bevor man etwas sieht.
   Bewusst die Eigenschaft scale und nicht transform: An transform hängt der
   Scroll-Übergang, mit dem die Zeilen auftauchen, der würde hiermit
   überschrieben.
   Wie stark die Zeile wächst, steht in --druck. Das Skript rechnet den Wert
   je Zeile aus: bis zu 8px je Seite, aber nie mehr, als bis zum Rand der
   Karte Platz ist. Auf dem Handy sind das nur 6px, und .preis-klassen
   schneidet alles ab, was darüber hinausragt. Eine feste Prozentzahl ginge
   deshalb nicht: Steht eine Karte allein in ihrer Reihe, ist die Zeile über
   1000px breit, und schon 3 % wären 16px je Seite. Ohne JavaScript gilt der
   vorsichtige Ersatzwert. */
@media (prefers-reduced-motion: no-preference) {
  .stufen li:active, .stufen li.gedrueckt {
    scale: var(--druck, 1.02);
    z-index: 1;
    box-shadow: 0 10px 22px -12px rgba(0, 0, 0, 0.35);
  }
}
/* Kleiner Pfeil hinter dem Namen der Leistung. Er zeigt auch auf dem Handy,
   wo es kein Überfahren gibt, dass man die Zeile antippen kann. Er steht
   bewusst dort und nicht am Zeilenende hinter dem Betrag: Dort nähme er der
   Unterzeile rund 20px, und "1 Stufe, bei leichten Gebrauchsspuren" bräche
   am Rechner um. Hinter dem Namen ist der Platz ohnehin frei. */
.stufen-titel { display: inline-flex; align-items: center; gap: 3px; }
.stufen-pfeil {
  width: 12px; height: 12px;
  flex-shrink: 0;
  color: var(--text-muted);
  transform: rotate(-90deg);
  transition: transform 0.15s, color 0.15s;
}
/* Nur mit Maus: Auf dem Handy bliebe die Zeile nach dem Antippen markiert. */
@media (hover: hover) {
  .stufen li:hover { background: var(--surface-2); }
  .stufen li.hervorgehoben:hover { background: color-mix(in srgb, var(--accent) 13%, transparent); }
  .stufen li:hover .stufen-pfeil { color: var(--accent-ink); transform: rotate(-90deg) translateY(2px); }
}
/* Ein Satz über der Preistafel, der sagt, dass man die Zeilen anklicken kann. */
.preis-tipp { font-size: 13px; color: var(--text-muted); max-width: none; }
.preis-tipp + .preis-klassen { margin-top: 10px; }
.stufen-balken { display: inline-flex; gap: 3px; }
.stufen-balken span { width: 11px; height: 5px; border-radius: 3px; background: var(--border); }
.stufen-balken span.an { background: var(--verlauf); }
.stufen-name {
  display: flex;
  flex-direction: column;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text);
}
.stufen-name small { font-size: 11.5px; font-weight: 500; color: var(--text-muted); }
.stufen-preis {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--text);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Aufschlag je weiterer Stufe: kleiner und in der Akzentfarbe, damit der
   Einstiegspreis der Anker bleibt */
.stufen-preis.stufen-aufschlag { font-size: 16px; color: var(--accent-ink); }

/* Hier standen bis zum 07.10.2026 die Regeln fuer .angebote, den Block
   "Unsere Angebote" ueber der Preistafel. Er ist auf Wunsch von David
   ersatzlos entfallen, die Regeln sind damit ebenfalls weg. */

.preis-hinweis {
  margin-top: 16px;
  font-size: 13px;
  color: var(--text-muted);
  max-width: 68ch;
}



/* ==========================================================================
   Ablauf
   ========================================================================== */
.process-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
}
.process-step {
  flex: 1 1 190px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: relative;
}
.process-num {
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 13px;
  color: var(--accent-text);
  background: var(--accent);
  width: 30px; height: 30px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.process-step h3 { font-size: 15.5px; text-transform: none; }
.process-step p { font-size: 13.5px; margin: 0; }
/* Hinweis zur Wäsche unter den drei Schritten. Kein eigener Kasten: Er gehört
   zum Ablauf darüber und soll ihn nicht als vierter Schritt verlängern. */
.ablauf-hinweis {
  margin: 18px 0 0;
  font-size: 14px;
  max-width: 66ch;
}

/* ==========================================================================
   Vorher / Nachher
   ========================================================================== */
/* Drei Reihen untereinander: zuerst Vorher und Nachher, dann nur
   Nachher-Videos, dann nur Nachher-Fotos (Vorgabe von Eliah und David,
   15.09.2026). */
.compare-grid {
  display: grid;
  gap: 28px;
}
.compare-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: var(--shadow);
}
/* Fotoreihe: Die Karten sind gleich hoch und nichts wird beschnitten. Jede
   Karte wächst im Verhältnis ihres Bildformats, --format ist Breite durch
   Höhe (ein Paar aus zwei 3:4-Hälften hat 1.5). Auf dem Handy untereinander. */
.vn-reihe {
  display: flex;
  align-items: flex-start;
  gap: inherit;
}
.vn-reihe > * { flex: var(--format, 1) 1 0%; min-width: 0; }
@media (max-width: 760px) {
  .vn-reihe { flex-direction: column; align-items: stretch; }
  .vn-reihe > * { flex: none; }
}
.vn-ganz { position: relative; aspect-ratio: var(--format, 3 / 2); background: var(--surface-2); }
.vn-ganz img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* Vorher und Nachher stehen fest nebeneinander, ohne Schieberegler: Ältere
   Kunden sollen nichts ziehen oder wischen müssen (Vorgabe von Eliah,
   15.09.2026). Jede Hälfte ist 3:4. Bildunterschriften gibt es bewusst nicht. */
.vn-paar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px;
  background: var(--border);
}
.vn-bild { position: relative; overflow: hidden; aspect-ratio: 3 / 4; background: var(--surface-2); }
.vn-bild img,
.vn-bild video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* Die Stempel VORHER und NACHHER auf den Bildern sind am 18.10.2026 auf
   Wunsch von David überall entfallen, mit ihnen die Klassen .compare-tag,
   .tag-before und .tag-after. Links steht in den Paaren weiterhin das
   Vorher-Bild und rechts das Nachher-Bild, das sagt jetzt nur noch der
   Alternativtext. Nicht ohne Rückfrage wieder einbauen. */

/* Volle Reihen: am Rechner Wabenlicht und zwei Videos gleich hoch.
   Auf dem Handy das Vergleichsbild darüber, beide Videos nebeneinander. */
@media (max-width: 760px) {
  .galerie-rest-reihe {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  /* Alles ausser den beiden Videos nimmt die ganze Breite: das
     Vergleichsfoto und, seit dem 18.10.2026, auch das Prüflampen-Paar, das
     in diese Reihe gerückt ist. In einer halben Spalte wären seine beiden
     Hälften briefmarkengross. */
  .galerie-rest-reihe > :not(.video-card) { grid-column: 1 / -1; }

  /* Die drei hochkanten Nachher-Fotos am Ende nahmen hochkant jedes fuer
     sich den ganzen Bildschirm ein, zusammen rund 1400 px Scrollweg
     (gemeldet von David am 18.10.2026). Sie stehen deshalb zu zweit
     nebeneinander, das dritte darunter mittig in derselben Breite. Aus
     1414 px werden so rund 540 px, beschnitten wird nichts. */
  .galerie-fotoreihe {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
  /* Bleibt eine ungerade Zahl uebrig, steht das letzte Foto allein in der
     Zeile. Es bekommt dann die volle Zeile, aber nur halbe Breite und steht
     mittig, sonst klebte es links. Bei gerader Zahl greift die Regel nicht,
     dann ist die Reihe von selbst voll. */
  /* Alle Fotos dieser Reihe bekommen hochkant dasselbe Seitenverhaeltnis,
     sonst stehen in einer Zeile zwei verschieden hohe Karten nebeneinander
     und darunter klafft eine Luecke (gemeldet von David am 18.10.2026).
     Was nicht ins 3:4 passt, wird mittig beschnitten, nicht gestaucht. */
  .galerie-fotoreihe > * { aspect-ratio: 3 / 4; }
  .galerie-fotoreihe > :last-child:nth-child(odd) {
    grid-column: 1 / -1;
    justify-self: center;
    width: calc(50% - 6px);
  }
}

/* Ein Vergleichsfoto liess sich bis zum 15.09.2026 per CSS spiegeln
   (Klasse gespiegelt). Das neue Foto liegt richtig herum, VORHER links und
   NACHHER rechts, deshalb ist die Regel entfernt. */

/* Videoreihe: vier Hochkant-Videos nebeneinander, auf dem Handy zwei mal
   zwei. Derselbe Kartenrahmen wie bei den Fotos; die Videos laufen stumm in
   Schleife, gesteuert in js/script.js, initVideos. */
.video-reihe {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: inherit;
}
@media (max-width: 560px) {
  .video-reihe { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* --------------------------------------------------------------------------
   Folge der Loeschungen vom 27.09.2026 und 12.10.2026 (Wunsch von David).

   Die Videoreihe hat vier Spalten und seit dem 27.09.2026 nur noch zwei
   Karten. Ohne diese Regel klebten beide Videos links und rechts blieben
   zwei leere Spalten. Sie ruecken in die mittleren beiden Spalten und
   behalten dabei genau die Groesse, die sie vorher hatten. Zwei Spalten
   statt vier waere die andere Moeglichkeit, dann waeren die Videos aber
   ueber tausend Pixel hoch, und genau das soll in einer Reihe nicht
   passieren. Kommen die Videos zurueck, kann die Regel ersatzlos weg.

   Hochkant aendert sich nichts, dort stehen die zwei Videos ohnehin
   nebeneinander.

   Hier stand bis zum 12.10.2026 eine zweite Regel: Die Vorher-Nachher-Reihe
   mit nur einer Karte wurde mittig gesetzt und auf 560 px begrenzt, sonst
   waere das allein verbliebene Prueflampen-Paar doppelt so gross gewesen wie
   die Paare darueber. Mit dem Parksensor-Paar ist am 12.10.2026 die zweite
   Karte der ersten Reihe weggefallen; das Prueflampen-Paar ist in diese Reihe
   hinaufgerueckt, es gibt also keine Reihe mit nur einer Karte mehr und die
   Regel war ohne Wirkung. Wird wieder eine Reihe einzeln besetzt, gehoert sie
   zurueck.
   -------------------------------------------------------------------------- */
@media (min-width: 561px) {
  .video-reihe:has(> :nth-child(2):last-child) > :first-child { grid-column: 2; }
}

.video-rahmen {
  position: relative;
  overflow: hidden;
  aspect-ratio: 9 / 16;
  background: #111;
}
.video-rahmen video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}


/* ==========================================================================
   Vierte Leistungskachel und Abschnitt Innenaufbereitung
   Live seit dem 27.09.2026, Wunsch von David. Entstanden als Entwurf
   vorschau/lack-innen, gebaut mit werkzeuge/lack-innen-bauen.py.
   ========================================================================== */
/* ---------------------------------------------------------------------------
   Vier Kacheln statt drei.

   Von Haus aus haben die Kacheln flex-basis 270px. Mit vier Stueck passen sie
   am Rechner gerade noch alle in eine Reihe, dann bleiben je rund 225px fuer
   den Text und die Ueberschrift "Kostenfreie Lackversiegelung" bricht drei
   Mal um. Ab 720px stehen sie deshalb zu zweit in zwei Reihen, genau wie bis
   zum 17.09.2026, als es schon einmal vier waren. Darunter greift wieder die
   Regel der Website.
   --------------------------------------------------------------------------- */
@media (min-width: 720px) {
  .grid-services > .service-card { flex: 1 1 calc(50% - 1px); }
}

/* Die Scroll-Staffelung der Website zaehlt nur bis zur dritten Kachel, die
   vierte bekaeme sonst den Startwert der ersten und liefe vor ihrer Nachbarin
   los. Dieselbe Reihenfolge wie im Block "Scroll-Uebergaenge" in style.css. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .grid-services > :nth-child(4) { --sg-k: 3; }
  }
}

/* ---------------------------------------------------------------------------
   Marke "Jetzt neu" an der Ueberschrift.

   David wollte sie am 27.09.2026 deutlich auffaelliger: volle Flaeche im
   Marken-Verlauf mit weisser Schrift, groesser gesetzt und leicht angehoben.

   Das weicht bewusst von der Farbregel ab, nach der die Akzentflaeche den
   Handlungen gehoert. Es ist die einzige volle Farbflaeche im Abschnitt und
   steht weit weg von der Empfehlung bei der Lackkorrektur, die beiden
   schwaechen sich also nicht gegenseitig. Verlauf und weisse Schrift sind
   dieselben wie bei .btn-primary, damit nichts Neues erfunden wird.
   --------------------------------------------------------------------------- */
.marke-neu {
  display: inline-block;
  vertical-align: 0.32em;
  margin-left: 13px;
  padding: 8px 18px 7px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent-text);
  background: var(--verlauf);
  border-radius: 999px;
  /* Kein Ring und kein Schein (Wunsch von David, 27.09.2026). Eine
     Zwischenfassung hatte beides aus zwei Schatten, zusammen mit 19 px
     Schrift war das zu viel. Die volle Akzentflaeche traegt die
     Aufmerksamkeit allein, das reicht. */
}
/* Hochkant unter die Ueberschrift, sonst wird die Zeile zu lang und
   "Innenaufbereitung" bricht mitten im Wort. */
@media (max-width: 620px) {
  .innen-neu .section-head h2 .marke-neu {
    display: block;
    margin: 12px 0 0;
    width: fit-content;
    vertical-align: baseline;
  }
}

/* ---------------------------------------------------------------------------
   Die Karte mit den sechs Punkten.

   Dieselbe Flaeche, derselbe Rahmen und derselbe Radius wie bei den
   Leistungskacheln, damit der neue Abschnitt nicht wie ein Fremdkoerper wirkt.
   --------------------------------------------------------------------------- */
.innen-karte {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px 26px 20px;
}

/* Die sechs Positionen stehen bewusst gedraengt, damit der ganze Abschnitt
   auf dem Handy ohne langes Scrollen zu ueberblicken ist (Wunsch von David,
   27.09.2026). Gestaucht wird ueber die Form, nicht ueber den Inhalt:
   gestrichen ist nichts.

   Der Hebel ist die Zeile selbst. Ueberschrift und Erklaerung standen
   untereinander, das waren hochkant vier Zeilen je Position. Jetzt laufen sie
   mit einem Doppelpunkt in einem Absatz, das sind drei. Dazu engere Abstaende
   und die zweite Spalte schon ab 700 px statt ab 760 px. */
.innen-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px 32px;
}
@media (min-width: 700px) {
  .innen-liste { grid-template-columns: 1fr 1fr; }
}
.innen-liste li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.innen-liste .icon {
  width: 17px;
  height: 17px;
  stroke-width: 2.4;
  color: var(--accent-ink);
  margin-top: 3px;
}
.innen-liste strong {
  font-weight: 700;
  color: var(--text);
}
.innen-liste span {
  font-size: 15px;
  line-height: 1.45;
  color: var(--text-muted);
}

/* Die Trennlinie haengt an der Liste und nicht am Satz darunter: Der Satz ist
   auf 62 Zeichen begrenzt, damit die Zeile lesbar bleibt, und eine Linie an
   ihm wuerde deshalb mitten in der Karte aufhoeren. */
.innen-liste {
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.innen-fuss {
  margin: 15px 0 0;
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--text-muted);
  max-width: 62ch;
}

/* ==========================================================================
   Über uns
   ========================================================================== */
.about-photo {
  aspect-ratio: 4 / 5;
  border-radius: 14px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}
.about-photo .media-fallback { flex-direction: column; gap: 10px; }
.about-photo .media-fallback span { font-size: 12.5px; font-family: var(--font-mono); letter-spacing: 0.04em; }
.signature { font-weight: 700; color: var(--text); font-size: 15px; margin: 4px 0 0; }

/* ==========================================================================
   Über-uns-Seite (eigene Seite statt Abschnitt auf der Startseite –
   dadurch bekommt sie Raum und wirkt persönlicher)
   ========================================================================== */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 34px 0 12px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.15s, gap 0.15s;
}
.back-link:hover { color: var(--accent-ink); gap: 11px; }
.back-link .icon { width: 1.05em; height: 1.05em; }

.about-page { padding-bottom: 90px; }
.about-page-intro { max-width: 640px; margin-bottom: 44px; }
.about-page h1 {
  font-size: clamp(30px, 4.4vw, 46px);
  line-height: 1.06;
  letter-spacing: -0.03em;
}

.about-page-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 56px;
  align-items: start;
}
@media (max-width: 900px) { .about-page-grid { grid-template-columns: 1fr; gap: 34px; } }

/* Zweites Foto auf „Über uns“: Eliah bei der Arbeit, unter dem Text. Quer
   zugeschnitten, damit die Textspalte nicht zu lang wird; Kopf und
   Poliermaschine bleiben im Bild. Am Computer bleibt das Gründerfoto beim
   Scrollen stehen, solange die längere Textspalte daneben durchläuft. */
.about-arbeit { aspect-ratio: 4 / 3; margin-top: 14px; }
.about-arbeit img[data-fallback-img] { object-position: 50% 38%; }
@media (min-width: 901px) {
  .about-page-grid > .about-photo { position: sticky; top: calc(var(--header-h) + 24px); }
}

.about-page-text { display: flex; flex-direction: column; gap: 18px; }
.about-page-text > p { font-size: 15.5px; margin: 0; }
/* Kleine Zwischenüberschriften gliedern den Text in drei Gedanken:
   wie es anfing, warum wir zu Ihnen kommen, was Sie vorher hören.
   Der Abstand nach oben ist größer als der nach unten, damit jede
   Überschrift sichtbar zu ihrem Absatz gehört. */
.about-page-text > h2 {
  font-size: 17px;
  letter-spacing: -0.01em;
  margin: 16px 0 -4px;
  color: var(--text);
}
.about-page-text > h2:first-child { margin-top: 0; }

.about-cta {
  margin-top: 56px;
  padding-top: 34px;
  border-top: 1px solid var(--border);
}
.about-cta > p { font-size: 16px; margin: 0 0 18px; }
.about-cta-buttons { display: flex; flex-wrap: wrap; gap: 14px; }
@media (max-width: 480px) { .about-cta-buttons .btn { flex: 1 1 auto; justify-content: center; } }
.trust-points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.trust-points li { display: flex; gap: 12px; font-size: 15px; align-items: flex-start; }
.check-badge {
  flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
  background: var(--surface-2); color: var(--text);
  display: flex; align-items: center; justify-content: center; margin-top: 1px;
}
.check-badge .icon { width: 0.85em; height: 0.85em; stroke-width: 2.4; }

/* ==========================================================================
   Bewertungen
   ========================================================================== */

/* ---------- Laufband mit Google-Rezensionen ----------

   Die Karten laufen langsam nach links. Der nahtlose Umbruch entsteht
   dadurch, dass jede Karte zweimal in der Spur steht und die Animation um
   genau die halbe Spurbreite schiebt.

   Drei Dinge halten das Laufband fuer aeltere Kundinnen und Kunden
   benutzbar: Es haelt an, sobald eine Maus darueber liegt, ein Finger es
   beruehrt oder jemand mit der Tastatur hineingeht, und es steht komplett
   still, wenn im System weniger Bewegung eingestellt ist. Dann und nur dann
   laesst es sich von Hand schieben, siehe .laufband weiter unten. Gelesen
   wird also nie unter Zeitdruck. */
.rezensionen { margin-bottom: 38px; }
.rezensionen-kopf {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 10px 24px;
  margin-bottom: 26px;
}
.rezensionen-kopf h2 { font-size: clamp(24px, 3.2vw, 34px); }
.rezensionen-kopf a { font-size: 15px; font-weight: 700; color: var(--accent-ink); }

.laufband {
  /* Nach aussen hin laufen die Karten weich aus, statt an einer harten Kante
     abgeschnitten zu werden. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);

  /* Eine ganz gewoehnliche seitliche Bildlaufflaeche.

     Frueher schob eine CSS-Animation die Spur per transform. Wischte jemand
     zusaetzlich mit dem Finger, addierten sich beide Wege und die Leiste lief
     ins Leere. Jetzt gibt es nur noch einen Weg: js/script.js zaehlt
     scrollLeft hoch. Wischen und Selbstlauf teilen sich damit dieselbe
     Mechanik und koennen sich nicht mehr gegenseitig verschieben.

     Ohne JavaScript bewegt sich nichts von selbst, wischen geht trotzdem. */
  overflow-x: auto;
  overflow-y: hidden;
  /* html hat scroll-behavior: smooth. Geerbt wird das zwar nicht, aber
     explizit auto stellt sicher, dass der Sprung am Umlauf hart erfolgt und
     nicht als sichtbares Gleiten. */
  scroll-behavior: auto;
  /* Ein Wisch am Rand soll nicht die Seite zurueckblaettern. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.laufband::-webkit-scrollbar { display: none; }
.laufband-spur {
  display: flex;
  gap: 18px;
  width: max-content;
}
/* Bei "weniger Bewegung" laeuft nichts von selbst, das entscheidet
   js/script.js. Gewischt werden darf weiterhin, deshalb bleibt die
   Bildlaufleiste dort sichtbar: Sie ist dann der einzige Hinweis darauf, dass
   es seitlich weitergeht. */
@media (prefers-reduced-motion: reduce) {
  .laufband { scrollbar-width: auto; }
  .laufband::-webkit-scrollbar { display: initial; }
}

.rezension {
  flex: 0 0 320px;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.rezension-sterne { display: flex; gap: 3px; color: #e8a33d; }
.rezension-sterne .icon { width: 17px; height: 17px; }
.rezension blockquote {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text);
  /* Auf sechs Zeilen begrenzt, hochkant auf sieben. Laengere Bewertungen
     enden mit "...". Ausfuehrliche Rezensionen machten die Karten sonst mehr
     als doppelt so hoch.

     Bewusst ohne Aufklappen: Ein Knopf dafuer war am 15.09.2026 kurz drin und
     wurde auf Wunsch von David wieder entfernt. Gekuerzt wird nur die
     Anzeige, im Text steht der volle Wortlaut, und der Link ueber der Leiste
     fuehrt zu allen Rezensionen bei Google. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  overflow: hidden;
}
.rezension figcaption {
  margin-top: auto;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text);
  display: flex; flex-wrap: wrap; gap: 8px;
}
@media (max-width: 640px) {
  .rezensionen { margin-bottom: 28px; }
  /* Rund 200 px breit: Auf einem Handy sind damit knapp zwei Karten zu sehen,
     die zweite bricht sichtbar an. Das zeigt, dass es weitergeht. Bei den
     vorherigen 268 px passte nur gut eine Karte ins Bild. */
  /* Rund 168 px breit bei 12 px Abstand: Auf einem 390er Bildschirm sind das
     genau zwei Karten nebeneinander. Vorher waren es mit 200 px etwa
     anderthalb. */
  .rezension { flex-basis: 168px; padding: 12px 13px 11px; gap: 8px; }
  .rezension-sterne .icon { width: 15px; height: 15px; }
  /* Hochkant sind die Zeilen kuerzer, deshalb eine Zeile mehr. */
  .rezension blockquote { font-size: 13.5px; line-height: 1.5; -webkit-line-clamp: 7; line-clamp: 7; }
  .rezension figcaption { font-size: 12.5px; gap: 6px; }
  .laufband-spur { gap: 12px; }
}

/* Bewusst klein gehalten (Wunsch von David, 15.09.2026): Der Kasten ist eine
   Bitte am Rande, keine eigene Station. Er steht nach den Rezensionen und
   soll ihnen nicht die Aufmerksamkeit nehmen. */
.review-panel {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 16px;
  align-items: center;
  background: linear-gradient(120deg, var(--surface-2), var(--surface));
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 20px;
}
.review-panel h2 { font-size: 17px; }
.review-panel p { font-size: 14px; }
.review-panel .btn { padding: 10px 18px; font-size: 14.5px; }
/* Hochkant schlicht untereinander: Ueberschrift, Zeile, Knopf.

   Das Symbol faellt weg. Es stand als eigene Spalte neben einem zwei Zeilen
   hohen Textblock und liess den Kasten schief wirken. Der Knopf laeuft nicht
   mehr ueber die volle Breite, sonst war der Kasten unten kopflastig. Der
   Innenabstand entspricht mit 18 px dem Seitenrand der Seite, dadurch wirkt
   der Kasten im Verhaeltnis ruhig. */
@media (max-width: 720px) {
  .review-panel { grid-template-columns: 1fr; gap: 5px; padding: 12px 16px; }
  .review-panel .review-icon { display: none; }
  .review-panel .btn { justify-self: start; padding: 7px 15px; font-size: 13px; min-height: 34px; }
  .review-panel h2 { font-size: 15px; }
  .review-panel p { font-size: 13px; line-height: 1.45; margin-top: 2px; }
}
.review-icon {
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--surface-2); color: var(--text);
  display: flex; align-items: center; justify-content: center;
  flex: none;
}
.review-icon .icon { width: 1.2em; height: 1.2em; }
@media (max-width: 720px) { .review-icon { margin: 0 auto; } }

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq-list { display: flex; flex-direction: column; gap: 10px; }
.faq-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 18px 50px 18px 20px;
  font-weight: 700;
  font-size: 15.5px;
  position: relative;
  display: block;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { background: var(--surface-2); }
.faq-item summary .icon {
  position: absolute; right: 18px; top: 50%; transform: translateY(-50%) rotate(0deg);
  color: var(--text-muted); transition: transform 0.2s ease;
}
.faq-item[open] summary .icon { transform: translateY(-50%) rotate(180deg); }
.faq-item .faq-answer { padding: 0 20px 20px; font-size: 14.5px; color: var(--text-muted); }
.faq-item .faq-answer p { margin: 0; }

/* ==========================================================================
   Einsatzgebiet
   ========================================================================== */
/* Hier stand bis 11.09.2026 eine Karte des Einsatzgebiets. Eine
   eingezeichnete Fläche wirkte wie ein festes Gebiet, obwohl nach Absprache
   auch weiter entfernte Orte angefahren werden. Die Ortsliste reicht.
   Wiederherstellen: siehe werkzeuge/LIESMICH.md, Abschnitt karte-bauen.py. */
/* Die Ortskacheln (.area-towns, .area-panel) sind am 17.09.2026 entfallen.
   Die Orte stehen jetzt im Fliesstext von .area-intro: Das ist kuerzer und
   Suchmaschinen gewichten einen Satz staerker als eine Aufzaehlung. */
.area-note { margin-top: 16px; font-size: 13.5px; }
/* Einleitender Satz ueber der Ortsliste. Steht bewusst als Fliesstext da:
   Suchmaschinen gewichten ihn staerker als eine Aufzaehlung, und fuer Kunden
   sagt er in einem Satz, was die Liste nur aufzaehlt. */
.area-intro { margin: 0 0 22px; max-width: 62ch; }

/* ==========================================================================
   Kontakt
   ========================================================================== */
.contact-grid { display: grid; grid-template-columns: 1fr 1.15fr; gap: 48px; }
@media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; } }
.contact-list { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-direction: column; gap: 18px; }
.contact-list li { display: flex; gap: 14px; align-items: flex-start; }
.contact-list a { text-decoration: none; font-weight: 700; }
.contact-list a:hover { color: var(--accent-ink); }
.contact-icon {
  width: 38px; height: 38px; flex-shrink: 0; border-radius: 8px;
  background: var(--surface-2); display: flex; align-items: center; justify-content: center; color: var(--text-muted);
}
/* Kurzer persönlicher Hinweis auf der Startseite, der zur Über-uns-Seite
   führt – ersetzt den früheren ganzen Abschnitt an dieser Stelle. */
.personal-note {
  font-size: 14.5px;
  margin: 0 0 18px;
  padding-left: 14px;
  border-left: 2px solid var(--accent-ink);
  color: var(--text-muted);
}
.personal-note a { color: var(--text); font-weight: 700; }
.personal-note a:hover { color: var(--accent-ink); }

.whatsapp-note {
  display: flex; gap: 12px; align-items: flex-start;
  background: color-mix(in srgb, var(--whatsapp) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--whatsapp) 30%, var(--border));
  border-radius: 10px; padding: 16px 18px; font-size: 14px;
}
.whatsapp-note .icon { color: var(--whatsapp-text); width: 1.4em; height: 1.4em; flex-shrink: 0; margin-top: 1px; }
.whatsapp-note p { margin: 0; color: var(--text); }
.whatsapp-note a { color: var(--whatsapp-text); font-weight: 700; text-decoration: underline; }

form.contact-form { display: flex; flex-direction: column; gap: 16px; }
/* Sprungziel der Preistafel. Am Rechner steht das Formular neben den
   Kontaktdaten direkt unter der Überschrift des Abschnitts; mit dem größeren
   Abstand bleibt sie beim Ankommen mit im Bild. Hochkant liegen die
   Kontaktdaten dazwischen, dort gilt der normale Abstand. */
@media (min-width: 901px) {
  #contact-form { scroll-margin-top: calc(var(--header-h) + 170px); }
}
/* Auswahl aus der Preistafel, oben im Kontaktformular. Dieselbe blasse Fläche
   und derselbe Balken wie in der angeklickten Zeile, damit man sie
   wiedererkennt. Der Balken hat hier eine eigene Klasse: An .stufen-balken
   hängt der Scroll-Übergang der Preistafel, der im Formular nichts zu suchen
   hat. */
.preis-auswahl {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 4px 12px;
  margin: 0;
  max-width: none;
  padding: 10px 14px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  color: var(--text);
}
.preis-auswahl[hidden] { display: none; }
.preis-auswahl-titel {
  grid-column: 1 / -1;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.preis-auswahl-text { font-size: 14.5px; font-weight: 700; line-height: 1.3; }
.auswahl-balken { display: inline-flex; gap: 3px; }
.auswahl-balken span { width: 11px; height: 5px; border-radius: 3px; background: var(--border); }
.auswahl-balken span.an { background: var(--verlauf); }
/* Kurzes Aufleuchten, wenn eine Auswahl ankommt. Die Verzögerung überbrückt
   den Weg nach unten, sonst wäre es vorbei, bevor man da ist. */
@media (prefers-reduced-motion: no-preference) {
  .preis-auswahl.ist-neu { animation: auswahl-neu 1.2s ease 0.5s both; }
}
@keyframes auswahl-neu {
  from { background: color-mix(in srgb, var(--accent) 24%, transparent); }
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; } }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.field .optional { font-weight: 400; font-style: italic; opacity: 0.8; }
.field input, .field select, .field textarea {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; color: var(--text); font-family: inherit; font-size: 14.5px;
  min-height: 46px;
}
.field textarea { resize: vertical; min-height: 110px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: 2px solid var(--accent-ink); outline-offset: 1px; }

.consent-field {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 13px; color: var(--text-muted); cursor: pointer;
}
.consent-field input[type="checkbox"] {
  /* Das Kaestchen selbst bleibt klein genug fuers Auge, bekommt am Telefon
     aber genug Flaeche zum Antippen. Der ganze Text ist ohnehin Teil des
     Labels und schaltet mit. */
  margin-top: 2px; width: 20px; height: 20px; flex-shrink: 0; accent-color: var(--accent);
}
.consent-field a { color: var(--text); text-decoration: underline; }

.form-notice {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--info-bg); border: 1px solid var(--info-border);
  border-radius: 10px; padding: 16px 18px; font-size: 14px;
}
.form-notice .icon { color: var(--text-muted); width: 1.4em; height: 1.4em; flex-shrink: 0; margin-top: 1px; }
.form-notice p { margin: 0; color: var(--text); }
.form-notice[hidden] { display: none; }

/* Spam-Falle: für Besucher unsichtbar, aber nicht per display:none –
   manche Skripte erkennen das und überspringen solche Felder. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   WhatsApp Floating Button
   ========================================================================== */
.whatsapp-fab {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 40;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--whatsapp);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  text-decoration: none;
  box-shadow: 0 10px 26px -8px rgba(0,0,0,0.45);
  transition: transform 0.15s ease, background 0.15s ease;
}
.whatsapp-fab:hover { background: var(--whatsapp-dark); transform: translateY(-2px); }
.whatsapp-fab .icon { width: 1.6em; height: 1.6em; stroke: none; fill: currentColor; }

/* Auf Handygroesse gab es bis zum 15.09.2026 eine feste Leiste am unteren
   Rand mit Anrufen und WhatsApp. Sie ist auf Wunsch von David entfernt: Der
   Anruf steht oben neben dem Logo, WhatsApp im Kontaktabschnitt, beides
   zusammen wirkte aufdringlich.

   Der schwebende WhatsApp-Knopf bleibt dem Rechner vorbehalten. */
@media (max-width: 999px) {
  .whatsapp-fab { display: none; }
}

/* ==========================================================================
   Footer
   ========================================================================== */
footer { padding: 60px 0 30px; }
.footer-top { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 40px; padding-bottom: 40px; border-bottom: 1px solid var(--border); }
@media (max-width: 720px) { .footer-top { grid-template-columns: 1fr; } }
.footer-col h4 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); margin: 0 0 14px; font-weight: 700; }
.footer-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.footer-col a { text-decoration: none; font-size: 14.5px; color: var(--text-muted); }
.footer-col a:hover { color: var(--accent-ink); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; padding-top: 24px; font-size: 13px; color: var(--text-muted); }
.footer-bottom a { text-decoration: underline; }

/* ==========================================================================
   Rechtstext-Seiten (impressum.html / datenschutz.html)
   ========================================================================== */
/* Kurzschreibweise fuer padding, deshalb muss der obere Wert die Kopfzeile
   selbst einrechnen: sie ueberschreibt sonst das padding-top: var(--header-h)
   der allgemeinen main-Regel. Als hier 56px fest eingetragen wurden, war die
   Leiste noch etwa so hoch. Mit dem groesseren Logo ist sie gewachsen und der
   Seitenanfang verschwand dahinter. */
.legal-page main { padding: calc(var(--header-h) + 24px) 0 90px; }
.legal-page h1 { font-size: clamp(26px, 4vw, 34px); text-transform: none; margin-bottom: 8px; }
.legal-page .legal-updated { font-size: 13px; color: var(--text-muted); margin-bottom: 40px; }
.legal-body { max-width: 76ch; display: flex; flex-direction: column; gap: 6px; }
.legal-body h2 { font-size: 20px; text-transform: none; margin-top: 30px; }
.legal-body h3 { font-size: 15.5px; text-transform: none; margin-top: 18px; }
.legal-body p, .legal-body li { font-size: 14.5px; color: var(--text-muted); }
/* Aufzählungen kommen erst mit den Rechtsgrundlagen dazu. Ohne eigene Regel
   säßen sie am linken Rand ohne Einzug und ohne Luft zwischen den Punkten. */
.legal-body ul { margin: 4px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.legal-body strong { color: var(--text); font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal], [data-reveal] { opacity: 1; transform: none; transition: none; }
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ==========================================================================
   Handy-Ansicht
   Auf dem Handy zählt Aufgeräumtheit mehr als Informationsdichte:
   kleinere Abstände, zwei Kacheln pro Reihe statt einer, und die
   Preistabelle wird zu gestapelten Blöcken, damit nichts seitlich
   weggescrollt werden muss.
   ========================================================================== */
@media (max-width: 640px) {
  .nav-wrap { padding: 10px 16px; gap: 10px; }
  .container { padding: 0 18px; }
  .hero-inner { padding-inline: 18px; padding-bottom: 40px; }
  .hero h1 { font-size: 27px; }
  .hero-sub { font-size: 16px; }
  /* Grundabstand aller Abschnitte hochkant enger. Wirkt auf jeden Abschnitt
     und spart ueber die Seite hinweg am meisten, ohne dass etwas gedraengt
     aussieht. */
  .section { padding: 38px 0; }
  .section-head { margin-bottom: 24px; }

  /* Preistafel: Nur Abstaende, die Preise und Beschriftungen bleiben wie sie
     sind. Die drei Klassenkarten tragen den groessten Teil. */
  .stufen li { padding: 7px 10px; gap: 10px; }
  .price-intro { font-size: 15px; }

  /* Galerie: engere Abstaende zwischen Reihen und Karten. Die Fotos selbst
     bleiben unveraendert, nichts wird beschnitten. */
  .compare-grid { gap: 14px; }
  .vn-reihe { gap: 12px; }

  /* Haeufige Fragen: Die sechs Eintraege tragen den Abschnitt, jeder spart
     hier ein paar Pixel. */
  .faq-list { gap: 8px; }
  .faq-item summary { padding: 13px 46px 13px 16px; font-size: 15px; }
  .faq-item .faq-answer { padding: 0 16px 15px; font-size: 14px; }

  /* Einsatzgebiet: kleinere Ortsmarken, engere Zeilen. */
  .area-note { margin-top: 12px; font-size: 13px; }
  .area-intro { margin-bottom: 16px; font-size: 15px; }

  /* Kontakt: Der Abschnitt ist mit dem vollen Formular der laengste der
     Seite. Enger gesetzt, ohne Felder wegzulassen. */
  .contact-grid { gap: 24px; }
  .contact-list { margin-bottom: 16px; gap: 12px; }
  form.contact-form { gap: 12px; }
  .field textarea { min-height: 84px; }
  .personal-note, .whatsapp-note { font-size: 13.5px; }

  /* Seit der vierte Punkt weg ist (15.09.2026), stehen die drei
     verbleibenden hochkant nebeneinander statt zwei zu zwei. Raster statt
     Flexbox: Jede Beschriftung braucht hier zwei Zeilen, mit Flex-Prozenten
     rutschten die Spalten ineinander. Der Text ist kleiner als vorher, sonst
     passen drei Spalten nicht ohne Trennstriche mitten im Wort. */
  .hero-punkte {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 8px;
    margin-top: 22px;
  }
  .hero-punkte li { align-items: flex-start; font-size: 12px; line-height: 1.3; gap: 5px; }
  .hero-punkte .icon { width: 15px; height: 15px; flex: none; margin-top: 1px; }
  /* Der vierte Punkt geht ueber alle drei Spalten, er steht ja unter den
     anderen. Dazu braucht nur er min-width: 0: Eine Rasterzelle wird sonst
     nie schmaler als ihr Inhalt, und sein langer Text wuerde die Spalten
     auseinanderziehen, bis die beiden hinteren aus dem Bild rutschen.
     Wichtig: min-width: 0 gehoert NUR an ihn. Stand es an allen drei
     Punkten, durfte "Transparente" aus seiner Spalte herauslaufen und lag
     auf dem Symbol von "Flexible Termine". Genau das war am 27.09.2026
     einen Moment lang live. */
  .hero-punkte .hero-punkt-neu { grid-column: 1 / -1; min-width: 0; margin-top: 9px; }
  .hero-punkt-neu a { align-items: flex-start; }
  .hero-neu-marke { margin-top: 1px; }

  /* Ablauf: Hochkant stehen die drei Schritte untereinander. Als Karten mit
     Ziffer, Überschrift und Text in drei Zeilen war der Abschnitt 746 px hoch
     und passte nicht auf einen Bildschirm. Ziffer und Überschrift teilen sich
     jetzt eine Zeile, der Text steht darunter. Das spart rund 200 px, der
     ganze Abschnitt ist ohne Scrollen zu sehen. */
  .process-list { gap: 12px; }
  .process-step {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 12px;
    row-gap: 6px;
    padding: 13px 15px;
  }
  .process-num { width: 26px; height: 26px; font-size: 12px; }
  .process-step h3 { font-size: 15px; }
  .process-step p { grid-column: 2; font-size: 13px; line-height: 1.45; }
  .ablauf-hinweis { margin-top: 14px; font-size: 13px; line-height: 1.5; }

  /* Leistungskacheln: dieselbe Kur wie bei den Ablauf-Schritten. Das Symbol
     stand auf einer eigenen Zeile über der Überschrift und kostete in jeder
     der vier Kacheln rund 36 px. Jetzt steht es daneben, der Text darunter.
     Das spart über den ganzen Abschnitt rund 250 px, er passt damit auf einen
     Bildschirm. Am Rechner bleibt das Symbol oben stehen. */
  .service-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    /* Oben ausrichten, nicht mittig. Mittig hiess: Das Symbol setzt sich in
       die Mitte der ganzen Zelle. Sobald die Ueberschrift umbrach oder die
       Empfehlungsmarke in eine zweite Zeile rutschte, hing es zwischen den
       Zeilen statt neben der ersten (gemeldet von David, 17.09.2026).
       Die Hoehe darunter gibt dem Symbol genau eine Zeile der Ueberschrift,
       darin steht es mittig. Damit sitzt es immer neben der ersten Zeile,
       egal wie viele folgen. */
    align-items: start;
    column-gap: 10px;
    row-gap: 6px;
    padding: 12px 16px;
    --kachel-titel: 16.5px;
    --kachel-zeile: 1.6;   /* wie bisher, nur jetzt benannt */
  }
  .service-card > .service-icon {
    margin-bottom: 0;
    height: calc(var(--kachel-titel) * var(--kachel-zeile));
  }
  /* Kein Versatz am Symbol. Gemessen an der Versalhöhe der Überschrift
     stehen die Symbole mittig, sobald ihre Zeichnung in ihrem eigenen
     Rahmen mittig sitzt. Genau daran lag es beim Funkel-Symbol, siehe
     icon-sparkle in index.html. Ein zusätzlicher Versatz im CSS schob sie
     nur wieder daneben (17.09.2026). */
  .service-card > p { grid-column: 2; font-size: 13.5px; line-height: 1.45; }
  .service-icon .icon { width: 22px; height: 22px; }
  /* 19 px liessen "Kostenfreie Lackversiegelung" neben Symbol und Pfeil
     umbrechen, die Kachel wurde dadurch eine Zeile hoeher als die andere. */
  .service-card h3 { font-size: var(--kachel-titel); line-height: var(--kachel-zeile); }

  /* Die aufklappbaren Kacheln tragen ihren eigenen Aufbau im summary. Dort
     lag das Symbol über die ganze Breite, also ebenfalls auf eigener Zeile.
     Drei Spalten: Symbol, Überschrift, Pfeil. */
  .service-card > details { grid-column: 1 / -1; }
  .kachel-klapp summary { grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 10px;
    align-items: start; }
  .kachel-klapp summary .service-icon { grid-column: 1;
    height: calc(var(--kachel-titel) * var(--kachel-zeile)); }
  /* Der Pfeil gehoert ebenfalls neben die erste Zeile, nicht in die Mitte. */
  .kachel-klapp .kachel-pfeil {
    height: calc(var(--kachel-titel) * var(--kachel-zeile)); width: 20px;
  }
  .kachel-text { margin-top: 10px; }
}

/* Preisklassen unterhalb der vollen Breite: immer zwei mal zwei statt
   drei plus eine einzelne. So bleiben alle vier Preise vergleichbar und
   die letzte Karte steht nicht allein auf ganzer Breite. */
@media (max-width: 1000px) {
  .preis-klasse { flex: 1 1 100%; }
}
@media (max-width: 700px) {
  .preis-klasse { padding: 14px 16px; }
  .preis-klasse .beispiele { margin-bottom: 8px; }
}

/* ==========================================================================
   Dankeschön nach dem Absenden

   Beide Formulare schicken die Anfrage im Hintergrund (initContactForm in
   js/script.js). Danach verschwinden die Felder und an ihrer Stelle steht
   der Dank. Die Höhe des Kastens hält das Skript vorher fest, damit nichts
   springt. Ohne JavaScript bleibt dieser Block versteckt, dann kommt die
   Rückmeldung wie früher nach dem Neuladen.
   ========================================================================== */
.danke {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: auto 0;
  padding: 10px 0;
  text-align: center;
}
.danke[hidden] { display: none; }
/* Vorübergehend ausgeblendete Links, etwa auf einen Abschnitt, der gerade
   ohne Inhalt ist. Die eigenen display-Regeln der Links würden das eingebaute
   [hidden] sonst überstimmen.
   Bewusst keine allgemeine [hidden]-Regel: Die Schritte der Schnellanfrage
   bleiben ausgeblendet im Raster stehen (siehe .schritt[hidden]). */
nav.links a[hidden], .mobile-menu a[hidden], .footer-col li[hidden] { display: none; }
.danke .icon {
  width: 34px;
  height: 34px;
  color: var(--accent-ink);
  stroke-width: 1.6;
}
.danke-titel {
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 800;
  color: var(--text);
  margin: 2px 0 0;
}
.danke p { margin: 0; font-size: 14.5px; color: var(--text-muted); max-width: 34ch; }
.danke-anruf { margin-top: 6px; font-size: 13px; }
.danke-anruf a { color: var(--accent-ink); font-weight: 700; }

form.gesendet > *:not(.danke) { display: none; }
/* Die Schnellanfrage setzt die Anzeige der Schritte mit drei Klassen
   (.schnell.gestuft .schritte). Das sticht die Regel darüber, deshalb hier
   noch einmal ausdrücklich mit einer Klasse mehr. */
.schnell.gestuft.gesendet .schritte { display: none; }
form.gesendet { justify-content: center; }

@media (prefers-reduced-motion: no-preference) {
  form.gesendet .danke { animation: danke-auf 0.32s ease both; }
  @keyframes danke-auf {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }
}

/* ==========================================================================
   Scroll-Übergänge
   Die Bewegung hängt am Scrollen, nicht an einer Uhr: Inhalte gleiten ins
   Bild, während man scrollt, und beim Zurückscrollen wieder zurück. Im Hero
   bleibt das Hintergrundbild beim Wegscrollen zurück und zoomt leicht, die
   Überschrift löst sich nach oben auf. Vorher/Nachher-Karten fahren aus der
   Tiefe heran, in der Preistafel füllen sich die Stufenbalken.

   Umgesetzt mit CSS-Scroll-Animationen (animation-timeline). Das rechnet der
   Browser selbst, ohne Skript und ohne Scroll-Handler. Browser ohne diese
   Technik (iPhones vor iOS 26, Firefox) bekommen unverändert das Einblenden
   aus initScrollReveal in js/script.js. Bei „Bewegung reduzieren“ bleibt
   alles still.

   Die Abfrage prüft auch die Schreibweisen für animation-range. Kennt ein
   Browser die nicht, liefe jede Animation über die ganze Strecke, und die
   Inhalte wären erst beim Verlassen des Bildschirms voll sichtbar.

   Zwei Stolperfallen:
   1. overflow: hidden macht ein Element zum Scroll-Container. Eine Zeitleiste
      darin misst dann gegen diesen Kasten statt gegen die Seite und steht
      still. Deshalb hängen Bild und Text im Hero an der benannten Zeitleiste
      --sg-hero auf .hero selbst, und die beiden Kachelraster bekommen
      overflow: clip. Das schneidet genauso ab, scrollt aber nicht.
   2. In .grid-services und .preis-klassen sind die 1px-Fugen der graue Grund
      des Rasters. Bewegt sich eine ganze Kachel, blitzt er durch. Dort bewegt
      sich deshalb nur der Inhalt, die Kachel selbst steht.

   Staffelung: --sg-k zählt die Kachel oder Karte in ihrer Reihe, --sg-z das
   Element in der Kachel, --sg-s das Balkenstück. Jeder Schritt verschiebt
   den Bereich um ein paar Prozent, dadurch läuft alles nacheinander ein.
   ========================================================================== */
@supports (animation-timeline: view()) and (view-timeline: --sg-probe block)
  and (animation-range: exit-crossing 8% exit-crossing 50%)
  and (animation-range: cover calc((1 + 2) * 2.5%) cover calc(28% + (1 + 2) * 2.5%)) {
  @media (prefers-reduced-motion: no-preference) {

    @keyframes sg-auftauchen {
      from { opacity: 0; transform: translate3d(0, var(--sg-weg, 56px), 0); }
      to   { opacity: 1; transform: none; }
    }
    @keyframes sg-heranzoomen {
      from { opacity: 0; transform: translate3d(0, 72px, 0) scale(0.9); }
      40%  { opacity: 1; }
      to   { opacity: 1; transform: none; }
    }
    @keyframes sg-linie { from { transform: scaleX(0); } }
    @keyframes sg-balken { from { background-size: 0% 100%; } }
    @keyframes sg-knopf {
      from { opacity: 0; transform: scale(0.3); }
      65%  { opacity: 1; transform: scale(1.12); }
      to   { opacity: 1; transform: none; }
    }
    @keyframes sg-hero-bild { to { transform: translate3d(0, 22%, 0) scale(1.08); } }
    @keyframes sg-hero-text { to { opacity: 0; transform: translate3d(0, -44px, 0); } }
    @keyframes sg-hero-verblassen { to { opacity: 0.45; } }

    /* Das bisherige Einblenden hier abschalten, sonst laufen zwei Effekte
       übereinander. is-visible setzt das Skript weiter, es ändert nichts mehr. */
    .js [data-reveal]:is(.section-head, .service-card, .preis-klasse,
        .process-step, .compare-card, .review-panel,
        .about-page-intro, .about-photo, .about-cta) {
      opacity: 1;
      transform: none;
      transition: none;
    }

    /* ---- Hero ---- */
    .hero { view-timeline: --sg-hero block; }
    .hero-media {
      animation: sg-hero-verblassen linear both;
      animation-timeline: --sg-hero;
      animation-range: exit-crossing 30% exit-crossing 100%;
    }
    .hero-media img {
      animation: sg-hero-bild linear both;
      animation-timeline: --sg-hero;
      animation-range: exit-crossing 0% exit-crossing 100%;
    }
    .hero-text {
      animation: sg-hero-text cubic-bezier(0.5, 0, 0.9, 0.6) both;
      animation-timeline: --sg-hero;
      animation-range: exit-crossing 8% exit-crossing 50%;
    }
    /* Die Blende verblasst mit dem Bild, sonst bliebe eine helle Flaeche ueber
       dem schon verschwundenen Foto stehen. */
    .hero-blende {
      animation: sg-hero-verblassen linear both;
      animation-timeline: --sg-hero;
      animation-range: exit-crossing 30% exit-crossing 100%;
    }
    /* Auf Handy und Tablet ist der Hero niedriger. Mit denselben Prozentwerten
       wäre der Text schon unter der Leiste verschwunden, bevor er verblasst,
       und das Bild bewegte sich kaum. Deshalb dort kürzere Strecken. */
    @media (max-width: 999px) {
      .hero-media, .hero-blende { animation-range: exit-crossing 12% exit-crossing 60%; }
      .hero-media img { animation-range: exit-crossing 0% exit-crossing 60%; }
      .hero-text { animation-range: exit-crossing 2% exit-crossing 24%; }
    }

    /* ---- Abschnittsköpfe: Überschrift, dann Unterzeile, dann die Linie ---- */
    .section-head { view-timeline: --sg-kopf block; }
    .section-head > * {
      animation: sg-auftauchen cubic-bezier(0.2, 0.7, 0.3, 1) both;
      animation-timeline: --sg-kopf;
      animation-range: cover 0% cover 30%;
    }
    .section-head > * + * { animation-range: cover 4% cover 34%; }
    .section-head h2::after {
      transform-origin: left center;
      animation: sg-linie cubic-bezier(0.2, 0.7, 0.3, 1) both;
      animation-timeline: --sg-kopf;
      animation-range: cover 12% cover 40%;
    }

    /* ---- Kacheln: Leistungen und Preisklassen ---- */
    .grid-services, .preis-klassen { overflow: clip; }
    .service-card, .preis-klasse { view-timeline: --sg-kachel block; }
    .service-card > *,
    .preis-klasse > h3,
    .preis-klasse > .beispiele,
    .stufen li {
      --sg-weg: 28px;
      animation: sg-auftauchen cubic-bezier(0.2, 0.7, 0.3, 1) both;
      animation-timeline: --sg-kachel;
      animation-range:
        cover calc((var(--sg-k, 0) + var(--sg-z, 0)) * 2.5%)
        cover calc(28% + (var(--sg-k, 0) + var(--sg-z, 0)) * 2.5%);
    }
    :is(.grid-services, .preis-klassen) > :nth-child(2) { --sg-k: 1; }
    :is(.grid-services, .preis-klassen) > :nth-child(3) { --sg-k: 2; }
    /* Die vierte Leistungskachel gibt es seit dem 17.09.2026 nicht mehr,
       damit fielen auch die beiden Sonderregeln fuer die zweite Reihe weg.
       Die drei verbliebenen Kacheln staffeln sich ueber die Regel darueber. */
    .service-card > :nth-child(2), .preis-klasse > .beispiele { --sg-z: 1; }
    .service-card > :nth-child(3), .stufen li:nth-child(1) { --sg-z: 2; }
    .service-card > :nth-child(4), .stufen li:nth-child(2) { --sg-z: 3; }
    .service-card > :nth-child(5), .stufen li:nth-child(3) { --sg-z: 4; }

    /* Die Stufenbalken füllen sich von links, Zeile für Zeile. Die graue Spur
       liegt als Farbe darunter, damit ein noch leeres Stück nicht fehlt. */
    .stufen-balken span.an {
      background: var(--verlauf) left center / 100% 100% no-repeat, var(--border);
      animation: sg-balken cubic-bezier(0.3, 0, 0.2, 1) both;
      animation-timeline: --sg-kachel;
      animation-range:
        cover calc(14% + (var(--sg-k, 0) + var(--sg-z, 0) + var(--sg-s, 0)) * 2.5%)
        cover calc(24% + (var(--sg-k, 0) + var(--sg-z, 0) + var(--sg-s, 0)) * 2.5%);
    }
    .stufen-balken span.an:nth-child(2) { --sg-s: 1; }
    .stufen-balken span.an:nth-child(3) { --sg-s: 2; }

    /* ---- Ablauf: Karten nacheinander, die Nummer springt kurz auf ---- */
    .process-step {
      view-timeline: --sg-schritt block;
      animation: sg-auftauchen cubic-bezier(0.2, 0.7, 0.3, 1) both;
      animation-timeline: view();
      animation-range: cover calc(var(--sg-k, 0) * 3%) cover calc(30% + var(--sg-k, 0) * 3%);
    }
    .process-list > :nth-child(2) { --sg-k: 1; }
    .process-list > :nth-child(3) { --sg-k: 2; }
    .process-num {
      animation: sg-knopf cubic-bezier(0.3, 0, 0.2, 1) both;
      animation-timeline: --sg-schritt;
      animation-range: cover calc(10% + var(--sg-k, 0) * 3%) cover calc(30% + var(--sg-k, 0) * 3%);
    }

    /* ---- Vorher/Nachher, Videos und Gründerfoto: aus der Tiefe heran ---- */
    .compare-card, .about-photo {
      transform-origin: 50% 75%;
      animation: sg-heranzoomen cubic-bezier(0.2, 0.7, 0.3, 1) both;
      animation-timeline: view();
      animation-range: cover calc(var(--sg-k, 0) * 4%) cover calc(36% + var(--sg-k, 0) * 4%);
    }
    .vn-reihe > :nth-child(2), .video-reihe > :nth-child(2) { --sg-k: 1; }
    .vn-reihe > :nth-child(3) { --sg-k: 2; }
    .video-reihe > :nth-child(3) { --sg-k: 2; }
    .video-reihe > :nth-child(4) { --sg-k: 3; }
    @media (max-width: 760px) {
      .vn-reihe > :nth-child(2), .vn-reihe > :nth-child(3) { --sg-k: 0; }
    }
    @media (max-width: 560px) {
      .video-reihe > :nth-child(3) { --sg-k: 0; }
      .video-reihe > :nth-child(4) { --sg-k: 1; }
    }

    /* ---- Einzelne Blöcke ---- */
    .review-panel, .about-page-intro, .about-cta {
      animation: sg-auftauchen cubic-bezier(0.2, 0.7, 0.3, 1) both;
      animation-timeline: view();
      animation-range: cover 0% cover 30%;
    }
  }
}
