/* Gebündelt von scripts/wp-build-theme.mjs – Reihenfolge aus src/styles/main.css */

/* ── fonts.css ─────────────────────────────────────────── */
/* ==========================================================================
   Self-hosted Fonts (WOFF2, latin + latin-ext)
   Portabel: Dateien liegen in public/fonts/ -> im WP-Theme assets/fonts/

   Display: Chivo (Omnibus-Type, SIL OFL 1.1, kein Reserved Font Name)
   Text:    Libre Franklin (Impallari Type, SIL OFL 1.1, kein RFN)

   Warum diese Paarung: Die vorige Kombination – Barlow Condensed in Versalien
   plus Barlow – ist der Standard-Look von Baukasten-Themes. Zwei Dinge daran
   waren das Problem: Grossbuchstaben loeschen die Wortsilhouette (jede Zeile
   wird ein Rechteck), und Versalsatz erzwingt eine Schmalschrift, weil es
   sonst zu breit wird. Im Deutschen ist das doppelt schade – Substantive sind
   ohnehin gross, der Rhythmus ist gratis eingebaut, und "DOPPELSTABMATTENZAUN"
   ist eine 20-stellige Mauer. Deshalb jetzt gemischte Schreibung in einer
   serifenbetonten Slab: materialnah, passend zu Stahl, und unverwechselbar.
   ========================================================================== */

/* Anzeigeschrift: Chivo, variabel im Bereich 600–700 aus einer Datei.

   Vorgeschichte, damit sie sich nicht wiederholt: Erst stand hier Barlow
   Condensed in Versalien — vom Kunden als „nach KI" verworfen. Danach Zilla
   Slab; deren Schraegfuesse lasen sich „wie eine Console", ebenfalls verworfen.
   Chivo ist ein kraeftiger, leicht schmaler Grotesk: genug Eigenart, um sich
   von der Fliesstextschrift abzusetzen, ohne Schreibmaschinen-Anmutung.

   Der Bereich `600 700` statt einer einzelnen Zahl ist Absicht. Bei Zilla Slab
   lag hier ein zweiter Block fuer 700, dessen Datei spaeter entfernt wurde —
   der Verweis lief auf HTTP 404, und weil base.css `font-synthesis-weight: none`
   setzt, durfte der Browser den fetten Schnitt nicht selbst erzeugen und fiel
   auf Georgia zurueck. Mit einem Bereich kann das nicht passieren. */
@font-face {
  font-family: 'Chivo';
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url('../fonts/chivo-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Libre Franklin';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/libre-franklin-var.woff2') format('woff2');
}

/* Metrisch angeglichene Rueckfall-Schriften. Ohne sie springen die Zeilen,
   sobald die echte Schrift nachgeladen ist (font-display: swap).
   Libre Franklin: ascent 0.966, descent 0.246, x-Hoehe 0.530.

   Chivo-Rueckfall auf Arial. Werte im Browser an der echten Datei gemessen:
   Chivo Aufstieg 94 %, Abstieg 25 %, x-Hoehe 51,1 %; Arial 91 / 21 / 51,9 %.
   Die Zeilenbreite derselben Ueberschrift betraegt 1817 gegen 1793 Einheiten,
   daraus size-adjust 101 %. */
@font-face {
  font-family: 'Chivo Fallback';
  src: local('Arial'), local('Helvetica Neue');
  size-adjust: 101%;
  ascent-override: 94%;
  descent-override: 25%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Libre Franklin Fallback';
  src: local('Arial'), local('Helvetica Neue');
  size-adjust: 102%;
  ascent-override: 97%;
  descent-override: 25%;
  line-gap-override: 0%;
}


/* ── tokens.css ─────────────────────────────────────────── */
/* ==========================================================================
   DESIGN TOKENS — Zaunmann Wetzlar ("Präzision aus Stahl")
   Nur Custom Properties. Diese Datei wird im WP-Theme zur Token-Basis
   (theme.json-Farben lassen sich hieraus ableiten).
   ========================================================================== */

:root {
  /* ── Markengrün-Skala (Hue ~92°, aus #62A72F) ─────────────────────────── */
  --green-50:  #f2f8ec;
  --green-100: #e0efd1;
  --green-200: #c3e0a4;
  --green-300: #a3ce7c;
  --green-400: #7fba50;
  --green-500: #62a72f; /* MARKE */
  /* Dieselbe Farbe als Kanaltripel. Gebraucht ueberall, wo Markengruen mit
     Deckkraft unter 1 stehen muss (Schein, Puls, Icon-Flaeche): rgba() nimmt
     keinen Hex-Wert mit Alpha aus einer Custom Property, und relative
     Farbfunktionen (color-mix, rgb(from …)) sind fuer die anvisierten
     Safari-Versionen zu jung. Ohne dieses Token stand #62A72F in scroll3d.css
     und cards.css sechsmal hartkodiert an der Token-Skala vorbei. */
  --green-500-rgb: 98, 167, 47;
  /* Vorher #4a7d20. Das erreichte auf Weiß 4,95 : 1, auf --ink-50 aber nur
     4,45 : 1 und auf --surface-tint 4,57 : 1 — die Kicker (.eyebrow) und die
     Kontaktlinks auf /contacts/ lagen damit unter der AA-Schwelle von 4,5.
     Nachgerechnet: #44741d ergibt 5,58 : 1 auf Weiß, 5,02 : 1 auf --ink-50,
     5,14 : 1 auf --surface-tint. Weiß auf dieser Fläche (CTA-Band): 5,58 : 1. */
  --green-600: #44741d; /* Links/Grün-Text auf hellen Flächen (AA überall) */
  --green-700: #3c671a;
  --green-800: #2e5014;
  --green-900: #223b10;

  /* ── Anthrazit/Neutral-Skala (kühl ~215°, aus #262D35) ────────────────── */
  --ink-950: #14181e;
  --ink-900: #1c222a; /* Footer-Hauptfläche */
  --ink-800: #262d35; /* MARKE, Dark-Sections, Headings */
  --ink-700: #333c47;
  --ink-600: #46515f;
  --ink-500: #5c6876; /* Sekundärtext AA auf Weiß */
  --ink-400: #7a8694;
  --ink-300: #a5aeb9;
  --ink-200: #cbd2d9;
  --ink-100: #e4e8ec;
  --ink-50:  #f1f3f5;
  --white:   #ffffff;
  --surface-tint: #f4f7f0; /* grünstichiges Off-White */

  /* ── Akzente / Funktional ─────────────────────────────────────────────── */
  --amber-star: #ffb800;
  --error:   #b3261e;
  --success: #3c671a;
  --warning: #9a5b00;

  /* ── RAL-Swatches (Produktfarbwähler) ─────────────────────────────────── */
  --ral-6005: #0f4336;
  --ral-7016: #383e42;
  --ral-zink: #b5bbc0;

  /* ── Semantische Tokens (Light) ───────────────────────────────────────── */
  --color-bg:            var(--white);
  --color-bg-alt:        var(--ink-50);
  --color-bg-tint:       var(--surface-tint);
  --color-heading:       var(--ink-800);
  --color-text:          var(--ink-700);
  --color-text-muted:    var(--ink-500);
  --color-link:          var(--green-600);
  --color-link-hover:    var(--green-700);
  --color-border:        var(--ink-100);
  --color-border-strong: var(--ink-200);
  --color-cta-bg:        var(--green-500);
  --color-cta-text:      var(--ink-950); /* Kontrast-Regel: Anthrazit-Text auf Grün */
  --color-cta-hover:     var(--green-400);
  --color-focus:         var(--green-600);
  --color-accent:        var(--green-500);

  /* ── Typografie ───────────────────────────────────────────────────────── */
  /* 'Chivo Fallback' und 'Libre Franklin Fallback' sind die metrisch
     angeglichenen Local-Fonts aus fonts.css – ohne sie verschieben sich beim
     Font-Swap die Zeilen. */
  --font-display: 'Chivo', 'Chivo Fallback', Arial, Helvetica, sans-serif;
  --font-body:    'Libre Franklin', 'Libre Franklin Fallback', Arial, Helvetica, sans-serif;

  /* Chivo baut breiter als die vorherige Slab: dieselbe Hero-Zeile brach mobil
     auf drei statt zwei Zeilen (gemessen 390 px: 119 px Hoehe bei 41 px
     Zeilenhoehe). Der untere Anker geht deshalb von 2,375rem auf 2,125rem, der
     obere bleibt — die Steigung ist so gewaehlt, dass 1440 px unveraendert bei
     rund 72 px landet. */
  --text-display: clamp(2.125rem, 1.244rem + 3.62vw, 4.5rem);
  --text-h1:      clamp(2rem, 1.68rem + 1.42vw, 2.95rem);
  --text-h2:      clamp(1.5rem, 1.27rem + 1.02vw, 2.2rem);
  --text-h3:      clamp(1.375rem, 1.25rem + 0.56vw, 1.75rem);
  --text-h4:      clamp(1.125rem, 1.08rem + 0.19vw, 1.25rem);
  --text-h5:      1rem;
  --text-lead:    clamp(1.0625rem, 1rem + 0.28vw, 1.25rem);
  --text-body:    1rem;
  --text-sm:      0.875rem;
  --text-xs:      0.8125rem;
  --text-kicker:  0.875rem;
  --text-button:  1rem;
  --text-number:  clamp(3.25rem, 2.17rem + 4.8vw, 6.5rem);
  --label:        0.6875rem; /* 11 px Versal-Label (.label in base.css) */

  --measure:      65ch;
  --measure-lead: 55ch;

  /* ── Layout / Container ───────────────────────────────────────────────── */
  --container-max:    1280px;
  --container-wide:   1440px;
  --container-form:   880px;
  /* --container-narrow (800px) ist entfallen: der schmale Container rueckte
     FAQ- und Stellendetail-Sektionen mittig ein und verschob damit ihre linke
     Kante bei 1440 px um 240 px gegen jede andere Ueberschrift der Seite.
     Das Lesemass steckt in den Kindern (.prose, .faq__answer, .section-head
     tragen je eigene max-width) — der Container brauchte es nicht. */
  --gutter:   clamp(1.25rem, 0.83rem + 1.85vw, 2.5rem);
  --grid-gap: clamp(1rem, 0.66rem + 1.48vw, 2rem);

  /* ── Spacing-Skala ────────────────────────────────────────────────────── */
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.25rem;
  --space-6:  1.5rem;
  --space-8:  2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;
  --space-32: 8rem;
  /* Vorher bis 7,5rem (120px) oben und unten: bei 10 Sektionen ergab das
     2220 px reines Polster auf der Startseite. Der Kunde empfand den Scrollweg
     als zu lang – hier liegt die Haelfte davon. */
  --section-pad:    clamp(3.25rem, 2.4rem + 3.8vw, 5.5rem);
  --section-pad-sm: clamp(2.5rem, 1.9rem + 2.6vw, 4.5rem);

  /* ── Radius & Schatten ────────────────────────────────────────────────── */
  --radius-sm:   6px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-pill: 999px;      /* nur noch fuer echte Chips/Marker */
  /* Buttons und Eingabefelder bewusst kantig: die Pillenform war laut Audit
     das deutlichste Baukasten-Merkmal (999px auf allen 4 Button-Varianten,
     65 % aller gerundeten Elemente vollrund). Stahlbau ist nicht rund. */
  --radius-control: 3px;
  --shadow-sm: 0 1px 3px rgba(20, 24, 30, 0.08);
  --shadow-md: 0 6px 24px -8px rgba(20, 24, 30, 0.16);
  --shadow-lg: 0 16px 48px -12px rgba(20, 24, 30, 0.24);

  /* ── Overlays (Text-auf-Bild) ─────────────────────────────────────────── */
  --overlay-hero: linear-gradient(180deg, rgba(20, 24, 30, 0.25) 0%, rgba(20, 24, 30, 0.05) 40%, rgba(20, 24, 30, 0.78) 100%);
  --overlay-tile: linear-gradient(200deg, rgba(38, 45, 53, 0) 35%, rgba(38, 45, 53, 0.85) 100%);
  --overlay-band: linear-gradient(90deg, rgba(20, 24, 30, 0.86) 0%, rgba(20, 24, 30, 0.62) 100%);

  /* ── Motion ───────────────────────────────────────────────────────────── */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 200ms;
  --dur-med:  300ms;
  --dur-slow: 600ms;

  /* ── Header-Höhe (fürs sticky-Offset / scroll-margin) ─────────────────── */
  --header-h: 76px;

  /* ── Beleg-Leiste: Überlappung in den Hero ────────────────────────────── */
  /* Steuert zugleich Pause-Button und Scroll-Cue im Video-Hero (hero.css). */
  --proofbar-lift: 56px;
}

/* Eine Klasse schaltet jede Sektion auf Dark (Anthrazit) um */
.section--dark {
  --color-bg:         var(--ink-800);
  --color-heading:    var(--white);
  --color-text:       var(--ink-300);
  --color-text-muted: var(--ink-300);
  --color-link:       var(--green-300);
  --color-link-hover: var(--green-200);
  --color-border:     color-mix(in srgb, var(--white) 12%, transparent);
  --color-focus:      var(--green-300);
  background: var(--color-bg);
  color: var(--color-text);
}

@media (max-width: 640px) {
  :root {
    --header-h: 60px;
    /* Die Beleg-Leiste ist hier bis zu vierzeilig — flachere Überlappung */
    --proofbar-lift: 28px;
  }
}


/* ── base.css ─────────────────────────────────────────── */
/* ==========================================================================
   BASE — Reset, Elemente, Typografie
   ========================================================================== */

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

* { margin: 0; }

/* [hidden] muss jede display-Regel schlagen (sonst bleiben .btn/.flex-Elemente sichtbar) */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* verhindert, dass Sprungmarken unter dem sticky Header verschwinden */
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* clip statt hidden: hidden würde den Body zum Scroll-Container machen
     und damit sticky-Header, scrollY und scroll-behavior brechen. */
  overflow-x: clip;
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

/* Icons ohne explizite Größe dürfen nie auf Container-Größe skalieren */
.icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
}

img { height: auto; }

input, button, textarea, select { font: inherit; color: inherit; }

button { cursor: pointer; background: none; border: none; padding: 0; }

a { color: var(--color-link); text-decoration: none; }
a:hover { color: var(--color-link-hover); }

ul, ol { padding: 0; list-style: none; }

/* ── Typografie ──────────────────────────────────────────────────────────── */

/* Die Anzeigeschrift traegt nur die beiden obersten Ebenen. Ab h3 uebernimmt
   die Textschrift in 600 – ein Magazin setzt auch nicht jede Zwischenzeile in
   der Auszeichnungsschrift, und sie muesste sonst bei 22px funktionieren. */
h1, h2 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--color-heading);
  line-height: 1.08;
  text-wrap: balance;
  /* Von Chivo ist eine variable Datei geladen (für 600–700 angemeldet) – ohne das faked der Browser Zwischenstufen. */
  font-synthesis-weight: none;
}

h3, h4, h5, h6 {
  font-family: var(--font-body);
  font-weight: 600;
  color: var(--color-heading);
  line-height: 1.35;
  text-wrap: balance;
}

h1 { font-size: var(--text-h1); line-height: 1.06; }
h2 { font-size: var(--text-h2); line-height: 1.12; }
h3 { font-size: var(--text-h3); line-height: 1.25; letter-spacing: -0.004em; }
h4 { font-size: var(--text-h4); }
h5 { font-size: var(--text-h5); }

p { text-wrap: pretty; }

/* Lange Komposita (z. B. „Doppelstabmattenzaun") dürfen den Viewport
   auf schmalen Screens nicht sprengen. */
h1, h2, h3, h4, h5, h6, p, li, a, td, dd, dt, summary, figcaption {
  overflow-wrap: break-word;
}
/* Silbentrennung nur dort, wo sie unvermeidlich ist.
   Chrome trennt lange deutsche Komposita schlecht („Doppelstabmat-tenzaun"
   statt „Doppelstab-mattenzaun"), obwohl lang="de" gesetzt ist. Gemessen an
   /doppelstabmattenzaun-8-6-8-…/: bei 390 px braucht das Wort 356 px in einer
   349 px breiten Spalte — ohne Trennung bricht die Ueberschrift dort auf DREI
   statt vier Zeilen um, ganz ohne Ueberlauf. Unter 380 px ist die Spalte so
   schmal, dass ein Bruch unvermeidlich ist; dann ist ein Trennstrich besser
   als ein harter Umbruch mitten im Wort. */
@media (max-width: 380px) {
  h1, h2, h3 { hyphens: auto; }
}

strong, b { font-weight: 600; }

:target { scroll-margin-top: calc(var(--header-h) + 1.5rem); }

/* ── Fokus (a11y) ────────────────────────────────────────────────────────── */

:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* ── Skip-Link ───────────────────────────────────────────────────────────── */

.skip-link {
  /* fixed: bleibt auch nach Scrollen erreichbar */
  position: fixed;
  left: 0.5rem;
  top: -100px;
  z-index: 1000;
  background: var(--green-500);
  color: var(--ink-950);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  transition: top var(--dur-fast);
}
.skip-link:focus { top: 0.5rem; color: var(--ink-950); }

/* ── Selection ───────────────────────────────────────────────────────────── */

::selection { background: var(--green-200); color: var(--ink-900); }

/* ── Utilities ───────────────────────────────────────────────────────────── */

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

.u-measure { max-width: var(--measure); }

.round-md { border-radius: var(--radius-md); overflow: hidden; }
.round-lg { border-radius: var(--radius-lg); overflow: hidden; }
/* height: auto, nicht 100%.
   Mit `height: 100%` loest die Bildhoehe gegen das Elternelement auf, dessen
   Hoehe sich aber erst aus dem Inhalt ergibt — eine Zirkelbeziehung. Auf der
   Startseite fuehrte das im Einzugsgebiet dazu, dass .area__side 539 px hoch
   gemessen wurde, obwohl seine Kinder 821 px brauchten: die Ortsliste lag
   danach mit 350x137 px ueber dem Betriebsfoto und der Adressblock mit
   350x146 px ueber der Ortsliste. Mit `auto` bestimmt `aspect-ratio` die
   Hoehe, wie es die drei Nutzungsstellen ohnehin erwarten. Bilder, die eine
   feste Flaeche fuellen sollen, bekommen ihre Hoehe in der jeweiligen
   Komponente (z. B. .card__media img). */
img.round-lg, img.round-md { display: block; width: 100%; height: auto; object-fit: cover; }

/* Versal-Label (Bauanleitung §3.3) — zweites typografisches Instrument neben
   dem Groessensprung. Genutzt von Beleg-Leiste, Werkbericht, Kostenkompass,
   Einzugsgebiet. misc.css setzt darauf auf (.costform .label, .area__nap .label). */
.label {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-500);
  line-height: 1.2;
}
.section--dark .label { color: var(--ink-300); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-kicker);
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--green-600);
  margin-bottom: var(--space-4);
}
.eyebrow::before {
  content: '';
  display: inline-block;
  width: 22px;
  height: 8px;
  /* Brand-Motiv "Doppelstab": zwei parallele Linien */
  background-image: linear-gradient(var(--green-500) 0 0), linear-gradient(var(--green-500) 0 0);
  background-size: 22px 2px;
  background-position: 0 2px, 0 5px;
  background-repeat: no-repeat;
  flex: none;
}
.section--dark .eyebrow { color: var(--green-400); }
.section--dark .eyebrow::before {
  background-image: linear-gradient(var(--green-400) 0 0), linear-gradient(var(--green-400) 0 0);
}

/* ── Prosa-Inhalte (aus html-Feldern) ───────────────────────────────────── */

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--space-4); }
.prose h2, .prose h3 { margin-top: var(--space-8); }
.prose p, .prose li { color: var(--color-text); font-size: var(--text-body); }
.prose a { color: var(--color-link); text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--color-link-hover); }
.prose ul { margin-top: var(--space-4); display: grid; gap: var(--space-2); }
.prose ul li {
  position: relative;
  padding-left: 1.75rem;
}
.prose ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 14px;
  height: 2px;
  background: var(--green-500);
}
.prose strong { color: var(--color-heading); }

/* Begriff-Beschreibung-Listen als Kartenreihe (Opt-in ueber die Klasse im
   html-Feld). Grund: eine Prosasektion ohne Bild steht auf dem Lesemass von
   rund 715 px, im 1280er Container bleiben daneben ueber 500 px leer.
   Fliesstext darf dort nicht hin — 1280 px Zeilenlaenge liest niemand.
   Kurze Paare schon: drei Spalten ergeben rund 48 Zeichen je Zeile.
   Verworfen wurde vorher, Aufzaehlungen pauschal zweispaltig zu setzen —
   bei drei Punkten steht der dritte allein und darueber klafft ein
   halbbreites Loch. Deshalb Karten und Spaltenzahl = Punktzahl.
   Optik bewusst identisch zu .feature (weiss, 1 px ink-100, radius-md),
   damit kein zweites Kartenvokabular entsteht. */
.prose ul.prose-cards { margin-top: var(--space-5); gap: var(--space-4); }
.prose ul.prose-cards > li {
  padding: var(--space-6);
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--ink-500);
}
.prose ul.prose-cards > li::before { content: none; }
.prose ul.prose-cards > li > strong {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-h4);
  font-weight: 600;
  color: var(--ink-800);
}
.section--tint .prose ul.prose-cards > li,
.section--alt .prose ul.prose-cards > li { background: var(--white); }
/* Erst ab 1024 px nebeneinander. Bei 900 px waere jede Karte 269 px breit,
   der Text darin rund 30 Zeichen je Zeile — zu schmal. Ab 1024 px sind es
   314 px und rund 36 Zeichen, ab 1280 px 391 px.
   Nur dann gibt der Prosablock auch das Lesemass frei, und darin nur die
   Kartenliste: Absaetze davor und danach bleiben auf --measure.
   Ohne :has() bleiben die Karten im Lesemass — schmaler, nicht kaputt. */
@media (min-width: 1024px) {
  .prose ul.prose-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .prose:has(> ul.prose-cards) { max-width: none; }
  .prose:has(> ul.prose-cards) > :not(ul.prose-cards) { max-width: var(--measure); }
}

/* Doppelstab-Divider — farbsteuerbare Utility (Bauanleitung §3.1).
   Die Farbe laeuft ueber --dbl, damit die Modifier greifen, ohne das
   background-image zu wiederholen. */
.rule-doublebar {
  --dbl: var(--ink-100);
  border: 0;
  height: 7px;
  background-image: linear-gradient(var(--dbl) 0 0), linear-gradient(var(--dbl) 0 0);
  background-size: 100% 2px;
  background-position: 0 0, 0 5px;
  background-repeat: no-repeat;
}
.rule-doublebar--green { --dbl: var(--green-500); }
.rule-doublebar--ink   { --dbl: var(--ink-200); }
.rule-doublebar--light { --dbl: rgba(255, 255, 255, 0.22); }
/* Senkrechte Variante (Trenner in den Werkdaten-Zeilen des Werkberichts).
   height bleibt auto und die Hoehe kommt ueber align-self:stretch aus dem
   Flex-Kontext: das in der Bauanleitung notierte height:100% loest gegen den
   hoehenlosen Flex-Container zu 0 auf, der Trenner waere unsichtbar. */
.rule-doublebar--v {
  width: 7px;
  height: auto;
  align-self: stretch;
  background-size: 2px 100%;
  background-position: 0 0, 5px 0;
}


/* ── layout.css ─────────────────────────────────────────── */
/* ==========================================================================
   LAYOUT — Container, Full-Bleed-Grid, Sektions-Rhythmus
   ========================================================================== */

/* Standard-Container */
.l-container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.l-container--wide   { max-width: var(--container-wide); }
.l-container--form   { max-width: var(--container-form); }
/* Der schmale Container (vorher 800 px, mittig) hielt nur ein Lesemass, das die
   Kinder ohnehin selbst tragen: .prose und .faq__answer sind auf --measure
   begrenzt, .section-head auf 42rem. Bezahlt wurde das mit einer verschobenen
   Rasterkante — gemessen bei 1440 px begannen Eyebrow, H2 und FAQ-Zeilen der
   Sektion bei 359,9 px, waehrend Logo, Breadcrumb, H1 und jede andere
   Ueberschrift derselben Seite bei 119,9 px stehen (29 Ueberschriften auf 23
   Seiten: 20 FAQ-Sektionen und 3 x 3 in den Stellendetails). Jetzt gleiche Kante
   wie der Standardcontainer; die Trennlinien der FAQ laufen bis zur rechten
   Containerkante und damit buendig mit Beleg-Leiste und Galerie. */
.l-container--narrow { max-width: var(--container-max); }

/* Full-Bleed-Grid: Content in Mittelspalte, Medien greifen über volle Breite.
   Wird auf dem Haupt-<main> gesetzt; Kinder ohne Klasse landen in "content". */
.l-flow > * {
  grid-column: content;
}
.l-flow {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, calc((var(--container-wide) - var(--container-max)) / 2))
    [content-start] min(100% - 2 * var(--gutter), var(--container-max)) [content-end]
    minmax(0, calc((var(--container-wide) - var(--container-max)) / 2)) [wide-end]
    minmax(var(--gutter), 1fr) [full-end];
}
.l-full { grid-column: full; }
.l-wide { grid-column: wide; }

/* Sektion */
.section {
  padding-block: var(--section-pad);
  background: var(--color-bg);
  color: var(--color-text);
}
.section--sm  { padding-block: var(--section-pad-sm); }
.section--tint { background: var(--color-bg-tint); }
.section--alt  { background: var(--color-bg-alt); }
.section--flush-top { padding-top: 0; }
.section--flush-bottom { padding-bottom: 0; }

/* Sektion-Kopf */
.section-head {
  max-width: 42rem;
  margin-bottom: var(--space-10);
}
/* Galerie-, Slider- und Werkbericht-Sektionen stehen im 1440er-Container, damit
   die Bildflaechen breiter laufen. Ihre Ueberschrift stand dadurch bei 39,9 px,
   waehrend jede andere Ueberschrift der Seite bei 119,9 px beginnt (gemessen
   bei 1440 px). Der Kopf wird deshalb auf die Kante des Standardcontainers
   eingerueckt — die Bilder darunter bleiben breit. */
.l-container--wide > .section-head {
  margin-inline-start: max(0px, calc((100% + 2 * var(--gutter) - var(--container-max)) / 2));
}
.section-head--center {
  margin-inline: auto;
  text-align: center;
}
.section-head--center .eyebrow { justify-content: center; }
.section-head__title { color: var(--color-heading); }
.section-head__lead {
  margin-top: var(--space-4);
  font-size: var(--text-lead);
  color: var(--color-text-muted);
  max-width: var(--measure-lead);
}
.section-head--center .section-head__lead { margin-inline: auto; }

/* Grid-Helfer (auto-fit, responsive ohne Breakpoint-Wald) */
.grid {
  display: grid;
  gap: var(--grid-gap);
}
.grid--auto-sm { grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); }
.grid--auto-md { grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); }
.grid--auto-lg { grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr)); }
/* Feste Spaltenzahlen für ausgewogene Sets (kein einzelnes Waisen-Element) */
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
/* Alle .grid--4 im Bestand haben 4 oder 8 Kacheln. Drei Spalten ergaben daraus
   3 + 1 bzw. 8 = 3+3+2 — gemessen 22 Waisenkarten bei 900 und 1024 px. Die
   Spaltenbreite wird deshalb unterhalb von 1100 px auf mindestens die halbe
   Zeile gesetzt: damit sind nur noch 2 oder 1 Spalten moeglich, die Kachelzahl
   geht in beiden Faellen auf. Zeilenzahl bleibt gleich (2 statt 3+1). */
.grid--4 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, max(250px, (100% - var(--grid-gap)) / 2)), 1fr));
}
@media (min-width: 1100px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}
/* Vier Spalten erst, wenn sie auch 250 px breit sein duerfen: bei 1100 px waren
   es gemessen 239 px, und zwei Kartentitel brachen dort auf drei Zeilen. */
@media (min-width: 1150px) {
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
}
/* Sieben Kacheln gehen in keiner Spaltenzahl glatt auf. Drei Spalten ergaben
   3 + 3 + 1 — eine Waisenkarte allein in der letzten Zeile, gemessen bei
   1024–1920 px auf /industrie-und-sicherheit/ und
   /tier-forst-und-landwirtschaft/. Vier Spalten machen daraus 4 + 3: die
   letzte Zeile ist zwar auch nicht voll, aber kein Einzelstueck mehr.
   Die Grenze liegt bei 1280 px, weil die Karte dort noch 279 px breit ist und
   alle sieben Titel zweizeilig bleiben; bei 1150 px waeren es 249 px und
   "Zaeune, Netze & Tore fuer Sportstaetten" braeche auf drei Zeilen
   (nachgemessen). Unterhalb 1280 px bleibt es bei drei Spalten — vier waeren
   zu schmal, zwei ergaeben 2+2+2+1 und damit dieselbe Waise. */
@media (min-width: 1280px) {
  .grid--auto-md:has(> :last-child:nth-child(7)) { grid-template-columns: repeat(4, 1fr); }
}
/* Dreier-Sets: unterhalb der Breite, ab der drei 300-px-Spalten passen, wuerde
   auto-fit auf zwei Spalten gehen — aus 3 Kacheln wuerde 2 + 1 (gemessen 15
   Waisen bei 900 px). Genau diese Sets gehen deshalb direkt auf eine Spalte.
   Sets mit 6 Kacheln bleiben zweispaltig, dort geht die Zahl auf. */
@media (max-width: 1015px) {
  .grid--3:has(> :last-child:nth-child(3)) { grid-template-columns: 1fr; }
}

/* Stack */
.stack { display: grid; gap: var(--space-4); align-content: start; }
.stack--lg { gap: var(--space-8); }

/* Cluster (Inline-Gruppe, z.B. Button-Reihen) */
.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
}

/* ── Prosa-Sektion ohne Bild ──────────────────────────────────────────────
   War ab 1000 px zweispaltig: Ueberschrift links (sticky), Text rechts. Das
   sollte verhindern, dass eine breite Ueberschrift ueber schmalem Text steht.
   Die Rechnung ging nicht auf, weil die Textspalte durch --measure (65ch) bei
   rund 650 px gedeckelt ist: die Ueberschriftenspalte trug 39–160 px Inhalt,
   die Textspalte 195–784 px. Gemessen bei 1440 px auf 76 Vorkommen in 42 der
   57 Seiten: 152–529 px leere Flaeche in der linken Spalte, zusammen
   14.927 px; das groesste Loch stand in der Datenschutzerklaerung. Keine
   Spaltenteilung
   schliesst das — die Textspalte kann wegen des Lesemasses nicht breiter und
   damit nicht flacher werden. Zwei Auswege wurden verworfen:
   `align-self: center` fuer die Ueberschrift (dann steht "2. Grundsaetze,
   Rechtsgrundlagen und Empfaenger" mitten neben dem Absatz, den sie
   einleitet) und ein schmaleres Kopf-Verhaeltnis (0,62fr brachte nur
   293 -> 228 px und beim groessten Loch gar nichts).
   Jetzt einspaltig — dasselbe Muster wie .section-head auf jeder anderen
   Sektion: Ueberschrift mit eigenem Mass darueber, Text im Lesemass darunter.
   Loch danach: 0 px. Preis: die betroffenen Seiten werden im Median 118 px
   hoeher (+3,0 %); zusammen mit der Kantenkorrektur am schmalen Container
   liegt die Spanne ueber alle 42 Seiten bei −435 bis +840 px, das Maximum
   traegt die Datenschutzerklaerung. */
.prose-split {
  display: grid;
  gap: var(--space-6);
}
/* gleiche Zeilenlaenge wie .section-head, damit die Ueberschrift nicht ueber
   die volle Containerbreite laeuft — das war der Grund fuer die alte Spalte */
.prose-split__head { max-width: 42rem; }
.prose-split__body > .prose { max-width: var(--measure); }
/* VERWORFEN: Aufzaehlungen ab 1100 px zweispaltig, damit rechts neben dem
   Lesemass keine leere Flaeche stehen bleibt. Funktioniert nur bei gerader
   Punktzahl. Die haeufigste Liste hat drei Punkte — dann steht der dritte
   allein in der linken Spalte und unter dem zweiten klafft ein Loch ueber die
   halbe Sektionsbreite. Das sieht kaputter aus als die leere Flaeche vorher.
   Fuellung der freien Flaeche gehoert auf die Inhaltsebene (Bild, Karten),
   nicht in eine pauschale Layoutregel. */

/* Zwei aufeinanderfolgende Sektionen mit gleichem Hintergrund gehören optisch
   zusammen – dann darf zwischen ihnen nicht doppelt gepolstert werden. */
.section--alt + .section--alt,
.section--tint + .section--tint,
.section--dark + .section--dark,
.section:not(.section--alt):not(.section--tint):not(.section--dark)
  + .section:not(.section--alt):not(.section--tint):not(.section--dark) {
  padding-top: 0;
}


/* ── components/buttons.css ─────────────────────────────────────────── */
/* ==========================================================================
   BUTTONS — Signature: Grünfläche + Anthrazit-Text
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-button);
  letter-spacing: 0.02em;
  line-height: 1;
  padding: 0.95rem 1.75rem;
  border-radius: var(--radius-control);
  border: 2px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: transform var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast), color var(--dur-fast),
    border-color var(--dur-fast), box-shadow var(--dur-fast);
  /* darf auf sehr schmalen Screens umbrechen statt den Viewport zu sprengen */
  max-width: 100%;
  text-wrap: balance;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
/* Kein Weichzeichner-Schatten: eine harte, versetzte Kante liest sich
   handwerklich statt nach Material-Design-Vorlage. */
.btn--primary { box-shadow: 0 2px 0 0 var(--green-700); }
.btn--primary:hover { box-shadow: 0 3px 0 0 var(--green-700); }
.btn--primary:active { box-shadow: 0 1px 0 0 var(--green-700); }

.btn__icon { width: 1.15em; height: 1.15em; flex: none; }
.btn__icon--end { transition: transform var(--dur-fast) var(--ease-out); }
.btn:hover .btn__icon--end { transform: translateX(3px); }

/* Primär: Signature-CTA */
.btn--primary {
  background: var(--color-cta-bg);
  color: var(--color-cta-text);
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover {
  background: var(--color-cta-hover);
  color: var(--ink-950);
  box-shadow: var(--shadow-md);
}

/* Sekundär: Outline anthrazit */
.btn--secondary {
  background: transparent;
  color: var(--ink-800);
  border-color: var(--ink-200);
}
.btn--secondary:hover {
  background: var(--ink-800);
  color: var(--white);
  border-color: var(--ink-800);
}

/* Ghost auf dunklem Grund / über Bildern */
.btn--ghost {
  background: transparent;
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.55);
}
.btn--ghost:hover {
  background: var(--white);
  color: var(--ink-900);
  border-color: var(--white);
}

/* Invertiert (auf grünem CTA-Band) */
.btn--invert {
  background: var(--white);
  color: var(--ink-950);
}
.btn--invert:hover {
  background: var(--ink-950);
  color: var(--white);
}

/* Lade-Zustand (Formular-Submit): Breite bleibt stabil */
.btn.is-loading {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.btn.is-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1.15em;
  height: 1.15em;
  border: 2px solid currentColor;
  border-color: var(--ink-950) transparent var(--ink-950) transparent;
  border-radius: 50%;
  animation: btn-spin 700ms linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn:disabled { opacity: 0.75; cursor: default; }

/* Größen */
.btn--lg { padding: 1.1rem 2.25rem; font-size: 1.0625rem; }
.btn--sm { padding: 0.65rem 1.2rem; font-size: var(--text-sm); }
.btn--block { display: flex; width: 100%; }

/* Text-Link mit Pfeil */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  color: var(--green-600);
}
.link-arrow svg { width: 1.05em; height: 1.05em; transition: transform var(--dur-fast) var(--ease-out); }
.link-arrow:hover { color: var(--green-700); }
.link-arrow:hover svg { transform: translateX(4px); }
.section--dark .link-arrow { color: var(--green-300); }
.section--dark .link-arrow:hover { color: var(--green-200); }


/* ── components/header.css ─────────────────────────────────────────── */
/* ==========================================================================
   HEADER / TOPBAR / NAV
   ========================================================================== */

/* ── Topbar (dünn, Kontaktinfos, mobil ausgeblendet) ─────────────────────── */
.topbar {
  background: var(--ink-900);
  color: var(--ink-300);
  font-size: var(--text-sm);
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 38px;
  padding-block: 0.3rem;
}
.topbar__group { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.topbar__item {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--ink-300);
  min-height: 26px; /* Klickfläche (WCAG 2.2 Target Size) */
}
.topbar__item svg { width: 15px; height: 15px; color: var(--green-400); flex: none; }
a.topbar__item:hover { color: var(--white); }
.topbar__promo {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--green-300);
  font-weight: 500;
}
.topbar__promo svg { width: 15px; height: 15px; flex: none; }
.topbar__social { display: inline-flex; gap: 0.25rem; }
.topbar__social a {
  color: var(--ink-300);
  /* Klickfläche >= 24px (WCAG 2.2 Target Size) */
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
}
.topbar__social a:hover { color: var(--white); }
.topbar__social .icon { width: 16px; height: 16px; }
/* Unter 1055 px passt die Topbar nicht mehr einzeilig und waechst auf 82 px.
   Der Aktions-Hinweis ist der verzichtbarste Teil und weicht zuerst.
   Nachgemessen in 1-px-Schritten: Umbruch bis einschliesslich 1054 px, ab
   1055 px einzeilig. Die alte Grenze von 1004 px liess das Band 1005–1054 px
   zweizeilig stehen. 1059 statt 1055 als Sicherheitsabstand, weil der Inhalt
   (Telefon, Zeiten, E-Mail) aus site.json kommt. */
@media (max-width: 1059px) { .topbar__promo { display: none; } }
@media (max-width: 900px) { .topbar { display: none; } }

/* ── Header (sticky) ─────────────────────────────────────────────────────── */
.header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--white);
  border-bottom: 1px solid transparent;
  transition: box-shadow var(--dur-med), border-color var(--dur-med);
}
.header.is-stuck {
  box-shadow: var(--shadow-sm);
  border-bottom-color: var(--ink-100);
}
.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: var(--header-h);
}
.header__logo { display: inline-flex; align-items: center; flex: none; }
/* Das Markenlogo ist eine breite Wortmarke (ca. 7:1) */
.header__logo .site-logo { height: 30px; width: auto; }
@media (max-width: 1100px) { .header__logo .site-logo { height: 26px; } }
@media (max-width: 640px) { .header__logo .site-logo { height: 24px; } }
.mobile-nav__logo { height: 24px; width: auto; }

/* ── Hauptnavigation (Desktop) ───────────────────────────────────────────── */
.nav { display: flex; align-items: center; gap: var(--space-2); }
.nav__list { display: flex; align-items: center; gap: 0.35rem; }
.nav__item { position: relative; }
.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.55rem 0.85rem;
  font-weight: 500;
  color: var(--ink-700);
  border-radius: var(--radius-sm);
  position: relative;
}
.nav__link:hover, .nav__link[aria-expanded='true'] { color: var(--green-600); }
.nav__link::after {
  content: '';
  position: absolute;
  left: 0.85rem; right: 0.85rem;
  bottom: 0.35rem;
  height: 2px;
  background: var(--green-500);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-fast) var(--ease-out);
}
.nav__link:hover::after,
.nav__item.is-current > .nav__link::after,
.nav__link[aria-expanded='true']::after { transform: scaleX(1); }
.nav__caret { width: 14px; height: 14px; transition: transform var(--dur-fast); }
.nav__link[aria-expanded='true'] .nav__caret { transform: rotate(180deg); }

/* Zwischen Burger-Grenze (980px) und ~1240px ist die Zeile knapp: das breite
   7:1-Wortmarken-Logo, 5 Navipunkte und der CTA teilen sich denselben Platz.
   Ohne Gegenmaßnahme bricht „Zäune & Tore" auf 2–3 Zeilen und der Header
   wächst von 76 auf 94 px. Deshalb hier enger setzen statt umbrechen lassen. */
.nav__link { white-space: nowrap; }
@media (max-width: 1240px) {
  .nav__list { gap: 0.1rem; }
  .nav__link { padding-inline: 0.5rem; }
  .nav__link::after { left: 0.5rem; right: 0.5rem; }
  /* Die Telefonnummer steht in dieser Breite bereits in der Topbar. */
  .header__tel { display: none; }
}

/* Dropdown (einfach, 1 Ebene) */
.nav__dropdown {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  min-width: 260px;
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-3);
  display: grid;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--dur-fast), transform var(--dur-fast), visibility var(--dur-fast);
}
.nav__item:hover .nav__dropdown,
.nav__dropdown.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.nav__dropdown a {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.65rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--ink-700);
  font-weight: 500;
}
.nav__dropdown a:hover { background: var(--green-50); color: var(--green-700); }
.nav__dropdown a small {
  display: block;
  font-weight: 400;
  font-size: var(--text-xs);
  color: var(--ink-400);
}

/* Zweispaltiges Dropdown: links die Einsatzbereiche, rechts die Produktebene.
   Bewusst nur eine zweite Spalte, keine dritte Menueebene (Kundenvorgabe). */
.nav__dropdown--wide {
  /* 264 px in der rechten Spalte, damit „Doppelstabmattenzaun 8/6/8" einzeilig
     bleibt — bei 232 px brach der laengste Produktname um. */
  grid-template-columns: minmax(272px, 1fr) minmax(264px, 1fr);
  gap: var(--space-5);
  padding: var(--space-4);
}
.nav__col { display: grid; gap: 2px; align-content: start; }
.nav__col--featured { border-left: 1px solid var(--ink-100); padding-left: var(--space-4); }
/* Bewusst ohne Versalien und ohne Sperrung: die Site hat davon bereits zu
   viele Systeme — hier reicht die kleinere, ruhigere Schriftgroesse. */
.nav__col-title {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-500);
  padding: 0 0.75rem;
  margin-bottom: 0.35rem;
}
.nav__col--featured a { padding-block: 0.5rem; }

.header__actions { display: flex; align-items: center; gap: var(--space-3); flex: none; }
.header__tel {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: var(--ink-800);
  padding: 0.5rem 0.6rem;
}
.header__tel svg { width: 18px; height: 18px; color: var(--green-600); }
.header__tel:hover { color: var(--green-700); }
@media (max-width: 1180px) { .header__tel-label { display: none; } }

/* Der Korridor direkt über der Burger-Grenze ist der engste der Site: 981 px
   Fenster = 919 px Container, darin Wortmarke 185 + Navigation 518 + Aktionen
   231 + zwei Abstände 48 = 982 px. Gemessen liefen die Aktionen dort 32 px
   über den rechten Fensterrand hinaus (Startseite, 981–1048 px). Hier wird
   deshalb enger gesetzt statt umzubrechen. */
@media (min-width: 981px) and (max-width: 1099px) {
  .header__inner { gap: var(--space-4); }
  .header__logo .site-logo { height: 24px; }
  .header__actions { gap: var(--space-2); }
  .header__actions .btn { padding-inline: 1.1rem; }
}

/* ── Mobile-Toggle ───────────────────────────────────────────────────────── */
.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--ink-800);
}
.nav-toggle svg { width: 26px; height: 26px; }
.nav-toggle .icon-close { display: none; }

@media (max-width: 980px) {
  .nav--desktop { display: none; }
  .header__tel { display: none; }
  .nav-toggle { display: inline-flex; }
}
/* Auf Mobile übernimmt die Sticky-Bottom-Bar den CTA -> Header bleibt schlank */
@media (max-width: 640px) {
  .header__actions > .btn { display: none; }
}

/* ── Mobile-Overlay-Menü ─────────────────────────────────────────────────── */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--ink-800);
  color: var(--white);
  display: flex;
  flex-direction: column;
  /* Geschlossen: ausgeblendet. Bewusst KEIN horizontaler Transform – ein
     seitlich verschobenes fixed-Element erzeugt horizontalen Overflow. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1.25rem);
  pointer-events: none;
  transition: opacity var(--dur-med) var(--ease-out),
    transform var(--dur-med) var(--ease-out),
    visibility var(--dur-med);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-nav.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}
.mobile-nav__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--gutter);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.mobile-nav__head .site-logo { height: 24px; width: auto; }
.mobile-nav__close {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--white);
  border-radius: var(--radius-sm);
}
.mobile-nav__close svg { width: 28px; height: 28px; }
.mobile-nav__body { flex: 1; padding: var(--space-6) var(--gutter); }
.mobile-nav__list { display: grid; gap: 0.25rem; }
/* Alle fuenf Zeilen der obersten Ebene sind gleich hoch. Vorher standen
   Akkordeon-Zeilen auf 64 px und einfache Links auf 41 px, weil der Link ein
   Inline-Element war und sein Polster die Zeilenhoehe nicht mitnahm. */
.mobile-nav__link,
.m-acc__trigger {
  min-height: 56px;
  padding-block: 0.35rem;
}
.mobile-nav__link {
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.6rem;
  color: var(--white);
  /* dieselbe Trennlinie wie unter den Akkordeon-Zeilen, damit alle fünf
     Zeilen der obersten Ebene gleich gebaut sind. 57 statt 56, weil die Linie
     bei border-box sonst von der Textzeile abginge — beim Akkordeon sitzt sie
     am umschliessenden .m-acc und kommt oben drauf. */
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  min-height: 57px;
  padding-inline: 0; letter-spacing: -0.008em;}
.mobile-nav__link:hover { color: var(--green-300); }

.m-acc { border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.m-acc__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.6rem;
  color: var(--white);
  padding-inline: 0;
  text-align: left; letter-spacing: -0.008em;}
.m-acc__trigger svg { width: 22px; height: 22px; transition: transform var(--dur-fast); flex: none; }
.m-acc__trigger[aria-expanded='true'] svg { transform: rotate(45deg); }
.m-acc__panel { display: none; padding: 0 0 var(--space-4) var(--space-2); }
.m-acc__panel.is-open { display: grid; gap: 0.15rem; }
.m-acc__panel a {
  color: var(--ink-300);
  padding: 0.45rem 0;
  font-weight: 500;
  font-size: 1.05rem;
  min-height: 44px;
  display: flex;
  align-items: center;
}
.m-acc__panel a:hover { color: var(--white); }
/* Zwischenueberschrift der Produktgruppe — keine dritte Menueebene, nur eine
   Beschriftung innerhalb derselben flachen Liste. */
.m-acc__caption {
  /* ink-300 auf ink-800 = 6,1 : 1. ink-400 waere mit 3,75 : 1 unter AA. */
  color: var(--ink-300);
  font-size: var(--text-sm);
  font-weight: 600;
  margin-top: var(--space-3);
  padding-bottom: 0.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding-top: var(--space-3);
}

.mobile-nav__foot {
  padding: var(--space-6) var(--gutter);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: grid;
  gap: var(--space-3);
  background: var(--ink-900);
}
/* Sekundär-Button auf dunklem Grund: heller Text statt Anthrazit */
.mobile-nav__foot .btn--secondary {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.45);
}
.mobile-nav__foot .btn--secondary:hover {
  background: var(--white);
  color: var(--ink-900);
  border-color: var(--white);
}
.mobile-nav__hours {
  color: var(--ink-400);
  font-size: var(--text-sm);
  text-align: center;
}

body.is-menu-open { overflow: hidden; }

/* ── Mobile Sticky-Bottom-Bar (ersetzt Topbar mobil) ─────────────────────── */
.mobile-bar {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  background: var(--white);
  border-top: 1px solid var(--ink-100);
  box-shadow: 0 -4px 16px rgba(20, 24, 30, 0.1);
  padding: 0.5rem;
  gap: 0.5rem;
  padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
}
.mobile-bar .btn { flex: 1; padding: 0.85rem 1rem; }
@media (max-width: 980px) {
  .mobile-bar { display: flex; }
  body { padding-bottom: 70px; }
  /* Auf /danke/ wird die Bar gar nicht erst gerendert (sie würde dort weiter
     für die bereits abgeschickte Anfrage werben) — dann entfällt auch der
     Platzhalter am Seitenende. Bewusst als :not(:has()) geschrieben: kennt ein
     Browser :has() nicht, fällt die Regel weg und es bleibt beim alten Polster,
     statt dass die Bar den Fußbereich überdeckt. */
  body:not(:has(.mobile-bar)) { padding-bottom: 0; }
  /* Formularseiten: der zweite Knopf würde zur laufenden Anfrage einladen und
     die Schritt-Navigation verdecken. Die Anruf-Zeile bleibt aber stehen —
     ohne sie ist auf /online-anfrage/, /bewerbung/ und /contacts/ mobil keine
     Telefonnummer in Reichweite. */
  body.is-form-page .mobile-bar .btn--primary { display: none; }
}


/* ── components/footer.css ─────────────────────────────────────────── */
/* ==========================================================================
   FOOTER
   ========================================================================== */

.footer {
  background: var(--ink-900);
  color: var(--ink-300);
  position: relative;
}
/* Doppelstab-Kante oben */
.footer::before {
  content: '';
  display: block;
  height: 4px;
  background: var(--green-500);
}
.footer__main {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr 1.2fr;
  gap: var(--space-8) var(--space-6);
  padding-block: var(--space-20) var(--space-16);
}
@media (max-width: 1100px) { .footer__main { grid-template-columns: 1fr 1fr 1fr; } }
@media (max-width: 720px)  { .footer__main { grid-template-columns: 1fr 1fr; gap: var(--space-8) var(--space-6); } }
@media (max-width: 460px)  { .footer__main { grid-template-columns: 1fr; } }

.footer__brand { display: grid; gap: var(--space-4); align-content: start; }
@media (max-width: 1100px) { .footer__brand { grid-column: 1 / -1; } }
@media (max-width: 460px)  { .footer__brand { grid-column: auto; } }
.footer__logo .site-logo { height: 36px; width: auto; }
@media (max-width: 640px) { .footer__logo .site-logo { height: 30px; } }
.footer__claim {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.25rem;
  color: var(--white);
  letter-spacing: -0.008em;
}
.footer__social { display: flex; gap: 0.6rem; margin-top: var(--space-2); }
.footer__social a {
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--ink-600);
  border-radius: 50%;
  color: var(--ink-300);
  transition: border-color var(--dur-fast), color var(--dur-fast), background var(--dur-fast);
}
.footer__social a:hover { border-color: var(--green-500); color: var(--white); background: var(--green-600); }
.footer__social svg { width: 18px; height: 18px; }

.footer__col-title {
  font-family: var(--font-body);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.9rem;
  letter-spacing: 0.10em;
  color: var(--ink-300);
  margin-bottom: var(--space-4);
}
.footer__links { display: grid; gap: 0.15rem; }
/* Klickfläche >= 24px (WCAG 2.2 Target Size) */
.footer__links a {
  display: inline-block;
  color: var(--ink-300);
  font-size: var(--text-sm);
  padding-block: 0.3rem;
}
.footer__links a:hover { color: var(--white); }

.footer__contact { display: grid; gap: var(--space-2); }
.footer__contact-item {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  color: var(--ink-300);
  font-size: var(--text-sm);
  padding-block: 0.25rem;
}
.footer__contact-item svg { width: 16px; height: 16px; color: var(--green-400); flex: none; margin-top: 2px; }
a.footer__contact-item:hover { color: var(--white); }

.footer__bottom {
  background: var(--ink-950);
  color: var(--ink-300);
  font-size: var(--text-xs);
}
.footer__bottom-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-block: var(--space-4);
}
.footer__legal { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.footer__legal a { color: var(--ink-300); display: inline-block; padding-block: 0.3rem; }
.footer__legal a:hover { color: var(--ink-200); }


/* ── components/hero.css ─────────────────────────────────────────── */
/* ==========================================================================
   HERO — Video (Home), Split (Unterseiten), Kompakt (2. Ebene)
   ========================================================================== */

/* ── Video-Hero (Home) ───────────────────────────────────────────────────── */
.hero-video {
  position: relative;
  min-height: min(92svh, 900px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--ink-800);
  isolation: isolate;
}
.hero-video__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover;
}
.hero-video__overlay {
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Der senkrechte Verlauf ist am Kicker (37,5 % der Hero-Hoehe) mit 0,06 fast
     wirkungslos — dort steht im Film eine helle Hallenwand. Der seitliche
     Verlauf deckt genau die Textspalte ab (x 0–46 % bei 1440 px) und laesst
     das Motiv rechts frei; er traegt deshalb die Lesbarkeit auf dem Desktop.
     Vorher 0,40 auf 0 bei 55 %: gemessen fielen 49–50 % der Kicker-Pixel unter
     4,5 : 1. Jetzt bis 0,68. */
  /* Stopps in px, nicht in Prozent: die Textspalte endet unabhaengig von der
     Fensterbreite bei rund 700 px vom linken Containerrand — mit
     Prozentstopps wurde der Verlauf bei 1920 px genau unter dem Kicker
     duenner (dort fielen noch 2,4 % der Pixel durch). */
  background: var(--overlay-hero),
    linear-gradient(90deg, rgba(20, 24, 30, 0.70) 0%, rgba(20, 24, 30, 0.62) 720px, rgba(20, 24, 30, 0) 1120px);
}
.hero-video__inner {
  width: 100%;
  padding-block: var(--space-16) var(--space-24);
}
/* Zweite Spalte für die Angebotskarte, sobald sie neben den Text passt */
@media (min-width: 1080px) {
  .hero-video__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(320px, 384px);
    gap: var(--space-12);
    align-items: end;
  }
}
@media (max-width: 980px) {
  /* Platz für die Sticky-Bottom-Bar lassen */
  .hero-video { min-height: min(88svh, 760px); }
  .hero-video__inner { padding-block: var(--space-12) var(--space-16); }
}
.hero-video__content { max-width: 40rem; color: var(--white); }
/* --green-300 erreichte ueber den hellen Filmbildern nur 2,6–4,1 : 1 (14 px,
   Soll 4,5) — gemessen fielen 83–100 % der Glyphenpixel durch. --green-200
   auf derselben Flaeche unter dem verstaerkten Verlauf: siehe Messung. */
.hero-video .eyebrow { color: var(--green-200); }
.hero-video .eyebrow::before {
  background-image: linear-gradient(var(--green-400) 0 0), linear-gradient(var(--green-400) 0 0);
}
.hero-video__title {
  font-size: var(--text-display);
  line-height: 1.02;
  color: var(--white);
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.35);
}
.hero-video__title .mark {
  position: relative;
  white-space: nowrap;
}
/* Markenmotiv "Doppelstab" statt Textmarker-Balken */
.hero-video__title .mark::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  bottom: -0.02em;
  height: 8px;
  background-image: linear-gradient(var(--green-500) 0 0), linear-gradient(var(--green-500) 0 0);
  background-size: 100% 3px;
  background-position: 0 0, 0 5px;
  background-repeat: no-repeat;
  z-index: 0;
}
.hero-video__lead {
  margin-top: var(--space-5);
  font-size: var(--text-lead);
  color: rgba(255, 255, 255, 0.92);
  max-width: 34rem;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.4);
}
.hero-video__actions { margin-top: var(--space-8); }

/* Unterhalb von 1080 px rutscht die Angebotskarte unter den Textblock — der
   Text wandert damit aus der dunklen Fusszone in die helle obere Haelfte des
   Films. Gemessen (Anteil der Glyphenpixel unter 4,5 : 1, reines Weiss als
   Vordergrund, also die guenstigste Annahme): 390 px ueber dem Posterbild
   75,2 %, 768 px ueber vier Videoframes bis 90,4 %, 1024 px bis 83,8 %.
   Ab 1080 px sitzt der Lead bei 62–78 % der Hero-Hoehe und ist unauffaellig
   (Median 8,9–15,9). Deshalb hier ein durchgehender Verlauf statt des
   Fussverlaufs — die Regel steht hinter .hero-video .eyebrow, weil sie sonst
   bei gleicher Spezifitaet verliert. */
@media (max-width: 1079px) {
  .hero-video__overlay {
    background: linear-gradient(180deg,
      rgba(20, 24, 30, 0.72) 0%,
      rgba(20, 24, 30, 0.68) 34%,
      rgba(20, 24, 30, 0.76) 66%,
      rgba(20, 24, 30, 0.88) 100%);
  }
  /* --green-300 erreicht ueber dem hellsten Filmbild auch unter diesem
     Verlauf nur 3,5 : 1 (14 px, Soll 4,5). --green-200: 4,5 : 1. */
  .hero-video .eyebrow { color: var(--green-200); }
}
.hero-video__pause {
  position: absolute;
  right: var(--gutter);
  /* Die Beleg-Leiste zieht sich um --proofbar-lift in den Hero — der
     Pause-Button muss um denselben Betrag mit nach oben. */
  bottom: calc(var(--proofbar-lift) + var(--space-6));
  z-index: 2;
  /* Projektregel R15 (min. 44 px). Vorher 42 px am Desktop und 38 px mobil —
     gemessen 38x38 bei 324/390/768/980 px, also 6 px unter dem Soll und
     kleiner als jeder andere Bedienknopf der Seite. Das ist ein
     WCAG-2.2.2-Pflichtelement (Bewegung anhalten). */
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.62);
  /* deckender als zuvor: der Film enthält hellen Himmel und eine weiße
     Halle — über Reinweiß bleiben Icon und Rand so bei 4,98 : 1 */
  background: rgba(20, 24, 30, 0.62);
  color: var(--white);
  backdrop-filter: blur(4px);
}
.hero-video__pause svg { width: 18px; height: 18px; }
.hero-video__pause .icon-play { display: none; }
.hero-video__pause.is-paused .icon-play { display: block; }
.hero-video__pause.is-paused .icon-pause { display: none; }
/* Ab 1080 px steht die Angebotskarte unten rechts — dort deckt sie den
   Pause-Button (gemessen: Karte x 662–1047, Button x 1005–1047 bei 1080 px).
   Der Button ist WCAG 2.2.2-Pflicht und muss bedienbar bleiben. */
@media (min-width: 1080px) {
  .hero-video__pause { top: var(--space-4); bottom: auto; }
}
@media (max-width: 980px) {
  /* Pause-Button oben rechts, damit er die CTAs nicht überlagert. Der Abstand
     zum Menü-Knopf war mit 38 px Größe gemessen 25 px bei 324/390 px — zwei
     runde Bedienelemente gleicher Größe direkt untereinander an derselben
     rechten Kante lesen sich als Paar. --space-6 statt --space-4 bringt die
     Lücke auf 33 px und damit auf denselben Wert wie ab 768 px. */
  .hero-video__pause {
    top: var(--space-6);
    bottom: auto;
  }
  /* Der Knopf sitzt oben rechts ueber dem Textblock und lief in den Kicker
     hinein — gemessen 44x20 px Ueberdeckung bei 324 px, 25x10 bei 390 px.
     Statt die Bedienung zu entfernen (sie ist nach WCAG 2.2.2 Pflicht, solange
     das Hero-Video automatisch in Schleife laeuft) bekommt die erste Textzeile
     rechts Platz. Nur der Kicker, nicht der ganze Block: H1 und Lead beginnen
     erst unterhalb des Knopfes. */
  .hero-video .eyebrow { padding-right: calc(44px + var(--space-4)); }
}

/* ── Angebotskarte im Video-Hero ─────────────────────────────────────────── */
.offer {
  /* KEIN backdrop-filter: über laufendem Video erzwingt jede solche Fläche
     pro Frame eine Neukomposition. Deckende Fläche sieht identisch aus. */
  background: rgba(20, 24, 30, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-6) var(--space-5);
  box-shadow: none;
  display: grid;
  gap: var(--space-4);
}
.offer__kicker {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-300);
}
.offer__list { display: grid; }
.offer__step {
  padding-block: 11px;
  color: var(--ink-200);
  font-size: var(--text-sm);
  line-height: 1.45;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.offer__step:first-child { border-top: 0; padding-top: 0; }
.offer__phone {
  display: inline-flex; align-items: center; gap: 0.5rem;
  justify-content: center;
  /* gemessen 26 px hoch — als Telefon-Link ist das der wichtigste
     Touch-Target der Karte (Projektregel R15: min. 44 px) */
  min-height: 44px;
  color: var(--white); font-weight: 600;
}
.offer__phone:hover { color: var(--green-300); }
.offer__hours { text-align: center; font-size: var(--text-xs); color: var(--ink-300); margin-top: -0.5rem; }

/* Unter 1080 px steht die Karte unter dem Textblock. Mit 32rem endete sie
   gemessen bei 768 px auf x = 539,5, waehrend Titel und Buttons darueber auf
   667,5 endeten und der Lead auf 571,5 — drei Kanten, keine zwei gleich.
   Dieselbe Breite wie .hero-video__content (40rem) macht daraus eine Kante
   fuer Titel, Aktionen und Karte; der Lead bleibt bewusst kuerzer, er traegt
   ein Lesemass (34rem). */
@media (max-width: 1079px) {
  .offer { margin-top: var(--space-8); max-width: 40rem; }
}
@media (max-width: 560px) {
  /* Auf 324–390 px frisst die Liste sonst den halben Hero. Mit ihr verschwindet
     auch die Zwischenzeile „So läuft es ab" — sie kündigt sonst drei Schritte an,
     die nicht kommen. */
  .offer__list,
  .offer__kicker { display: none; }
  .offer { padding: var(--space-5); }
}

/* ── Split-Hero (Unterseiten Ebene 1) ────────────────────────────────────── */
.hero-split {
  position: relative;
  background: var(--white);
}
.hero-split__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  min-height: 460px;
  /* .l-container--wide setzt nur max-width; das mittige Ausrichten steckt in
     .l-container, und die steht an diesem Element nicht. Ab 1440 px klebte der
     ganze Hero deshalb am linken Fensterrand: bei 1920 px lief er von 0 bis
     1440 px, waehrend Kopfzeile und Breadcrumb bei 360 px begannen — rechts
     blieben 480 px weisse Flaeche neben dem Bild stehen (gemessen). */
  margin-inline: auto;
  /* Der Split-Hero stand als einziger Block im 1440er-Container, alles andere
     auf der Seite im 1280er. H1 und Kicker begannen dadurch bei 87,9 px, Logo,
     Breadcrumb und die Sektionsueberschriften bei 119,9 px — gemessen bei
     1440 px auf 49 von 59 Seiten, ein sichtbarer Versatz von 32 px.
     Der Innenabstand holt die Textspalte exakt auf die Kante des
     Standardcontainers (Gutter + halbe Differenz der beiden Containerbreiten);
     die Bildspalte laeuft weiter bis zum aeusseren Rand. */
  padding-inline-start: calc(
    var(--gutter) + max(0px, (min(100%, var(--container-wide)) - var(--container-max)) / 2)
  );
}
.hero-split__content {
  padding-block: var(--section-pad-sm);
  /* Die linke Kante macht jetzt der Container, nicht mehr max-width + justify-self */
  padding-inline: 0 var(--space-12);
  align-self: center;
  min-width: 0;
  width: 100%;
}
.hero-split__media {
  position: relative;
  overflow: hidden;
  min-width: 0; /* Grid-Kind darf nicht durch Bildbreite gesprengt werden */
}
.hero-split__media img,
.hero-split__media picture {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Katalogaufnahmen (freigestelltes Produkt vor hellem Grund) duerfen nicht
   beschnitten werden: bei `cover` fielen auf /gartentore-1-fluegelig/ 36 % und
   auf /wartung-und-reparatur/ 45 % der Bildhoehe weg – vom Tor war der obere
   Abschluss nicht mehr zu sehen. Baustellenfotos bleiben auf `cover`, dort ist
   der Anschnitt gewollt.
   Diese Regeln stehen bewusst NACH der Basisregel: beide haben dieselbe
   Spezifitaet (eine Klasse plus ein Element), es gewinnt also die spaetere.
   Beim ersten Versuch standen sie davor und blieben wirkungslos. */
.hero-split__media--fit {
  background: var(--ink-50);
  padding: var(--space-6);
}
.hero-split__media--fit img,
.hero-split__media--fit picture { object-fit: contain; }
.hero-split__title { margin-top: var(--space-2); }
.hero-split__lead {
  margin-top: var(--space-4);
  font-size: var(--text-lead);
  color: var(--color-text-muted);
  max-width: var(--measure-lead);
}
.hero-split__actions { margin-top: var(--space-6); }
@media (max-width: 860px) {
  /* Einspaltig: das Bild soll wieder randlos ueber die volle Breite laufen,
     der Innenabstand wandert deshalb zurueck an die Textspalte. */
  .hero-split__grid { grid-template-columns: 1fr; padding-inline-start: 0; }
  .hero-split__content { padding-inline: var(--gutter); padding-block: var(--space-10); order: 2; justify-self: stretch; }
  .hero-split__media { order: 1; aspect-ratio: 4 / 3; min-height: 0; }
  .hero-split__media img,
  .hero-split__media picture { position: absolute; inset: 0; width: 100%; height: 100%; }
}

/* ── Kompakt-Hero (Ebene 2, heller Kopf ohne Bild) ───────────────────────── */
.hero-compact {
  background: var(--ink-50);
  /* Bewusst asymmetrisch und kleiner als --section-pad: Direkt darunter folgt
     die Breadcrumb-Leiste und danach die erste Sektion mit vollem Polster.
     Mit --section-pad an dieser Stelle stapeln sich 88 + 16 + 16 + 88 px zu
     einem sichtbaren Loch (auf den drei Formularseiten gemessen). Ein Versuch,
     das auf die Sektionsskala zu vereinheitlichen, hat es verschlimmert. */
  padding-block: var(--space-12) var(--space-10);
  border-bottom: 1px solid var(--ink-100);
}
.hero-compact__title { margin-top: var(--space-2); }
.hero-compact__lead {
  margin-top: var(--space-4);
  font-size: var(--text-lead);
  color: var(--color-text-muted);
  max-width: var(--measure);
}
.hero-compact__actions { margin-top: var(--space-6); }

/* ── Scroll-Cue ──────────────────────────────────────────────────────────── */
.scroll-cue {
  position: absolute;
  left: 50%;
  /* mit der Beleg-Leiste mit nach oben, sonst deckt sie die untere Hälfte ab */
  bottom: calc(var(--proofbar-lift) + var(--space-5));
  transform: translateX(-50%);
  width: 2px; height: 44px;
  z-index: 2;
  overflow: hidden;
}
/* Sobald die Angebotskarte unter dem Text steht (max-width 32rem, links
   ausgerichtet), liegt sie über der Fenstermitte — gemessen bis 1079 px.
   Der rein dekorative Cue würde quer über die Karte laufen. */
@media (max-width: 1079px) {
  .scroll-cue { display: none; }
}
.scroll-cue::after {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 2px; height: 18px;
  background: var(--green-400);
  animation: scroll-cue 1.8s var(--ease-out) infinite;
}
@keyframes scroll-cue {
  0% { transform: translateY(-100%); opacity: 0; }
  40% { opacity: 1; }
  100% { transform: translateY(220%); opacity: 0; }
}

/* Die zweite Hero-Aktion war ein gleich grosser Ghost-Button. Zwei Buttons
   derselben Groesse, einer gefuellt, einer mit Rahmen — genau das Muster, an
   dem generierte Startseiten erkennbar sind. Jetzt eine untergeordnete
   Textaktion: kein Kasten, eigene Hoehe, eindeutige Rangfolge. */
.hero-video__actions .btn--ghost {
  padding: 0.35rem 0;
  border: 0;
  border-bottom: 2px solid rgba(255, 255, 255, 0.35);
  border-radius: 0;
  background: none;
  font-size: var(--text-body);
  letter-spacing: 0.01em;
}
.hero-video__actions .btn--ghost:hover {
  border-bottom-color: var(--green-400);
  color: var(--green-300);
  transform: none;
}


/* ── components/cards.css ─────────────────────────────────────────── */
/* ==========================================================================
   CARDS — Produktkarten, Welten-Kacheln, USP-Leiste, Fakten-Kacheln
   ========================================================================== */

/* ── Produktkarte ────────────────────────────────────────────────────────── */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast);
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.card__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--ink-50); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-slow) var(--ease-out); }
.card:hover .card__media img { transform: scale(1.04); }
.card__body { display: flex; flex-direction: column; gap: 0.5rem; padding: var(--space-6); flex: 1; }
.card__kicker {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  color: var(--green-600);
}
.card__title { font-size: var(--text-h3); font-size: 1.35rem; color: var(--ink-800); }
/* Steht in einer Rasterzeile ein einzeiliger neben einem zweizeiligen Titel,
   beginnt der Kartentext 27 px tiefer (gemessen: 22 Zeilen auf 15 Seiten bei
   1440 px, 30 bei 1024 px). Kein Titel im ganzen Bestand ist laenger als zwei
   Zeilen — zwei Zeilen zu reservieren deckt also den Maximalfall exakt ab.
   Zeilenhoehe aller drei Titel ist 1,25 (gemessen 27 px bei 21,6 px, 25 px bei
   20 px, 32,7 px bei 26,2 px), zwei Zeilen sind damit 2,5em. Erst ab 560 px —
   das ist die kleinste Breite, ab der eines der Raster zweispaltig wird;
   darunter stehen die Karten untereinander und es waere nur Leerraum. */
@media (min-width: 560px) {
  .card__title,
  .feature__title,
  .job-card__title { min-height: 2.5em; }
}
/* Kein -webkit-line-clamp mehr. Es kappte 33 von 93 Kartentexten sichtbar
   (gemessen bei 1440 px: 67–90 px Inhalt in 45 px Fenster) — die Texte sind
   66–95 Zeichen lang und brauchen in einer 300-px-Karte 3 bis 4 Zeilen; auf
   zwei Zeilen liesse sich das nur mit ~55 Zeichen bringen. Die Karten stehen
   im Raster ohnehin auf gleicher Hoehe (align-items:stretch), und .card__foot
   haelt die Fusszeile unten — es entsteht also kein Versatz. Nebeneffekt:
   -webkit-line-clamp war eine der vier Safari-empfindlichen Techniken. */
.card__text {
  color: var(--ink-500);
  font-size: var(--text-sm);
}
.card__foot {
  margin-top: auto;
  padding-top: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.card__more {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 600;
  color: var(--green-600);
  font-size: var(--text-sm);
}
.card__more svg { width: 1em; height: 1em; transition: transform var(--dur-fast) var(--ease-out); }
.card:hover .card__more svg { transform: translateX(4px); }
/* Stretched-Link: ganze Karte klickbar */
.card__link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.card__swatches { display: flex; gap: 0.35rem; }
/* Die alte Doppelkontur (2px Weiß + 1px --ink-100) war auf weißer Karte
   praktisch unsichtbar: --ink-100 erreicht dort 1,15 : 1. Das Zinkmuster stand
   damit ohne erkennbare Grenze auf Weiß (1,94 : 1). --ink-400: 3,71 : 1.
   Gleiche Kontur wie .swatch__chip und .finish__chip. */
.card__swatch {
  width: 18px; height: 18px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--ink-400);
}

/* ── Welten-Kachel (4:5, Bild + Overlay) ─────────────────────────────────── */
.world {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  isolation: isolate;
  background: var(--ink-800);
}
.world__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; transition: transform var(--dur-slow) var(--ease-out); }
.world::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: var(--overlay-tile);
}
.world:hover .world__img { transform: scale(1.05); }
.world__body {
  padding: var(--space-6);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
}
.world__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.55rem;
  line-height: 1.05;
  color: var(--white); letter-spacing: -0.008em;}
.world__arrow {
  flex: none;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.6);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--white);
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.world__arrow svg { width: 20px; height: 20px; }
.world:hover .world__arrow { background: var(--green-500); color: var(--ink-950); border-color: var(--green-500); }
.world__link::after { content: ''; position: absolute; inset: 0; }
/* Tastaturbedienung: gleicher Zoom wie bei :hover, sonst wirkt die Kachel
   bei Tab-Fokus tot. motion.css setzt die Dauer bei Reduced Motion auf 0,01 ms. */
.world:focus-visible .world__img { transform: scale(1.05); }

/* ── Revier-Streifen (layout: "strip", randlos über die volle Breite) ────── */
.worldstrip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: var(--space-10);
}
.world--strip {
  aspect-ratio: auto;
  min-height: 320px;
  border-radius: 0;
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.22);
}
.worldstrip .world--strip:first-child { box-shadow: none; }
.world--strip .world__body { padding: var(--space-5); }
.world--strip .world__title { font-size: 1.375rem; }
.world--strip:focus-visible { outline: 3px solid var(--green-300); outline-offset: -6px; }

@media (max-width: 900px) { .worldstrip { grid-template-columns: repeat(2, 1fr); } .world--strip { min-height: 220px; } }
@media (max-width: 480px) { .worldstrip { grid-template-columns: 1fr; } .world--strip { min-height: 168px; } }

/* ── Beleg-Leiste (überlappt Hero, ersetzt die alte USP-Leiste) ──────────── */
.usp-bar-wrap { position: relative; z-index: 5; }

.proofbar {
  position: relative;
  margin-top: calc(-1 * var(--proofbar-lift));
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.proofbar__rule { display: block; width: 100%; }

.proofbar__facts { display: grid; grid-template-columns: repeat(4, 1fr); }
.proof { padding: var(--space-6); border-left: 1px solid var(--ink-100); min-width: 0; }
.proof:first-child { border-left: 0; }
.proof__value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.75rem, 1.35rem + 1.3vw, 2.5rem);
  line-height: 1;
  color: var(--ink-800);
  font-variant-numeric: tabular-nums; letter-spacing: -0.008em;}
.proof__label { margin-top: var(--space-2); color: var(--ink-800); }
.proof__note  { margin-top: 0.35rem; font-size: var(--text-xs); color: var(--ink-500); line-height: 1.45; }

/* Mittig gesetzte Reihe statt eigener Spalten.
   Vorher drei gleich breite Rasterspalten — in sich symmetrisch, aber die
   Faktenzeile darueber hat vier. Gemessen bei 1440 px: Fakten beginnen bei
   x = 121/421/720/1020, die Sprungmarken bei 121/520/920. Zwei Raster mit
   verschiedener Spaltenzahl uebereinander lesen sich als schief, egal wie
   exakt jedes fuer sich ist. Als mittige Reihe konkurriert die Zeile nicht
   mehr mit den Kanten darueber. */
.proofbar__jump {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  background: var(--surface-tint);
  border-top: 1px solid var(--ink-100);
}
/* Bewusst ohne senkrechte Trenner: die Faktenzeile darueber hat vier Spalten,
   die Sprungzeile drei. Gemessen bei 1440 px lagen die Trenner der Faktenzeile
   bei x = 420,5 / 720 / 1019,5, die der Sprungzeile bei 520,3 / 919,7 — sie
   kreuzten kein einziges Element der Zeile darueber und lasen sich dadurch als
   Versehen. Die drei Sprungmarken sind ohnehin abgegrenzt: eigene Flaeche
   (--surface-tint), Trennlinie nach oben und eine Hover-Flaeche je Feld. */
.jump {
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  min-height: 56px;
  padding: var(--space-4) var(--space-6);
  color: var(--ink-800);
  transition: background var(--dur-fast);
}
.jump:hover { background: var(--green-50); color: var(--ink-800); }
.jump__q { font-weight: 600; }
.jump__a { display: inline-flex; align-items: center; gap: 0.35rem; font-size: var(--text-sm); font-weight: 600; color: var(--green-700); }
.jump__a svg { width: 1em; height: 1em; transition: transform var(--dur-fast) var(--ease-out); }
.jump:hover .jump__a svg { transform: translateX(4px); }

@media (max-width: 1024px) {
  .proofbar__facts { grid-template-columns: repeat(2, 1fr); }
  .proof:nth-child(odd) { border-left: 0; }
  .proof:nth-child(-n+2) { border-bottom: 1px solid var(--ink-100); }
  /* untereinander: hier trennt die waagerechte Linie sinnvoll, sie laeuft
     ueber die ganze Breite und kreuzt nichts schief */
  .proofbar__jump { flex-direction: column; }
  .jump { border-top: 1px solid var(--ink-100); }
  .jump:first-child { border-top: 0; }
}
@media (max-width: 560px) {
  .proofbar__facts { grid-template-columns: 1fr; }
  .proof { border-left: 0; border-bottom: 1px solid var(--ink-100); padding: var(--space-5); }
  .proof:last-child { border-bottom: 0; }
  .proof:nth-child(-n+2) { border-bottom: 1px solid var(--ink-100); }
}

/* ── "Warum Zaunmann" / Fakten-Kacheln (Icon oben) ───────────────────────── */
.feature {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  height: 100%;
}
.section--tint .feature, .section--alt .feature { background: var(--white); }
/* Frueher: 52x52-Quadrat, 12px Radius, gruen getoent, ein Icon darin, direkt
   ueber der h3 — laut Audit exakt die Geometrie, die als KI-Merkmal gilt und
   auf 6 von 10 Seiten vorkam. Jetzt: das Icon steht frei, darueber die
   Doppelstab-Linie des Hauses. Kein Kasten, kein Farbfeld. */
/* Die Doppelstab-Linie ueber dem Icon ist wieder raus: sie stand ohne
   erkennbaren Bezug ueber dem Symbol und wurde als sinnlose Dekoration
   gelesen. Das Markenmotiv traegt weiterhin die Trenner (FAQ, Ablaufkette,
   Kostenkompass, .rule-doublebar) – dort trennt es tatsaechlich etwas. */
.feature__icon {
  display: block;
  color: var(--green-600);
  width: 2.75rem;
}
.feature__icon svg { width: 24px; height: 24px; stroke-width: 1.5; }
.section--dark .feature__icon { color: var(--green-400); }
.feature__title { font-family: var(--font-body); font-weight: 600; font-size: var(--text-h4); color: var(--ink-800); text-transform: none; }
.feature__text { color: var(--ink-500); font-size: var(--text-sm); }
.section--dark .feature {
  background: var(--ink-700);
  border-color: rgba(255, 255, 255, 0.08);
}
.section--dark .feature__title { color: var(--white); }
.section--dark .feature__text { color: var(--ink-300); }
.section--dark .feature__icon { background: rgba(var(--green-500-rgb), 0.16); color: var(--green-300); }

/* ── Katalog-Karte (Hersteller-Renders, ruhige Fläche) ───────────────────── */
.catalog-card {
  background: var(--ink-50);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  text-align: center;
}
.catalog-card img { width: 100%; aspect-ratio: 1; object-fit: contain; }
/* Kicker trägt die Einordnung (Preisbewusst, RAL 6005 …). Bewusst ohne
   Versalien und Sperrung: die Site hat davon ohnehin genug, und eine
   RAL-Nummer in Großbuchstaben liest sich schlechter, nicht besser. */
.catalog-card__kicker {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--green-700);
}
.catalog-card__label { margin-top: var(--space-3); font-weight: 600; color: var(--ink-700); font-size: var(--text-sm); }
.catalog-card__kicker + .catalog-card__label { margin-top: var(--space-1); }
/* Der Erklärtext ist der eigentliche Inhalt dieser Karten (Maße, Aufbau).
   Linksbündig, weil zentrierte Fließtexte über zwei Zeilen hinaus zerfasern. */
.catalog-card__text {
  margin-top: var(--space-2);
  text-align: left;
  color: var(--ink-600);
  font-size: var(--text-sm);
  line-height: 1.55;
}
/* Für breite Motive (z. B. Gitter-Muster 3,2:1) – sonst schwebt ein
   schmaler Streifen in einer quadratischen Kachel. Zwei Spalten, damit
   jedes Muster groß genug erkennbar ist und keine Waise entsteht. */
.grid--catalog-wide { grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); }
@media (min-width: 1000px) { .grid--catalog-wide { grid-template-columns: repeat(2, 1fr); } }
.grid--catalog-wide .catalog-card {
  /* Studio-Freisteller stehen auf Weiß – sonst rahmt die graue Kachel das Bild */
  background: var(--white);
  padding: var(--space-5);
}
.grid--catalog-wide .catalog-card img {
  aspect-ratio: 16 / 5;
  object-fit: cover;
  border-radius: var(--radius-sm);
}


/* ── components/forms.css ─────────────────────────────────────────── */
/* ==========================================================================
   FORMS — Multistep-UI, Felder, Options-Karten, Progress, Upload
   ========================================================================== */

.form-card {
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: clamp(1.5rem, 1rem + 2.5vw, 3rem);
}

/* ── Progress ────────────────────────────────────────────────────────────── */
.form-progress { margin-bottom: var(--space-8); }
/* Desktop: nummerierte Steps mit Linie */
.form-steps { display: flex; align-items: center; gap: 0; }
.form-steps__item { display: flex; align-items: center; flex: 1 1 auto; min-width: 0; }
.form-steps__item:last-child { flex: 0 0 auto; }
.form-steps__dot {
  flex: none;
  width: 38px; height: 38px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600;
  border: 2px solid var(--ink-200);
  color: var(--ink-500);
  background: var(--white);
  transition: all var(--dur-fast);
}
.form-steps__dot svg { width: 18px; height: 18px; display: none; }
.form-steps__label {
  margin-left: 0.6rem;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink-500);
  white-space: nowrap;
  flex: 0 0 auto;
}
.form-steps__line {
  flex: 1 1 auto;
  min-width: 16px;
  height: 2px;
  background: var(--ink-200);
  margin: 0 0.75rem;
}
.form-steps__item.is-active .form-steps__dot { border-color: var(--green-500); color: var(--ink-800); box-shadow: 0 0 0 4px var(--green-100); }
.form-steps__item.is-active .form-steps__label { color: var(--ink-800); }
.form-steps__item.is-done .form-steps__dot { background: var(--green-500); border-color: var(--green-500); color: var(--white); }
.form-steps__item.is-done .form-steps__dot .num { display: none; }
.form-steps__item.is-done .form-steps__dot svg { display: block; }
.form-steps__item.is-done .form-steps__line { background: var(--green-500); }
@media (max-width: 720px) { .form-steps { display: none; } }

/* Mobile: Balken + Text */
.form-progress__mobile { display: none; }
@media (max-width: 720px) { .form-progress__mobile { display: block; } }
.form-progress__label { font-size: var(--text-sm); font-weight: 600; color: var(--ink-700); margin-bottom: var(--space-2); }
.form-progress__bar { height: 6px; background: var(--ink-100); border-radius: var(--radius-control); overflow: hidden; }
.form-progress__fill { height: 100%; background: var(--green-500); border-radius: var(--radius-control); transition: width var(--dur-med) var(--ease-out); }

/* ── Fieldset / Step ─────────────────────────────────────────────────────── */
.form-step { border: 0; padding: 0; margin: 0; }
.form-step[hidden] { display: none; }
.form-step__legend { padding: 0; margin-bottom: var(--space-2); }
.form-step__title {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-h3);
  line-height: 1.15;
  color: var(--ink-800);
}
/* Fokus wird per JS gesetzt (Screenreader-Ansage) – visuell dezent halten */
.form-step__title:focus { outline: none; }
.form-step__title:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 4px; }
.form-step__hint { color: var(--ink-500); margin-bottom: var(--space-6); }

/* ── Options-Karten (Radio/Checkbox als Karten) ──────────────────────────── */
.option-grid { display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.option-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); }
/* align-items: center liess die Titel innerhalb einer Rasterzeile auf
   verschiedenen Hoehen beginnen: die Karten sind gleich hoch (Raster),
   ihre Inhalte aber nicht — je nachdem, ob die Beschreibung eine, zwei oder
   drei Zeilen braucht. Gemessen bei 1440 px auf /online-anfrage/: Titelkanten
   784,2 / 801,7 / 793,0 = 17,5 px Spanne, waehrend Icons (804,7) und
   Auswahlkreise (777,8) exakt auf einer Linie standen; in Karte 1 stand der
   Titel dadurch ueber dem Icon, in Karte 2 daneben. Oben ausgerichtet
   beginnen alle Titel auf derselben Kante (nachgemessen 0 px Spanne). */
.option {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  /* rechts Platz für die Check-Markierung */
  padding: var(--space-4) 2.75rem var(--space-4) var(--space-5);
  border: 1.5px solid var(--ink-200);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast);
  background: var(--white);
}
.option:hover { border-color: var(--green-400); }
.option__input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
}
/* Das 34-px-Icon steht neben einer 20-px-Titelzeile (16 px / 1,25). Oben
   ausgerichtet haengt es 14 px unter der Zeile; die Haelfte davon wird nach
   oben ausgeglichen, dann liegt die Icon-Mitte auf der Mitte der Titelzeile. */
.option__icon { flex: none; width: 34px; height: 34px; margin-top: -0.4375rem; color: var(--green-600); display: inline-flex; align-items: center; justify-content: center; }
.option__icon .icon { width: 28px; height: 28px; }
.option__body { display: grid; gap: 0.15rem; min-width: 0; }
.option__label { display: block; font-weight: 600; color: var(--ink-800); line-height: 1.25; }
.option__desc { display: block; font-size: var(--text-xs); color: var(--ink-500); font-weight: 400; line-height: 1.35; }
.option__check {
  position: absolute;
  top: 0.6rem; right: 0.6rem;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid var(--ink-200);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--white);
  transition: all var(--dur-fast);
}
.option__check svg { width: 14px; height: 14px; opacity: 0; }
.option:has(.option__input:checked) { border-color: var(--green-500); border-width: 2px; background: var(--green-50); }
.option:has(.option__input:checked) .option__check { background: var(--green-500); border-color: var(--green-500); }
.option:has(.option__input:checked) .option__check svg { opacity: 1; }
.option:has(.option__input:focus-visible) { outline: 3px solid var(--color-focus); outline-offset: 2px; }

/* ── Textfelder ──────────────────────────────────────────────────────────── */
.field { display: grid; gap: 0.4rem; }
.field__label { font-weight: 500; font-size: var(--text-sm); color: var(--ink-700); }
.field__req { color: var(--error); }
.field__control {
  width: 100%;
  min-height: 52px;
  padding: 0.75rem 1rem;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--ink-800);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
textarea.field__control { min-height: 120px; resize: vertical; }
.field__control::placeholder { color: var(--ink-400); }
.field__control:focus { outline: none; border-color: var(--green-600); box-shadow: 0 0 0 3px var(--green-100); }
.field__control:user-invalid { border-color: var(--error); }
.field__error { color: var(--error); font-size: var(--text-sm); font-weight: 500; min-height: 0; }
.field__error:empty { display: none; }
.option-block { display: grid; gap: 0.5rem; }
.option-block .field__label { margin-bottom: 0.15rem; }
.option-grid.has-error .option { border-color: var(--error); }
.consent.has-error { color: var(--error); }
.consent.has-error input { outline: 2px solid var(--error); outline-offset: 2px; }
.field-grid { display: grid; gap: var(--space-4); grid-template-columns: 1fr 1fr; }
@media (max-width: 560px) { .field-grid { grid-template-columns: 1fr; } }
.field--full { grid-column: 1 / -1; }

/* ── Upload / Dropzone ───────────────────────────────────────────────────── */
.dropzone {
  border: 2px dashed var(--ink-200);
  border-radius: var(--radius-md);
  padding: var(--space-8);
  text-align: center;
  transition: border-color var(--dur-fast), background var(--dur-fast);
  cursor: pointer;
  display: grid;
  gap: var(--space-2);
  justify-items: center;
}
.dropzone.is-drag { border-color: var(--green-500); background: var(--green-50); }
.dropzone__icon { width: 44px; height: 44px; color: var(--green-600); }
.dropzone__title { font-weight: 600; color: var(--ink-800); }
.dropzone__hint { font-size: var(--text-sm); color: var(--ink-500); }
.dropzone input[type='file'] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.file-list { display: grid; gap: 0.5rem; margin-top: var(--space-4); }
.file-chip {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3);
  padding: 0.6rem 0.9rem;
  background: var(--ink-50);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}
.file-chip__name { display: flex; align-items: center; gap: 0.5rem; color: var(--ink-700); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-chip__remove { color: var(--ink-500); width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; }
.file-chip__remove:hover { background: var(--ink-200); color: var(--ink-800); }

/* ── Consent-Checkbox ────────────────────────────────────────────────────── */
.consent {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  font-size: var(--text-sm);
  color: var(--ink-600);
}
.consent input { margin-top: 3px; width: 20px; height: 20px; flex: none; accent-color: var(--green-600); }
.consent a { color: var(--green-600); text-decoration: underline; }

/* ── Navigation ──────────────────────────────────────────────────────────── */
/* Knoepfe rechts zusammen statt auseinandergezogen.
   Mit `space-between` klebte „Zurueck" am linken und „Weiter" am rechten Rand
   der Karte — auf breiten Karten liegen dann zwei zusammengehoerige Aktionen
   eine halbe Kartenbreite auseinander, und der Blick springt. Beide gehoeren
   an das Ende des Formulars, der Vorwaertsknopf zuletzt. */
.form-nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-8);
}
.form-nav__spacer { display: none; }
/* Auf schmalen Geraeten volle Breite: zwei halbe Knoepfe nebeneinander sind
   dort schwerer zu treffen als zwei volle untereinander. */
@media (max-width: 480px) {
  .form-nav { flex-direction: column-reverse; align-items: stretch; }
  .form-nav .btn { width: 100%; justify-content: center; }
}

/* Zusammenfassung (letzter Schritt) */
.summary-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: var(--space-6); }
.summary-chip {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.4rem 0.85rem;
  background: var(--green-50);
  color: var(--green-800);
  border-radius: var(--radius-control);
  font-size: var(--text-sm);
  font-weight: 500;
}

/* Restore-Banner */
.form-restore {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0.75rem 1rem;
  background: var(--green-50);
  border: 1px solid var(--green-200);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--green-800);
  margin-bottom: var(--space-6);
}
.form-restore.is-shown { display: flex; }
.form-restore button { color: var(--green-700); text-decoration: underline; font-weight: 600; }

/* ── No-JS-Fallback: ein langes, voll bedienbares Formular ──────────────
   Wichtig: [hidden] wird hier bewusst überschrieben, damit ohne JS ALLE
   Schritte sichtbar sind und der Submit-Button erreichbar bleibt. */
.no-js .form-step[hidden] { display: block !important; }
.no-js .form-step + .form-step {
  margin-top: var(--space-10);
  padding-top: var(--space-8);
  border-top: 1px solid var(--ink-100);
}
.no-js .form-progress { display: none; }
.no-js .form-nav__step { display: none !important; }
.no-js .form-nav__submit[hidden] { display: inline-flex !important; }
.no-js .form-restore { display: none !important; }

.form-success {
  text-align: center;
  padding: var(--space-10) 0;
}


/* ── components/misc.css ─────────────────────────────────────────── */
/* ==========================================================================
   MISC — Breadcrumbs, CTA-Bänder, FAQ, Steps, Swatches, Reviews, Galerie,
   Slider, Badges, JobCard
   ========================================================================== */

/* ── Breadcrumbs ─────────────────────────────────────────────────────────── */
.breadcrumbs {
  padding-block: var(--space-4);
  font-size: var(--text-sm);
}
/* Die Leiste steht zwischen zwei Polstern: unten am Hero und oben an der
   ersten Sektion. Zusammen mit ihren eigenen 2 x 16 px ergab das auf Desktop
   rund 250 px Leerraum am Stueck — gemessen auf den drei Formularseiten, wo
   dahinter direkt die Formularkarte kommt und der Bruch am staerksten auffiel.
   Die Sektion direkt hinter der Leiste beginnt deshalb frueher. Der Rhythmus
   zwischen den uebrigen Sektionen bleibt unveraendert. */
.breadcrumbs + section,
.breadcrumbs + .section {
  padding-top: var(--space-8);
}
.breadcrumbs__list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.breadcrumbs__sep { color: var(--ink-300); }
.breadcrumbs a { color: var(--ink-500); }
.breadcrumbs a:hover { color: var(--green-600); }
.breadcrumbs__current { color: var(--ink-800); font-weight: 500; }

/* ── CTA-Bänder ──────────────────────────────────────────────────────────── */
.cta-band {
  position: relative;
  /* Kein overflow:hidden — der Baum-Sticker ragt bewusst 34px ueber die
     Oberkante hinaus und wurde sonst oben abgeschnitten. Beschneiden ist
     hier entbehrlich: das Hintergrundbild liegt auf inset:0 und die gruene
     Oberkante ist ein Inset-Schatten, beide koennen nicht ueberlaufen. */
  isolation: isolate;
}
.cta-band--dark { background: var(--ink-800); color: var(--white); }
.cta-band--dark .cta-band__bg { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; opacity: 0.14; }
.cta-band--dark::after { content: ''; position: absolute; inset: 0; z-index: -1; background: var(--overlay-band); }
/* Oberkante als grüner Doppelstab — Grün auf Grün wäre unsichtbar, deshalb
   --green-300 auf --green-600. Rein dekorativ, aria-neutral. */
.cta-band--green {
  background: var(--green-600);
  color: var(--white);
  box-shadow: inset 0 2px 0 var(--green-300), inset 0 7px 0 -3px var(--green-300);
}
.cta-band__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  flex-wrap: wrap;
  padding-block: var(--section-pad-sm);
}
.cta-band__text { max-width: 40rem; }
.cta-band__title { color: var(--white); }
.cta-band--green .cta-band__title { color: var(--white); }
.cta-band__sub { margin-top: var(--space-3); font-size: var(--text-lead); color: rgba(255, 255, 255, 0.85); }
/* Auf --ink-800 erreicht Weiß mit 0,85 noch 10,48 : 1 — auf der grünen Fläche
   dagegen nur 4,07 : 1 (gemessen). Dort deshalb voll deckend: 5,58 : 1. */
.cta-band--green .cta-band__sub { color: var(--white); }
.cta-band__actions { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.cta-band__phone { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--green-300); font-weight: 600; }
.cta-band--green .cta-band__phone { color: var(--white); }
.cta-band__phone:hover { color: var(--white); }
.cta-band__phone svg { width: 18px; height: 18px; }
/* Baum-Sticker */
/* Das Siegel sitzt auf einem gruenen Band und ist selbst gruen. Mit nur 14 px
   Ueberstand ragte es kaum aus dem Band heraus und las sich dadurch nicht als
   aufgeklebtes Siegel, sondern als Darstellungsfehler — der Kollege hat es als
   z-index-Problem gemeldet. Es liegt korrekt oben (z-index 2, gemessen); es
   fehlte die Abgrenzung. Deutlicherer Ueberstand plus heller Ring loesen es. */
.cta-band__sticker {
  position: absolute;
  top: -34px; right: 6%;
  transform: rotate(-6deg);
  z-index: 2;
  box-shadow: 0 0 0 4px var(--white), 0 6px 18px rgba(20, 24, 30, 0.22);
}
.cta-band--green .cta-band__sticker { background: var(--ink-900); color: var(--white); }
@media (max-width: 720px) { .cta-band__sticker { display: none; } }

/* ── FAQ (details/summary) ───────────────────────────────────────────────── */
.faq { display: grid; }
/* Trenner als Doppelstab statt 1-px-Linie (Markenmotiv, §3.1 Einsatz 5).
   7 px hoch, deshalb 7 px zusätzliches Bodenpolster. */
.faq__item {
  --faq-rule: var(--ink-200);
  padding-bottom: 7px;
  background-image: linear-gradient(var(--faq-rule) 0 0), linear-gradient(var(--faq-rule) 0 0);
  background-size: 100% 2px;
  background-position: 0 calc(100% - 5px), 0 100%;
  background-repeat: no-repeat;
}
.faq__item summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) 0;
  cursor: pointer;
  font-weight: 600;
  font-size: var(--text-h4);
  color: var(--ink-800);
  list-style: none;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__icon {
  flex: none;
  width: 26px; height: 26px;
  position: relative;
  margin-top: 2px;
}
.faq__icon::before, .faq__icon::after {
  content: '';
  position: absolute;
  background: var(--green-600);
  transition: transform var(--dur-fast);
}
.faq__icon::before { top: 12px; left: 4px; width: 18px; height: 2px; }
.faq__icon::after  { top: 3px; left: 12px; width: 2px; height: 20px; }
.faq__item[open] .faq__icon::after { transform: rotate(90deg); opacity: 0; }
.faq__item[open] summary { color: var(--green-700); }
.faq__answer { padding: 0 0 var(--space-5); color: var(--ink-500); max-width: var(--measure); }
.faq__answer p + p { margin-top: var(--space-3); }
.faq__answer a { color: var(--green-600); text-decoration: underline; text-underline-offset: 2px; }
/* Auf --ink-50 erreicht --green-600 nur 4,45 : 1 (gemessen) — dort --green-700 */
.section--alt .faq__answer a,
.section--tint .faq__answer a { color: var(--green-700); }
.section--dark .faq__item { --faq-rule: rgba(255, 255, 255, 0.22); }
.section--dark .faq__item summary { color: var(--white); }
.section--dark .faq__answer { color: var(--ink-300); }

/* ── Steps (Projektablauf 1-2-3) ─────────────────────────────────────────── */
/* Ablaufschritte gibt es im Bestand nur als Dreier- (11x) und Fuenfersatz (1x).
   Vier Spalten machten daraus 4 + 1, zwei Spalten aus dem Dreiersatz 2 + 1 —
   gemessen 1 Waise bei 1440 px und 11 bei 900 px. Die Spalte ist deshalb nach
   unten auf ein Drittel der Zeile begrenzt (nie mehr als 3) und die Kachel
   darf schmaler werden (200 statt 260 px), damit drei Spalten bis 768 px
   tragen; darunter einspaltig statt zweispaltig. */
.steps {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, max(200px, (100% - 2 * var(--space-8)) / 3)), 1fr));
  counter-reset: step;
}
@media (max-width: 767px) { .steps { grid-template-columns: 1fr; } }
.step { position: relative; padding-top: var(--space-4); }
/* War var(--text-number) = bis 104px in Gruen mit opacity .9 — die riesige
   Deko-Ziffer ist ein klassisches Vorlagen-Element. Jetzt sachlich klein,
   mit Kante darunter statt Farbflaeche. */
.step__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ink-400);
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--green-500);
  display: inline-block;
  min-width: 2.4rem;
}
.step__title { margin-top: var(--space-3); font-family: var(--font-body); font-weight: 600; font-size: var(--text-h4); color: var(--ink-800); text-transform: none; }
.step__text { margin-top: var(--space-2); color: var(--ink-500); }
.section--dark .step__title { color: var(--white); }
.section--dark .step__text { color: var(--ink-300); }

/* ── Farb-Swatches (RAL) ─────────────────────────────────────────────────── */
.swatches { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.swatch { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; width: 92px; }
/* Kontur statt Andeutung: „Feuerverzinkt" (--ral-zink) erreicht auf --ink-50
   nur 1,74 : 1 und auf Weiß 1,94 : 1 — das Muster war ohne erkennbare Grenze
   (WCAG 1.4.11 verlangt 3 : 1 für bedeutungstragende Flächen). Die alte
   Innenkontur rgba(0,0,0,.08) brachte 1,1 : 1, die vorgeschlagenen .18 nur
   2,87 : 1. Nachgerechnet: --ink-400 liefert 3,71 : 1 auf Weiß, 3,33 : 1 auf
   --ink-50 und 3,75 : 1 auf --ink-800 — passt auf allen Untergründen.
   Aussenkontur, damit die Musterfläche selbst nicht kleiner wird. */
.swatch__chip {
  width: 72px; height: 72px;
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 1px var(--ink-400), var(--shadow-sm);
}
.swatch__label { font-size: var(--text-xs); color: var(--ink-600); text-align: center; font-weight: 500; }

/* ── Reviews (Bewertungen, consent-gated Elfsight) ───────────────────────── */
.reviews { display: grid; grid-template-columns: 0.8fr 1.4fr; gap: var(--space-10); align-items: center; }
@media (max-width: 820px) { .reviews { grid-template-columns: 1fr; } }
.reviews__score { text-align: left; }
.reviews__num { font-family: var(--font-display); font-weight: 600; font-size: var(--text-number); line-height: 1; color: var(--ink-800); }
.reviews__stars { display: inline-flex; gap: 2px; margin-block: var(--space-2); color: var(--amber-star); }
.reviews__stars svg { width: 22px; height: 22px; }
.reviews__meta { color: var(--ink-500); font-size: var(--text-sm); }
.reviews__meta a { color: var(--green-600); text-decoration: underline; }

.consent-box {
  border: 1px dashed var(--ink-200);
  border-radius: var(--radius-md);
  padding: var(--space-8);
  text-align: center;
  background: var(--white);
  display: grid;
  gap: var(--space-3);
  justify-items: center;
}
.consent-box__title { font-weight: 600; color: var(--ink-800); }
.consent-box__text { color: var(--ink-500); font-size: var(--text-sm); max-width: 40ch; }

/* ── Galerie + Lightbox ──────────────────────────────────────────────────── */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); gap: 8px; }
.gallery__item {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--ink-50);
  cursor: zoom-in;
}
.gallery__item img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-med) var(--ease-out); }
.gallery__item:hover img { transform: scale(1.05); }
.gallery__more { margin-top: var(--space-8); text-align: center; }
.gallery__hidden { display: none; }
.gallery__hidden.is-shown { display: block; }

.lightbox { border: none; padding: 0; max-width: 100vw; max-height: 100vh; width: 100%; height: 100%; background: transparent; }
.lightbox::backdrop { background: rgba(20, 24, 30, 0.94); }
.lightbox__inner { position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
.lightbox__img { max-width: 92vw; max-height: 84vh; object-fit: contain; border-radius: var(--radius-sm); }
.lightbox__caption {
  position: absolute;
  bottom: 4vh; left: 50%; transform: translateX(-50%);
  color: var(--ink-300);
  font-size: var(--text-sm);
  font-weight: 500;
  text-align: center;
}
.lightbox__btn {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: var(--white);
  display: inline-flex; align-items: center; justify-content: center;
  backdrop-filter: blur(4px);
}
.lightbox__btn:hover { background: rgba(255, 255, 255, 0.25); }
.lightbox__btn svg { width: 24px; height: 24px; }
.lightbox__prev { left: 2vw; }
.lightbox__next { right: 2vw; }
.lightbox__close { top: 2vh; right: 2vw; transform: none; }

/* ── Referenz-Slider (Scroll-Snap) ───────────────────────────────────────── */
.rslider { position: relative; }
.rslider__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(82vw, 380px);
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: var(--space-2);
}
.rslider__track::-webkit-scrollbar { display: none; }
.rslide {
  scroll-snap-align: start;
  aspect-ratio: 4 / 5;
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--ink-700);
}
.rslide img { width: 100%; height: 100%; object-fit: cover; }
.rslide__chip {
  position: absolute;
  left: var(--space-3); bottom: var(--space-3);
  background: rgba(20, 24, 30, 0.72);
  color: var(--white);
  font-size: var(--text-xs);
  font-weight: 500;
  padding: 0.35rem 0.7rem;
  border-radius: var(--radius-pill);
  backdrop-filter: blur(4px);
}
.rslider__controls { display: flex; align-items: center; gap: var(--space-4); margin-top: var(--space-6); }
.rslider__btn {
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1px solid var(--ink-600);
  color: var(--white);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
.rslider__btn:hover { background: var(--green-600); border-color: var(--green-600); }
.rslider__btn svg { width: 20px; height: 20px; }
.rslider__progress { flex: 1; height: 6px; position: relative; }
.rslider__progress::before {
  content: ''; position: absolute; inset: 0;
  background-image: linear-gradient(var(--ink-600) 0 0), linear-gradient(var(--ink-600) 0 0);
  background-size: 100% 2px; background-position: 0 1px, 0 4px; background-repeat: no-repeat;
}
.rslider__bar {
  position: absolute; top: 1px; left: 0; height: 3px; width: 25%;
  background: var(--green-500);
  transition: left var(--dur-fast) var(--ease-out);
}

/* ── Badges (SVG-Roundel) ────────────────────────────────────────────────── */
.badge-roundel {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 96px; height: 96px;
  border-radius: 50%;
  text-align: center;
  line-height: 1.05;
  flex: none;
}
.badge-roundel--green { background: var(--green-500); color: var(--ink-950); }
.badge-roundel--ink { background: var(--ink-800); color: var(--white); }
.badge-roundel__big { font-family: var(--font-display); font-weight: 600; font-size: 1.9rem; }
.badge-roundel__small { font-family: var(--font-body); font-weight: 600; text-transform: uppercase; font-size: 0.7rem; letter-spacing: 0.10em; }

/* ── JobCard ─────────────────────────────────────────────────────────────── */
.job-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-8);
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  height: 100%;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast);
  position: relative;
}
.job-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.job-card__tag { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; color: var(--green-600); }
.job-card__title { font-size: var(--text-h3); color: var(--ink-800); }
.job-card__meta { color: var(--ink-500); font-size: var(--text-sm); }
.job-card__foot { margin-top: auto; padding-top: var(--space-3); }

/* ── Video-Einbettung (Klick zum Abspielen) ─────────────────────────────── */
.video-embed {
  position: relative;
  max-width: 1000px;
  margin-inline: auto;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--ink-900);
  box-shadow: var(--shadow-lg);
}
.video-embed__poster,
.video-embed video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.video-embed__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 84px; height: 84px;
  border-radius: 50%;
  background: var(--green-500);
  color: var(--ink-950);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-md);
  transition: transform var(--dur-fast) var(--ease-out), background var(--dur-fast);
}
.video-embed__play .icon { width: 30px; height: 30px; margin-left: 4px; }
.video-embed__play:hover { transform: scale(1.07); background: var(--green-400); }
.video-embed.is-playing .video-embed__play,
.video-embed.is-playing .video-embed__poster { display: none; }
@media (max-width: 640px) { .video-embed__play { width: 64px; height: 64px; } }

/* ── Kontakt-Panel ───────────────────────────────────────────────────────── */
.contact-panel {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-12);
  align-items: center;
}
@media (max-width: 860px) { .contact-panel { grid-template-columns: 1fr; gap: var(--space-8); } }
.contact-list { display: grid; gap: var(--space-5); margin-top: var(--space-6); }
.contact-list li { display: flex; gap: var(--space-4); align-items: flex-start; }
.contact-list strong { color: var(--ink-800); font-weight: 600; }
.contact-list a { color: var(--green-600); }
.contact-list a:hover { color: var(--green-700); }
.contact-list__icon {
  flex: none;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--green-50);
  color: var(--green-600);
  display: inline-flex; align-items: center; justify-content: center;
}
.contact-list__icon .icon { width: 20px; height: 20px; }

/* ── Bild-Platzhalter (Asset-Download noch offen) ────────────────────────── */
.img-placeholder {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 120px;
  background:
    linear-gradient(135deg, var(--ink-100) 0%, var(--ink-50) 100%);
  position: relative;
  overflow: hidden;
}
.img-placeholder::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: linear-gradient(var(--ink-200) 0 0), linear-gradient(var(--ink-200) 0 0);
  background-size: 40px 2px;
  background-position: center 46%, center 54%;
  background-repeat: no-repeat;
  opacity: 0.6;
}

/* ── Anchor-Nav (Material-Guide Ankersektionen) ──────────────────────────── */
.anchor-nav {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  padding: var(--space-4) 0;
  position: sticky;
  top: var(--header-h);
  background: var(--color-bg);
  z-index: 20;
  border-bottom: 1px solid var(--ink-100);
}
.anchor-nav a {
  padding: 0.45rem 0.95rem;
  border-radius: var(--radius-control);
  background: var(--ink-50);
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 500;
}
.anchor-nav a:hover { background: var(--green-50); color: var(--green-700); }

/* Fallback, wenn das Bewertungs-Widget nicht lädt */
.reviews__fallback {
  display: grid;
  gap: var(--space-4);
  justify-items: start;
  padding: var(--space-6);
  border: 1px dashed var(--ink-200);
  border-radius: var(--radius-md);
  background: var(--white);
}
.reviews__fallback p { color: var(--ink-500); font-size: var(--text-sm); }

/* Galerie auf schmalen Screens zweispaltig – einspaltig wird die Seite
   sonst endlos lang (auf /referenzen/ über 30 Bildschirmhöhen). */
@media (max-width: 700px) {
  .gallery { grid-template-columns: repeat(2, 1fr); gap: 6px; }
}
@media (max-width: 380px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}

/* ==========================================================================
   STARTSEITEN-SEKTIONEN (Redesign) — worklog, finish, costguide, rail,
   warranty, area. Bewusst am Dateiende: .gallery--plates muss die globalen
   .gallery-Breakpoints weiter oben schlagen (gleiche Spezifität).
   ========================================================================== */

/* ── WERKBERICHT (type: "worklog") ───────────────────────────────────────── */
.worklog__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
.plate { position: relative; margin: 0; }
/* Die drei Detailaufnahmen im Werkbericht standen quadratisch (1:1 aus der
   Galerie-Regel) und waren je 450 px hoch – die Sektion kam damit auf 1438 px.
   Sie haengen in einem Lightbox-Button, deshalb muss das Verhaeltnis dort
   gesetzt werden, nicht am Bild. Fester 4:3-Ausschnitt: Motive bleiben lesbar,
   feste Proportion haelt den Layout-Shift bei 0. */
.plate:not(.plate--wide) .gallery__item,
.plate:not(.plate--wide) .gallery__item img {
  aspect-ratio: 4 / 3;
}
.plate--wide {
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--ink-50);
}
.plate--wide img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 16 / 9; }
.plate__tag {
  position: absolute; top: var(--space-4); left: var(--space-4); z-index: 2;
  background: rgba(20, 24, 30, 0.86);
  color: var(--white);
  padding: 6px 12px;
  border-radius: var(--radius-control);
}
.plate__tag--now { background: var(--green-500); color: var(--ink-950); }

.worklog__caption {
  margin-top: var(--space-4);
  max-width: 62ch;
  font-size: var(--text-sm);
  color: var(--ink-500);
  line-height: 1.55;
}

.worklog__facts {
  display: flex; align-items: stretch; flex-wrap: wrap;
  gap: var(--space-6) var(--space-8);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--ink-100);
}
.fact { min-width: 0; }
.fact__value {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
  line-height: 1.05; color: var(--ink-800);
  margin-top: 4px; letter-spacing: -0.008em;}
.worklog__facts .rule-doublebar--v { align-self: stretch; }

.worklog__plates { margin-top: var(--space-10); }
.gallery--plates { grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.gallery--plates .gallery__item { aspect-ratio: 1; border-radius: var(--radius-md); width: 100%; }
.plate__cap {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--ink-500);
  line-height: 1.5;
}

@media (max-width: 860px) {
  .worklog__pair { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  /* schlägt die globale .gallery-Regel (2 Spalten ab 700 px) bewusst */
  .gallery--plates { grid-template-columns: 1fr; gap: var(--space-6); }
  .gallery--plates .gallery__item { aspect-ratio: 16 / 10; }
  .worklog__facts .rule-doublebar--v { display: none; }
}

/* ── AUSFÜHRUNG (type: "finish") — Farbwechsel ohne eine Zeile JS ────────── */
/* Bildflaeche und Schalterzeile standen auf zwei verschiedenen Breiten
   (940 px und 1000 px): die Pillenreihe endete gemessen 60 px rechts neben der
   Bildkante. Beide haengen jetzt an derselben Groesse. */
.finish { display: grid; gap: var(--space-5); --finish-w: 940px; }

.finish__stage {
  position: relative;
  /* Quellmaße 1360x972 ergaben auf 1000px Breite 714px Hoehe – das Bild
     dominierte die Sektion. Ausschnitt statt Vollbild: die Proportion bleibt
     als Verhaeltnis erhalten (Layout-Shift = 0), object-fit schneidet oben und
     unten etwas ab. Das Tor bleibt vollstaendig im Bild. */
  aspect-ratio: 16 / 9;
  max-width: var(--finish-w);
  width: 100%;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--ink-100);    /* kein Weißblitz, falls ein Bild noch lädt */
  box-shadow: var(--shadow-md);
}
.finish__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0;
  transition: opacity 240ms var(--ease-out);
}

/* Musste an --finish-w haengen, stand aber weiter auf einem eigenen Wert: die
   Bildflaeche endete bei 1440 px gemessen auf x = 1059,9, die Schalterzeile auf
   1119,9 — 60 px daneben, genau der Versatz, den die Regel oben beseitigen
   sollte. Jetzt tatsaechlich dieselbe Kante (nachgemessen 1059,9 / 1059,9). */
.finish__bar {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--space-4);
  max-width: var(--finish-w);
}
.finish__state { font-size: var(--text-sm); color: var(--ink-500); }
.finish__state b { color: var(--ink-800); font-weight: 600; }
.finish__state-item { display: none; }

.finish__opts { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.finish__opt {
  display: inline-flex; align-items: center; gap: 0.6rem;
  min-height: 44px; padding: 0 var(--space-4);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-control);
  background: var(--white);
  color: var(--ink-700);
  font-size: var(--text-sm); font-weight: 600;
  cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast), color var(--dur-fast);
}
.finish__opt:hover { border-color: var(--ink-800); }
.finish__chip {
  width: 20px; height: 20px; border-radius: 50%;
  box-shadow: 0 0 0 1px var(--ink-400);   /* siehe .swatch__chip */
  flex: none;
}
.finish__chip--zink { background: var(--ral-zink); }
.finish__chip--6005 { background: var(--ral-6005); }
.finish__chip--7016 { background: var(--ral-7016); }

.finish__note { font-size: var(--text-xs); color: var(--ink-500); max-width: 62ch; }
/* Die Sektion steht auf --surface-tint; dort erreicht --green-600 nur
   4,57 : 1 (Risiko R12). --green-700 auf Tint: 6,17 : 1. */
.finish .link-arrow { color: var(--green-700); }
.finish .link-arrow:hover { color: var(--green-800); }

/* ── Zustandslogik: drei Zeilen je Option, kein JS ───────────────────── */
#finish-zink:checked ~ .finish__stage .finish__img--zink,
#finish-6005:checked ~ .finish__stage .finish__img--6005,
#finish-7016:checked ~ .finish__stage .finish__img--7016 { opacity: 1; }

#finish-zink:checked ~ .finish__bar .finish__state-item--zink,
#finish-6005:checked ~ .finish__bar .finish__state-item--6005,
#finish-7016:checked ~ .finish__bar .finish__state-item--7016 { display: inline; }

#finish-zink:checked ~ .finish__bar [for="finish-zink"],
#finish-6005:checked ~ .finish__bar [for="finish-6005"],
#finish-7016:checked ~ .finish__bar [for="finish-7016"] {
  background: var(--ink-800); color: var(--white); border-color: var(--ink-800);
}

.finish__radio:focus-visible ~ .finish__bar .finish__opt { outline: 1px dashed var(--ink-300); }
#finish-zink:focus-visible ~ .finish__bar [for="finish-zink"],
#finish-6005:focus-visible ~ .finish__bar [for="finish-6005"],
#finish-7016:focus-visible ~ .finish__bar [for="finish-7016"] {
  outline: 3px solid var(--color-focus); outline-offset: 3px;
}

@media (max-width: 620px) {
  .finish__opts { width: 100%; }
  .finish__opt { flex: 1 1 100%; justify-content: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
  .finish__img { transition-duration: 0.01ms; }   /* greift ohnehin global über motion.css */
}

/* ── KOSTENKOMPASS (type: "costguide") ───────────────────────────────────── */
.costguide { display: grid; gap: var(--space-10); }
@media (min-width: 1000px) {
  .costguide { grid-template-columns: minmax(0, 1fr) minmax(360px, 420px); gap: var(--space-16); align-items: start; }
}

/* Grid-Kinder duerfen von langen Komposita nicht gesprengt werden */
.costguide__body { min-width: 0; }

.factors { margin-top: var(--space-8); }
/* Die Begriffsspalte stand fest auf 150 px. "MONTAGEAUFWAND" brauchte in
   Versalien mit 0,10em Sperrung 236 px, "AUSFÜHRUNG" 162 px — beide brachen
   deshalb bei JEDER Desktopbreite mitten im Wort ("AUSFÜHRUN/G"). Zwei
   Aenderungen zusammen: die Versalien entfallen (der Begriff steht jetzt wie
   .wcase__term im Garantieblock, also im selben Muster), damit sinkt der
   Platzbedarf auf 167 px; und die Spalte waechst auf mindestens 180 px.
   hyphens:auto (die Seite ist lang="de") faengt kuenftige laengere Begriffe
   an der Silbengrenze ab, statt sie mittendrin zu zerschneiden. */
.factor {
  display: grid;
  grid-template-columns: minmax(180px, auto) minmax(0, 1fr);
  gap: var(--space-6);
  padding-block: var(--space-5);
  position: relative;
}
.factor::after {                       /* Doppelstab-Trenner statt 1px-Linie */
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 7px;
  background-image: linear-gradient(rgba(255,255,255,.22) 0 0), linear-gradient(rgba(255,255,255,.22) 0 0);
  background-size: 100% 2px;
  background-position: 0 0, 0 5px;
  background-repeat: no-repeat;
}
.factor:last-child::after { content: none; }
.factor__term {
  font-family: var(--font-body); font-weight: 600;
  font-size: 1.25rem; line-height: 1.15;
  color: var(--white);
  hyphens: auto;
}
.factor__text { color: var(--ink-200); font-size: var(--text-sm); line-height: 1.6; }
@media (max-width: 700px) { .factor { grid-template-columns: 1fr; gap: var(--space-2); } }

.primer {
  margin-top: var(--space-10);
  padding: var(--space-6);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.04);
}
.primer__title {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-h3); color: var(--white);
}
.primer__list { margin-top: var(--space-5); display: grid; gap: var(--space-5); }
.primer__row { display: grid; grid-template-columns: 5rem minmax(0, 1fr); gap: var(--space-5); align-items: start; }
.primer__code {
  font-family: var(--font-display); font-weight: 600; font-size: 1.75rem;
  line-height: 1; color: var(--green-400); font-variant-numeric: tabular-nums;
}
.primer__text { color: var(--ink-200); font-size: var(--text-sm); line-height: 1.6; }
.primer .link-arrow { margin-top: var(--space-5); }
@media (max-width: 480px) { .primer__row { grid-template-columns: 1fr; gap: var(--space-1); } }

/* ── Mini-Konfigurator (weiße Karte auf dunkler Fläche) ─────────────── */
.costform {
  /* Weiße Karte in einer .section--dark: dort steht --color-focus auf
     --green-300 (1,9 : 1 auf Weiß — der Fokusring wäre unsichtbar).
     Auf der hellen Kartenfläche gilt wieder der helle Fokuswert (4,95 : 1). */
  --color-focus: var(--green-600);
  /* Ebenso erbt die Karte sonst --color-text der dunklen Sektion (--ink-300,
     auf Weiß nur 2,4 : 1). Gemessen an <legend class="label">. */
  color: var(--ink-700);
  background: var(--white);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: grid; gap: var(--space-5);
  box-shadow: var(--shadow-lg);
  position: sticky; top: calc(var(--header-h) + var(--space-6));
}
@media (max-width: 999px) { .costform { position: static; } }
.costform__title {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-h4); color: var(--ink-800);
}
.costform__set { border: 0; padding: 0; margin: 0; min-width: 0; }
.costform__set legend { padding: 0; margin-bottom: var(--space-3); }
/* base.css setzt `.section--dark .label { color: var(--ink-300) }` (§3.3).
   Diese Karte ist aber weiß — dort gilt wieder der helle Wert (5,68 : 1).
   misc.css wird nach base.css gebündelt, gleiche Spezifität, gewinnt. */
.costform .label { color: var(--ink-500); }
/* Raster statt Fliesstext-Umbruch.
   Mit `flex-wrap` richtete sich jede Zeile nach der Breite ihrer Beschriftungen:
   „bis 10 m" und „10 – 20 m" ergaben zwei ungleich breite Felder nebeneinander,
   „ueber 100 m" blieb als einzelnes Feld in der letzten Zeile stehen. Das las
   sich als unaufgeraeumt. Ein Raster mit gleich breiten Spalten stellt alle
   Felder buendig untereinander — die Zeilenzahl aendert sich dadurch nicht. */
.costform__opts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: var(--space-2);
}
.opt { position: relative; display: flex; }
.opt span { flex: 1; justify-content: center; }
.opt input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; margin: 0; cursor: pointer;
}
.opt span {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 var(--space-4);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-control);
  background: var(--ink-50);
  color: var(--ink-700);
  font-size: var(--text-sm); font-weight: 600;
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.opt:hover span { border-color: var(--ink-800); }
.opt input:checked + span {
  background: var(--green-500);
  color: var(--ink-950);          /* Kontrastregel des Projekts: 6,01 : 1 */
  border-color: var(--green-500);
}
.opt input:focus-visible + span { outline: 3px solid var(--color-focus); outline-offset: 2px; }

.costform__echo {
  border-left: 3px solid var(--green-500);
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
  background: var(--surface-tint);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  /* Die Hinweiszeilen sind unterschiedlich lang — feste Mindesthöhe, damit
     beim Umschalten nichts springt (Risiko R8). Gemessen (längste Zeile
     "Sichtschutz heißt bei uns …", min-height testweise auf 0):
     Karte 420 px -> 89 px | 368 px -> 111 px | 300 px -> 132 px. */
  min-height: 5.75rem;   /* 92 px */
}
.costform__hint { display: none; font-size: var(--text-sm); color: var(--ink-700); line-height: 1.55; }
.costform__hint--default { display: block; }

.costform:has(#cf-sichtschutz:checked)     .costform__hint--sichtschutz,
.costform:has(#cf-laermschutz:checked)     .costform__hint--laermschutz,
.costform:has(#cf-sicherheit:checked)      .costform__hint--sicherheit,
.costform:has(#cf-tierfreundlich:checked)  .costform__hint--tierfreundlich,
.costform:has(#cf-aesthetik:checked)       .costform__hint--aesthetik { display: block; }

.costform:has(#cf-sichtschutz:checked)     .costform__hint--default,
.costform:has(#cf-laermschutz:checked)     .costform__hint--default,
.costform:has(#cf-sicherheit:checked)      .costform__hint--default,
.costform:has(#cf-tierfreundlich:checked)  .costform__hint--default,
.costform:has(#cf-aesthetik:checked)       .costform__hint--default { display: none; }

.costform__note { font-size: var(--text-xs); color: var(--ink-500); line-height: 1.5; }
/* Ab hier wird die Karte schmaler als 380 px bzw. 310 px — die längste
   Hinweiszeile bricht auf fünf bzw. sechs Zeilen um. */
@media (max-width: 419px) { .costform__echo { min-height: 7.25rem; } }  /* 116 px */
@media (max-width: 349px) { .costform__echo { min-height: 8.5rem; } }   /* 136 px */

/* ── ABLAUF (type: "rail") ───────────────────────────────────────────────── */
.rail {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-8);
  position: relative;
}
.rail__step { position: relative; padding-top: 78px; }
/* Schiene: Doppelstab-Motiv, waagerecht durch alle Marker */
.rail__step::before {
  content: '';
  position: absolute;
  top: 27px; left: 60px; right: calc(-1 * var(--space-8));
  height: 7px;
  background-image: linear-gradient(var(--ink-200) 0 0), linear-gradient(var(--ink-200) 0 0);
  background-size: 100% 2px;
  background-position: 0 0, 0 5px;
  background-repeat: no-repeat;
}
.rail__step:last-child::before { content: none; }
.rail__marker {
  position: absolute; top: 0; left: 0;
  width: 56px; height: 56px;
  border-radius: 50%;
  border: 2px solid var(--ink-200);
  background: var(--white);
  display: inline-flex; align-items: center; justify-content: center;
}
.rail__num {
  font-family: var(--font-display); font-weight: 600; font-size: 1.375rem;
  line-height: 1; color: var(--ink-800); font-variant-numeric: tabular-nums;
}
.rail__title {
  font-family: var(--font-body); font-weight: 600; text-transform: none;
  font-size: var(--text-h4); color: var(--ink-800);
}
.rail__text { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--ink-500); line-height: 1.6; }
.rail__chip {
  display: inline-block; margin-top: var(--space-4);
  background: var(--green-50);
  color: var(--green-700);          /* 6,17 : 1 */
  font-size: var(--text-xs); font-weight: 600;
  padding: 5px 12px; border-radius: var(--radius-pill);
}

.rail__after {
  margin-top: var(--space-12);
  padding: var(--space-5) var(--space-6);
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md);
  color: var(--ink-700);
  font-size: var(--text-sm); line-height: 1.6;
}
.rail__after .link-arrow { margin-left: 0.5rem; white-space: nowrap; }

@media (max-width: 900px) {
  .rail { grid-template-columns: 1fr; gap: var(--space-8); }
  .rail__step { padding-top: 0; padding-left: 80px; min-height: 56px; }
  /* Schiene kippt auf senkrecht */
  .rail__step::before {
    top: 60px; bottom: calc(-1 * var(--space-8)); left: 27px; right: auto;
    width: 7px; height: auto;
    background-size: 2px 100%;
    background-position: 0 0, 5px 0;
  }
}
@media (max-width: 380px) {
  .rail__step { padding-left: 68px; }
  .rail__marker { width: 46px; height: 46px; }
  .rail__step::before { top: 50px; left: 22px; }
}

/* ── GARANTIE (type: "warranty") ─────────────────────────────────────────── */
.warranty { display: grid; gap: var(--space-10); }
@media (min-width: 900px) {
  .warranty { grid-template-columns: minmax(280px, 380px) minmax(0, 1fr); gap: var(--space-16); align-items: start; }
}

.wdoc {
  background: var(--surface-tint);
  border-left: 6px solid var(--green-500);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  padding: var(--space-8);
}
.wdoc__big {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(5rem, 3.2rem + 6vw, 8rem);
  line-height: 0.82; color: var(--ink-800);
  font-variant-numeric: tabular-nums;
}
.wdoc__unit {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.5rem; letter-spacing: -0.008em; color: var(--ink-800);
  margin-top: var(--space-2);
}
.wdoc__note { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--ink-500); line-height: 1.5; }
.wdoc__rule { display: block; width: 100%; margin-block: var(--space-6); }
.wdoc__small {
  font-family: var(--font-display); font-weight: 600;
  font-size: 2.25rem; line-height: 1; color: var(--ink-800); letter-spacing: -0.008em;
}

.wcases { display: grid; }
.wcase {
  display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: var(--space-6);
  padding-block: var(--space-5);
  border-top: 1px solid var(--ink-100);
}
.wcase:first-child { border-top: 0; padding-top: 0; }
.wcase__term { font-weight: 600; color: var(--ink-800); }
.wcase__text { color: var(--ink-500); line-height: 1.6; }
.wcase__text a { color: var(--green-600); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 700px) { .wcase { grid-template-columns: 1fr; gap: var(--space-2); } }

.wtree {
  margin-top: var(--space-12);
  display: flex; align-items: center; gap: var(--space-6);
  flex-wrap: wrap;
  background: var(--green-50);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}
.wtree__text { color: var(--ink-700); font-size: var(--text-lead); max-width: 46ch; }

/* ── EINZUGSGEBIET (type: "area") ────────────────────────────────────────── */
.area { display: grid; gap: var(--space-10); }
@media (min-width: 900px) {
  /* Vorher: schmale Textspalte links, Ortsliste rechts. Nach dem Entfernen der
     grossen Ortszahl war die linke Spalte 386 px hoeher als die rechte – ein
     sichtbares Loch. Jetzt teilt sich die linke Spalte intern auf: Foto und
     Adresse stehen nebeneinander statt uebereinander. */
  .area { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--space-12); align-items: start; }
  .area__side {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-6) var(--space-8);
    align-content: start;
  }
  .area__side > .eyebrow,
  .area__side > .section-head__title,
  .area__side > .section-head__lead { grid-column: 1 / -1; }
  .area__side > .area__photo { grid-column: 1; margin-top: 0; align-self: start; }
  .area__side > .area__nap { grid-column: 2; margin-top: 0; }
}
.area__side,
.area__places { min-width: 0; }
.area__photo { margin-top: var(--space-6); width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.area__nap { margin-top: var(--space-5); display: grid; gap: var(--space-3); }
.area__nap li { color: var(--ink-700); }
.area__nap .label { display: block; margin-bottom: 2px; }
/* Sektion steht auf --surface-tint: --green-600 wäre nur 4,57 : 1 (R12) */
.area__nap a { color: var(--green-700); font-weight: 600; }
.area__nap a:hover { color: var(--green-800); }

.places {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px var(--space-6);
}
.place { position: relative; padding-left: 1.15rem; color: var(--ink-700); }
.place::before {
  content: ''; position: absolute; left: 0; top: 0.6em;
  width: 8px; height: 8px; background: var(--green-500);
}
.place a { color: var(--green-700); text-decoration: underline; text-underline-offset: 2px; }
.place--seat { font-weight: 600; color: var(--ink-800); }
.place__tag { color: var(--green-700); margin-left: 0.4rem; }
.area__foot { margin-top: var(--space-8); font-size: var(--text-sm); color: var(--ink-500); }
@media (max-width: 380px) {
  /* 324 px: 150px-Spalten würden zweispaltig überlaufen */
  .places { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px var(--space-4); }
}

/* WCAG 2.2 Zielgroesse: die verlinkten Orte im Einzugsgebiet stehen als
   eigenstaendige Listeneinträge, nicht im Fliesstext — die Inline-Ausnahme
   greift dort nicht. Padding statt groesserer Schrift, damit das Raster
   der Ortsliste unveraendert bleibt. */
.place a { display: inline-block; padding-block: 0.2rem; }
/* Der Pfeil-Link braucht dasselbe Polster, aber NICHT `inline-block`: das
   ueberschrieb das `inline-flex` aus buttons.css, und weil base.css jedes
   <svg> auf `display: block` setzt, rutschte der Pfeil damit unter den Text
   statt daneben zu stehen. `inline-flex` nimmt Polster genauso an. */
.rail__after .link-arrow {
  display: inline-flex;
  padding-block: 0.2rem;
}

/* Der Ausfuehrungs-Schalter arbeitet ohne JavaScript ueber `:checked ~ …`.
   Dafuer muessen die drei Radios VOR der Bildflaeche im DOM stehen – sie lagen
   damit ganz oben in der Sektion, rund 630 px ueber dem Sichtfeld. Beim Klick
   auf eine Pille wanderte der Fokus dorthin und der Browser sprang 144 px nach
   oben (gemessen). `position: fixed` haelt sie immer im Sichtfeld, ohne die
   Geschwister-Selektoren zu beruehren – die richten sich nach der DOM-Ordnung,
   nicht nach der Positionierung. Kein JavaScript noetig.
   Gemessen nach der Aenderung: 0 px Sprung. */
.finish__radio.u-visually-hidden {
  position: fixed !important;
  top: 50%;
  left: 0;
}


/* ── components/scroll3d.css ─────────────────────────────────────────── */
/* ==========================================================================
   SCROLL-3D-MONTAGE — uebernommen aus dem Integrationspaket scroll3d-montage/.
   Alle Klassen tragen den Praefix .s3d, damit es keine Kollision mit dem
   restlichen Designsystem gibt. Ergaenzt um den Rueckfall .s3d-fallback.
   ========================================================================== */
.s3d { position: relative; background: #171a12; }
  .s3d__pin { position: sticky; top: 0; height: 100svh; overflow: hidden; }
  .s3d__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
  .s3d__veil {
    position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(180deg,
      rgba(8,10,6,calc(.26 + var(--hero,0) * .34)) 0%,
      rgba(8,10,6,.10) 34%, rgba(8,10,6,0) 58%, rgba(8,10,6,.30) 100%);
  }

  /* Hero-Text: nur am Anfang sichtbar */
  .s3d__hero {
    position: absolute; inset: auto 0 0 0; z-index: 3; color: var(--white);
    padding: 0 clamp(1rem,5vw,3.4rem) clamp(3rem,10vh,6.5rem);
    opacity: var(--hero, 1);
    transform: translateY(calc((1 - var(--hero,1)) * -26px));
  }
  .s3d__hero h1 {
    margin: 0; font-weight: 800; line-height: 1.04; letter-spacing: -.025em;
    font-size: clamp(2.4rem, 7vw, 5.6rem); text-wrap: balance;
    text-shadow: 0 2px 34px rgba(0,0,0,.45);
  }
  .s3d__eyebrow {
    margin: 0 0 .6rem; font-size: .72rem; font-weight: 700;
    letter-spacing: .2em; text-transform: uppercase; color: #a9dd7c;
  }
  .s3d__intro { margin: 1rem 0 0; max-width: 38ch; line-height: 1.6;
    font-size: clamp(1rem,1.6vw,1.25rem); color: #eef1e8; }
  .s3d__cue {
    position: absolute; left: 50%; bottom: 1.4rem; translate: -50% 0; z-index: 3;
    color: var(--white); font-size: .68rem; letter-spacing: .22em; text-transform: uppercase;
    text-align: center; opacity: var(--hero, 1);
  }
  .s3d__cue span { display: block; margin: .5rem auto 0; width: 1px; height: 26px;
    background: linear-gradient(180deg,var(--white),transparent); }

  /* Marker am Bauteil */
  .s3d__markers { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
  /* absolute, nicht fixed.
     Mit `position: fixed` haengen die Erklaerkaesten am Fenster statt an der
     Sektion: Sie verschwinden dann nur, wenn die JavaScript-Schleife sie
     wegnimmt. iOS Safari haelt genau diese Schleife waehrend einer
     Wischbewegung an — beim schnellen Hochscrollen blieb der Kasten deshalb
     ueber dem folgenden Inhalt stehen (auf dem Desktop nicht reproduzierbar,
     dort laeuft die Schleife durch). Absolut im gepinnten Bereich greift
     dessen `overflow: hidden`, und die Kaesten gehen ohne jedes Skript mit
     der Sektion aus dem Bild. */
  .s3d-mk {
    position: absolute; left: 0; top: 0; opacity: 0;
    transform: translate(-50%,-50%) scale(.94);
    transition: opacity .34s ease, transform .34s ease;
  }
  .s3d-mk.is-on { opacity: 1; transform: translate(-50%,-50%) scale(1); }
  .s3d-mk__dot {
    position: absolute; left: 0; top: 0; translate: -50% -50%;
    width: 13px; height: 13px; border-radius: 50%; background: var(--green-500);
    box-shadow: 0 0 0 4px rgba(var(--green-500-rgb),.28), 0 2px 10px rgba(0,0,0,.55);
  }
  /* Die Zentrierung steckt in `translate`, die Animation nur in `scale`.
     Vorher stand -50%/-50% in BEIDEN Eigenschaften – `translate` und
     `transform` sind eigenstaendige Eigenschaften und werden nacheinander
     angewandt, der Ring lag also um 100 % statt 50 % versetzt und sass
     sichtbar links oberhalb des Punktes. */
  .s3d-mk__dot::after {
    content: ""; position: absolute; left: 50%; top: 50%; translate: -50% -50%;
    width: 13px; height: 13px; border-radius: 50%; border: 1px solid var(--green-500);
    animation: s3dPulse 2.4s ease-out infinite;
  }
  @keyframes s3dPulse {
    0%   { scale: 1;   opacity: .9 }
    100% { scale: 3.6; opacity: 0 }
  }
  .s3d-mk__line {
    position: absolute; left: 0; top: 0; width: 62px; height: 1px;
    background: linear-gradient(90deg,var(--green-500),rgba(255,255,255,.5));
    transform-origin: left center; transform: rotate(-34deg);
  }
  .s3d-mk__box {
    position: absolute; left: 56px; top: -78px; width: min(300px, 56vw);
    background: rgba(12,15,9,.74); backdrop-filter: blur(9px);
    border: 1px solid rgba(255,255,255,.16); border-radius: var(--radius-md);
    padding: .8rem 1rem; color: var(--white);
  }
  .s3d-mk.is-left .s3d-mk__line { transform: rotate(214deg); }
  .s3d-mk.is-left .s3d-mk__box  { left: auto; right: 56px; }
  .s3d-mk__box b {
    display: block; font-size: .64rem; letter-spacing: .18em;
    text-transform: uppercase; color: #a9dd7c; margin-bottom: .3rem;
  }
  .s3d-mk__box h3 { margin: 0; font-size: clamp(1rem,1.4vw,1.2rem); line-height: 1.2; }
  .s3d-mk__box p  { margin: .35rem 0 0; font-size: .84rem; line-height: 1.5; color: #dbe2cd; }

  /* Vertikaler Fortschritt rechts */
  .s3d__vp {
    position: absolute; right: clamp(.9rem,2.6vw,2.2rem); top: 50%; translate: 0 -50%;
    z-index: 5; display: flex; gap: .75rem; align-items: stretch;
    opacity: calc(1 - var(--hero,0) * .9);
  }
  .s3d__vplabels {
    display: flex; flex-direction: column; justify-content: space-between; text-align: right;
    font-size: .61rem; letter-spacing: .14em; text-transform: uppercase; color: rgba(255,255,255,.6);
  }
  .s3d__vplabels span {
    opacity: .85; transition: all .3s ease; white-space: nowrap;
    background: rgba(12,15,9,.55); backdrop-filter: blur(6px);
    padding: .28rem .5rem; border-radius: var(--radius-sm); border: 1px solid rgba(255,255,255,.08);
  }
  .s3d__vplabels span.is-on {
    color: var(--white); opacity: 1; font-weight: 700;
    background: rgba(var(--green-500-rgb),.9); border-color: rgba(255,255,255,.3);
  }
  .s3d__vptrack {
    position: relative; width: 2px; border-radius: var(--radius-pill);
    background: rgba(255,255,255,.28); height: min(330px,46vh);
  }
  .s3d__vptrack i {
    position: absolute; left: 0; top: 0; width: 100%; border-radius: var(--radius-pill);
    height: calc(var(--p,0) * 100%); background: var(--green-500);
  }
  .s3d__vptrack u {
    position: absolute; left: 50%; translate: -50% -50%; top: calc(var(--p,0) * 100%);
    width: 9px; height: 9px; border-radius: 50%; background: var(--white);
    box-shadow: 0 0 0 3px rgba(var(--green-500-rgb),.55);
  }
  /* 56vw ergab bei 324 px nur 181 px Kastenbreite — die drei Textzeilen
     wuchsen damit auf 270 px Hoehe und fuellten fast die halbe gepinnte
     Flaeche. Mit 100vw minus 5,5rem sind es 236 px bei 324 px und 302 px ab
     390 px, die Hoehe faellt auf 200 px bzw. 165 px (nachgemessen). Die
     Randkorrektur in scroll3d.js schiebt den Kasten anschliessend ins Bild;
     sie braucht Luft von 2 x 12 px, die bleibt hier erhalten. */
  /* Auf schmalen Geraeten liegt der Kasten in einem Band am unteren Rand,
     nicht neben dem Markierungspunkt. Gemessen sass er sonst mit seiner Mitte
     bei y ≈ 390–480 von 844 px, also mitten im Bild, und verdeckte die Szene,
     die er erklaeren soll. Ausserdem reichte er bei hoch liegenden Ankern unter
     den festen Seitenkopf (Unterkante y = 61). Die Lage setzt scroll3d/index.js;
     hier steht nur die Breite, damit das Band die volle Zeile nutzt.
     Die Verbindungslinie entfaellt: sie zeigte quer ueber den halben Bildschirm. */
  @media (max-width: 700px) {
    .s3d-mk__box { width: calc(100vw - 1.5rem); }
    .s3d-mk__line { display: none; }
  }
  @media (max-width: 640px) {
    .s3d__vplabels { display: none; }
    .s3d__vptrack  { height: 32vh; }
  }
  @media (prefers-reduced-motion: reduce) {
    .s3d-mk { transition: none; }
    .s3d-mk__dot::after { animation: none; }
  }

/* ── Rueckfall und Zustandsschaltung ─────────────────────────────────────
   Standardzustand ist bewusst die statische Liste: ohne JavaScript, ohne
   WebGL oder bei "Bewegung reduzieren" bleibt der Ablauf lesbar. Erst wenn
   die Szene laeuft, setzt das Skript data-s3d-state="live". Ohne diese
   Umkehrung stand im Original eine leere Flaeche in Scrollhoehe. */
.s3d {
  height: auto;
  /* Gepinnte Scrollstrecke — die einzige Stellschraube fuer das Tempo.
     Die reine Scrollstrecke ist (Wert − 100vh); je Phase ein Fuenftel davon.
       180vh -> 80vh Strecke, 16vh je Phase (zu hastig, Rueckmeldung Kunde)
       300vh -> 200vh Strecke, 40vh je Phase  <- aktuell
     Die Phasengrenzen in den Szenen liegen im Fortschrittsraum 0…1 und sind
     von der Hoehe unabhaengig: eine Aenderung hier verschiebt keine Phase,
     sie dehnt nur den Weg dorthin. Gilt fuer beide Szenen (Montage und
     Drahtaufbau), weil beide dieselbe Sektion nutzen. */
  --s3d-height: 300vh;
}
.s3d__pin { display: none; }
.s3d[data-s3d-state='live'] { height: var(--s3d-height); }
.s3d[data-s3d-state='live'] .s3d__pin { display: block; }
/* Mit laufender Szene verschwindet die Ablaufliste nur OPTISCH. display:none
   hat sie auch aus dem Barrierefreiheitsbaum genommen; fuer Screenreader
   blieben von der Sektion 110 statt 877 Zeichen uebrig. Deklarationen
   identisch mit .u-visually-hidden (base.css) — hier zustandsabhaengig,
   deshalb als Regel und nicht als Klasse am Element. */
.s3d[data-s3d-state='live'] .s3d-fallback {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.s3d-fallback {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-6);
}
.s3d-fallback__item {
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: var(--space-4);
  align-items: start;
}
.s3d-fallback__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--green-400);
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--green-500);
}
.s3d-fallback__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-h4);
  color: var(--white);
}
.s3d-fallback__text {
  margin-top: var(--space-2);
  color: var(--ink-300);
  font-size: var(--text-sm);
  line-height: 1.6;
  max-width: 54ch;
}
@media (min-width: 800px) {
  .s3d-fallback { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-8) var(--space-10); }
}


/* ── motion.css ─────────────────────────────────────────── */
/* ==========================================================================
   MOTION — Scroll-Reveals + Reduced-Motion-Fallback + Consent-Banner
   ========================================================================== */

/* Reveal: Default sichtbar; JS setzt .reveal nur bei erlaubter Motion */
.reveal {
  opacity: 0;
  transform: translateY(24px);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

/* Consent-Banner */
.cookie-banner {
  position: fixed;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%) translateY(0);
  z-index: 300;
  width: min(680px, calc(100% - 2rem));
  background: var(--white);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
  display: none;
}
.cookie-banner.is-shown { display: block; }
.cookie-banner__title { font-family: var(--font-body); font-weight: 600; font-size: var(--text-h4); color: var(--ink-800); margin-bottom: var(--space-2); text-transform: none; }
.cookie-banner__text { color: var(--ink-500); font-size: var(--text-sm); }
.cookie-banner__text a { color: var(--green-600); text-decoration: underline; }
.cookie-banner__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-5); }
@media (max-width: 980px) { .cookie-banner { bottom: 84px; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  .scroll-cue { display: none; }
}
