/* ===== 01-tokens.css ===== */
/* ==========================================================================
   01-TOKENS — Design-Tokens
   --------------------------------------------------------------------------
   Einzige Quelle für Farbe, Typo, Abstände, Bewegung.
   Kundenspezifische Werte NICHT hier ändern, sondern in brand.css überschreiben.

   Gestaltungsprinzip: kantig, technisch, handwerklich.
   Keine Radien, keine weichen Schatten, keine Pastell-Gradienten.
   ========================================================================== */

:root {
  /* --- Farbe: Basis -------------------------------------------------------
     Warmes Schwarz statt #000, warmes Weiß statt #FFF.
     Reines Schwarz/Weiß wirkt billig und flach am Bildschirm. */
  --c-ink:        #14110F;   /* Text, Rahmen, Flächen */
  --c-ink-soft:   #3A3431;   /* Sekundärtext */
  --c-ink-mute:   #6E6862;   /* Meta, Labels */
  --c-paper:      #F6F2EB;   /* Seitenhintergrund */
  --c-paper-warm: #EDE7DC;   /* abgesetzte Sektion */
  --c-line:       #14110F;   /* Rahmenfarbe = Tinte, volle Härte */
  --c-line-soft:  #CFC7B9;   /* dezente Trennlinie */

  /* --- Farbe: Marke (pro Kunde überschreiben) --- */
  --c-accent:      #C63A17;  /* Primärakzent — Zinnober */
  --c-accent-ink:  #FFFFFF;  /* Text auf Akzentfläche */
  --c-accent-deep: #93290F;  /* Hover/Tiefe */
  --c-accent-2:    #1B4D8F;  /* Sekundärakzent — Kobalt */

  /* --- Farbe: Funktional --- */
  --c-focus:   #1B4D8F;
  --c-error:   #A61B1B;
  --c-success: #1E6B3A;

  /* --- Typografie ---------------------------------------------------------
     Font-Stacks lokal/system. Webfonts erst final einbauen (siehe fonts/README).
     --f-display: eng, kräftig, für Headlines in Großbuchstaben.
     --f-text:    ruhig, gut lesbar, für Fließtext.
     --f-label:   für Labels, Navigation, Schaltflächen. */
  --f-display: "Kunde Display", "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --f-text:    "Kunde Text", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* --f-label: für Kleinschrift wie Navigation, Schaltflächen, Bildlegenden.
     BEWUSST dieselbe Familie wie der Fließtext.

     Frühere Fassungen setzten hier eine Monospace-Schrift ein, um einen
     "technischen" Ton zu erzeugen. Das war ein Fehler: Systemseitige
     Monospace-Schriften sehen auf jedem Betriebssystem anders aus, wirken
     billig und sind sofort als Vorlagenmerkmal erkennbar. Eine gut
     gesetzte Grotesk in Versalien mit weitem Tracking erreicht dieselbe
     Klarheit und sieht nach Gestaltung aus statt nach Terminalfenster. */
  --f-label:   var(--f-text);

  /* Nur für echte Codedarstellung. In Komponenten nicht verwenden. */
  --f-mono:    ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Typo-Skala: fluid, aber mit klaren Sprüngen.
     Große Sprünge = klare Hierarchie = wirkt gestaltet, nicht generiert. */
  /* Hero-Headline. Bewusst nicht größer: Ab etwa 7.5rem braucht eine
     vierzeilige Headline mehr Höhe, als der Hero hat — dann schiebt sie
     Fließtext, Schaltflächen und Faktenzeile aus dem Bild. Wer eine
     größere Wirkung will, kürzt den Text, statt den Grad zu erhöhen. */
  --t-mega:  clamp(2.75rem, 7.5vw, 7.5rem);
  --t-h1:    clamp(2.5rem,  6.5vw,  5.25rem);
  --t-h2:    clamp(1.9rem,  4.2vw,  3.5rem);
  --t-h3:    clamp(1.35rem, 2.4vw,  1.95rem);
  --t-h4:    clamp(1.1rem,  1.6vw,  1.3rem);
  --t-lead:  clamp(1.1rem,  1.5vw,  1.375rem);
  --t-body:  1.0625rem;
  --t-small: 0.9375rem;
  --t-label: 0.75rem;      /* Mono-Labels, uppercase */

  --lh-tight:   0.94;      /* Display-Headlines */
  --lh-snug:    1.12;
  --lh-normal:  1.62;      /* Fließtext — großzügig, das liest sich teuer */
  --ls-mega:   -0.045em;   /* enges Tracking bei großen Graden */
  --ls-tight:  -0.025em;
  --ls-label:   0.16em;    /* weites Tracking bei Mono-Labels */

  /* --- Raum ---------------------------------------------------------------
     Basis 8px, aber mit bewusst großen Sektionsabständen.
     Zu enge Abstände sind das häufigste Merkmal billiger Seiten. */
  --s-1:  0.25rem;
  --s-2:  0.5rem;
  --s-3:  0.75rem;
  --s-4:  1rem;
  --s-5:  1.5rem;
  --s-6:  2rem;
  --s-7:  3rem;
  --s-8:  4rem;
  --s-9:  6rem;
  --s-10: 8rem;
  --s-11: 12rem;

  --sektion-y:  clamp(4.5rem, 9vw, 9rem);   /* vertikaler Sektionsabstand */
  --gutter:     clamp(1.25rem, 4vw, 3.5rem); /* seitlicher Seitenrand */
  --max-w:      82.5rem;    /* 1320px — Inhaltsbreite */
  --max-w-text: 38rem;      /* Lesebreite, ca. 70 Zeichen */

  /* --- Kanten & Rahmen ----------------------------------------------------
     Leichte Rundung statt scharfer Ecke. 4px ist genug, um die Härte zu
     nehmen, und zu wenig, um weich oder verspielt zu wirken. Absolut
     scharfe Ecken lassen jede Fläche nach unfertigem Prototyp aussehen. */
  --radius:    4px;
  --radius-sm: 3px;
  --radius-lg: 6px;

  --b-hair:  1px solid var(--c-line);
  --b-thin:  1.5px solid var(--c-line);
  --b-bold:  2px solid var(--c-line);
  --b-heavy: 3px solid var(--c-line);
  --b-soft:  1px solid var(--c-line-soft);

  /* Schatten: sehr zurückhaltend und NIE reines Schwarz. Ein schwarzer
     Versatzschatten wirkt wie ein Aufkleber. Diese hier geben Tiefe,
     ohne sich in den Vordergrund zu drängen. */
  --sh-weich:  0 2px 6px rgba(20, 17, 15, 0.07),
               0 8px 24px rgba(20, 17, 15, 0.06);
  --sh-karte:  0 1px 3px rgba(20, 17, 15, 0.06),
               0 12px 32px rgba(20, 17, 15, 0.08);
  --sh-hoch:   0 4px 12px rgba(20, 17, 15, 0.10),
               0 20px 48px rgba(20, 17, 15, 0.10);

  /* --- Bewegung -----------------------------------------------------------
     Ein Easing-Set, konsequent verwendet. Uneinheitliche Easings
     sind ein sofort sichtbares Qualitätsleck. */
  --e-out:  cubic-bezier(0.16, 1, 0.30, 1);      /* Standard: satt, entschieden */
  --e-in:   cubic-bezier(0.55, 0, 1, 0.45);
  --e-io:   cubic-bezier(0.65, 0, 0.35, 1);
  --e-snap: cubic-bezier(0.34, 1.32, 0.42, 1);   /* leichtes Überschwingen */

  --d-fast: 180ms;
  --d-base: 320ms;
  --d-slow: 620ms;
  --d-reveal: 900ms;

  /* --- Ebenen --- */
  --z-base: 1;
  --z-sticky: 50;
  --z-nav: 100;
  --z-overlay: 200;
  --z-modal: 300;
}

/* Raster-Linien-Textur als wiederverwendbarer Hintergrund.
   Erzeugt das technische Millimeterpapier-Gefühl. */
:root {
  --bg-raster:
    repeating-linear-gradient(0deg,   var(--c-line-soft) 0 1px, transparent 1px 4.5rem),
    repeating-linear-gradient(90deg,  var(--c-line-soft) 0 1px, transparent 1px 4.5rem);
  --bg-diagonal:
    repeating-linear-gradient(45deg, var(--c-ink) 0 1px, transparent 1px 7px);
}

/* Dunkle Sektionen: Tokens umkehren, damit Komponenten unverändert
   funktionieren. Kein Extra-CSS pro Komponente nötig. */
.ist-dunkel {
  --c-ink:        #F6F2EB;
  --c-ink-soft:   #C9C2B8;
  --c-ink-mute:   #8E877E;
  --c-paper:      #14110F;
  --c-paper-warm: #1E1A17;
  --c-line:       #F6F2EB;
  --c-line-soft:  #3A3431;
  color: var(--c-ink);
  background-color: var(--c-paper);
}


/* ===== 02-base.css ===== */
/* ==========================================================================
   02-BASE — Reset, Grundtypografie, Zugänglichkeit
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Sticky-Nav-Höhe berücksichtigen, wenn per Anker gesprungen wird */
  scroll-padding-top: calc(var(--nav-h, 4.75rem) + var(--s-5));
}

body {
  margin: 0;
  background-color: var(--c-paper);
  color: var(--c-ink);
  font-family: var(--f-text);
  font-size: var(--t-body);
  line-height: var(--lh-normal);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;   /* schützt gegen horizontales Ausbrechen von Marquees */
}

/* Verhindert Scrollen, solange das Mobil-Menü offen ist */
body[data-scroll-sperre] { overflow: hidden; }

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  text-wrap: balance;      /* verhindert Hurenkinder in Headlines */
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: var(--lh-snug); }
h4 { font-size: var(--t-h4); line-height: var(--lh-snug); }

p  { margin: 0 0 var(--s-4); max-width: var(--max-w-text); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: color var(--d-fast) var(--e-out);
}
a:hover { color: var(--c-accent); }

ul, ol { margin: 0 0 var(--s-4); padding-left: var(--s-5); }
li + li { margin-top: var(--s-2); }

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

figure { margin: 0; }

strong, b { font-weight: 700; }

hr {
  border: 0;
  border-top: var(--b-bold);
  margin: var(--s-7) 0;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
  border-radius: var(--radius);
}

button { cursor: pointer; }

/* --- Fokus: sichtbar und kantig, nie entfernen -------------------------- */
:focus-visible {
  outline: 3px solid var(--c-focus);
  outline-offset: 3px;
}
:focus:not(:focus-visible) { outline: none; }

/* --- Auswahlfarbe --- */
::selection {
  background: var(--c-accent);
  color: var(--c-accent-ink);
}

/* --- Nur für Screenreader --- */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- Sprunglink zum Inhalt (Pflicht für Barrierefreiheit) --------------- */
.sprunglink {
  position: absolute;
  top: var(--s-2);
  left: var(--s-2);
  z-index: var(--z-modal);
  padding: var(--s-3) var(--s-4);
  background: var(--c-ink);
  color: var(--c-paper);
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--d-base) var(--e-out);
}
.sprunglink:focus { transform: translateY(0); }

/* --- Bewegung reduzieren: harte Abschaltung ----------------------------
   Pflicht. Ohne das ist die Seite für Menschen mit vestibulären
   Beschwerden unbenutzbar — und es ist ein WCAG-Kriterium. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Reveal-Elemente müssen trotzdem sichtbar sein */
  [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}

/* --- Druckansicht: Kunden drucken Kontaktseiten wirklich aus ----------- */
@media print {
  .site-nav, .site-footer, .zum-anfang, video, .karte-platzhalter { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  a::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}


/* ===== 03-layout.css ===== */
/* ==========================================================================
   03-LAYOUT — Container, Raster, Sektionen
   --------------------------------------------------------------------------
   Grundhaltung: 12-Spalten-Raster, aber ASYMMETRISCH bespielt.
   Alles zentriert und gleich breit ist das Erkennungsmerkmal von
   Baukasten-Seiten. Wir setzen Inhalte bewusst versetzt.
   ========================================================================== */

.wrap {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Randlos, aber mit Seitenrand — für Marquees und volle Bildflächen */
.wrap-breit {
  width: 100%;
  padding-inline: var(--gutter);
}

.sektion {
  position: relative;
  padding-block: var(--sektion-y);
}
.sektion--eng   { padding-block: calc(var(--sektion-y) * 0.55); }
.sektion--weit  { padding-block: calc(var(--sektion-y) * 1.45); }
.sektion--warm  { background: var(--c-paper-warm); }
.sektion--rand  { border-top: var(--b-bold); }

/* --- 12-Spalten-Raster -------------------------------------------------- */
.raster {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--s-6) var(--s-5);
}

/* Spaltenbelegung — Desktop */
@media (min-width: 62rem) {
  .sp-1  { grid-column: span 1; }
  .sp-2  { grid-column: span 2; }
  .sp-3  { grid-column: span 3; }
  .sp-4  { grid-column: span 4; }
  .sp-5  { grid-column: span 5; }
  .sp-6  { grid-column: span 6; }
  .sp-7  { grid-column: span 7; }
  .sp-8  { grid-column: span 8; }
  .sp-9  { grid-column: span 9; }
  .sp-10 { grid-column: span 10; }
  .sp-12 { grid-column: span 12; }

  /* Versatz — hiermit entsteht die asymmetrische Anmutung */
  .ab-2  { grid-column-start: 2; }
  .ab-3  { grid-column-start: 3; }
  .ab-4  { grid-column-start: 4; }
  .ab-5  { grid-column-start: 5; }
  .ab-6  { grid-column-start: 6; }
  .ab-7  { grid-column-start: 7; }
  .ab-8  { grid-column-start: 8; }
}

/* Mobil: alles volle Breite, kein Versatz */
@media (max-width: 61.9375rem) {
  .raster > * { grid-column: 1 / -1; }
}

/* --- Zweiteiler mit ungleicher Gewichtung -------------------------------
   Standard-Muster für "Text links, Bild rechts" — aber 5/7 statt 6/6,
   das wirkt komponiert statt schematisch. */
.split {
  display: grid;
  gap: var(--s-7) var(--s-6);
  align-items: start;
}
@media (min-width: 62rem) {
  .split            { grid-template-columns: 5fr 7fr; gap: var(--s-8); }
  .split--umgekehrt { grid-template-columns: 7fr 5fr; }
  .split--mittig    { align-items: center; }
}

/* --- Sektionskopf ------------------------------------------------------- */
.sektion-kopf {
  display: grid;
  gap: var(--s-4);
  margin-bottom: var(--s-8);
  max-width: 54rem;
}
/* :not(.kicker) ist entscheidend: Das Label ist ebenfalls ein <p>.
   Ohne die Ausnahme bekommt es Lead-Größe und Fließtextfarbe, und die
   eigene Kicker-Regel verliert, weil sie geringere Spezifität hat. */
.sektion-kopf p:not(.kicker) { color: var(--c-ink-soft); font-size: var(--t-lead); }

/* Kleines Label über der Headline.
   --------------------------------------------------------------------------
   KEIN vorangestellter Strich und KEINE durchlaufende Nummerierung
   (01, 02, 03 …). Beides war in früheren Fassungen enthalten und ist
   ein sofort erkennbares Vorlagenmerkmal — es sieht nach Baukasten aus,
   nicht nach Redaktion. Das Label trägt nur noch das Wort selbst, in der
   Textschrift, in Versalien mit weitem Tracking. */
.kicker {
  display: inline-block;
  font-family: var(--f-label);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-accent);
}

/* Falls doch einmal eine optische Trennung gebraucht wird: eine feine
   Linie UNTER dem Label, nicht davor. Wirkt wie eine Marginalie statt
   wie ein Aufzählungszeichen. */
.kicker--unterstrich {
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-line-soft);
}

/* --- Kartenraster -------------------------------------------------------
   auto-fit füllt die Zeile so voll wie möglich. Bei sechs Karten ergibt
   das auf breiten Schirmen 4 + 2 — eine halbleere zweite Zeile, die
   unfertig aussieht. Deshalb wird die Spaltenzahl zur Anzahl passend
   gesetzt: 6 Karten → 3 + 3, 8 Karten → 4 + 4.

   Regel: Die Zeilen müssen gleichmäßig aufgehen. Geht die Anzahl nicht
   auf (5, 7), gehört das vor dem Bauen geklärt — dann ist meist eine
   Karte zu viel oder eine zu wenig. */
.karten {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(17.5rem, 100%), 1fr));
}
.karten--2 { grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr)); }

@media (min-width: 62rem) {
  .karten--3 { grid-template-columns: repeat(3, 1fr); }
  .karten--4 { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 40rem) and (max-width: 61.9375rem) {
  .karten--3,
  .karten--4 { grid-template-columns: repeat(2, 1fr); }
}

/* --- Hilfsklassen ------------------------------------------------------- */
.stapel > * + * { margin-top: var(--s-4); }
.stapel-weit > * + * { margin-top: var(--s-6); }
.text-lead { font-size: var(--t-lead); line-height: 1.5; color: var(--c-ink-soft); }
.text-eng  { max-width: var(--max-w-text); }
.mittig    { text-align: center; margin-inline: auto; }

/* Trennlinie mit Diagonalschraffur — statt schlichtem <hr> */
.trenner-schraffur {
  height: 0.75rem;
  background-image: var(--bg-diagonal);
  border-block: var(--b-hair);
}


/* ===== 04-komponenten.css ===== */
/* ==========================================================================
   04-KOMPONENTEN
   --------------------------------------------------------------------------
   Reihenfolge:
   1  Buttons          6  Leistungs-Akkordeon
   2  Navigation       7  Galerie
   3  Hero + Video     8  Kontakt / Formular
   4  Bewertungs-Laufband  9  Karte (Google Maps mit Einwilligung)
   5  Karten / Kacheln 10 Footer + Zum-Anfang
   ========================================================================== */


/* ==========================================================================
   1 — BUTTONS
   Umriss in der Markenfarbe, Fläche leer. Beim Überfahren läuft ein
   Farbverlauf von links ein, die Schrift wird weiß. Kein Schatten.
   ========================================================================== */

/* Grundform: Umriss in der Markenfarbe, Fläche leer. Beim Überfahren
   läuft ein Farbverlauf von links nach rechts ein und die Schrift wird
   hell. Kein Schatten — die Bewegung trägt den Effekt allein.

   Der Verlauf geht von einem helleren zu einem dunkleren Ton derselben
   Farbe. Eine einzelne Volltonfläche wirkt flach; zwei Nuancen geben
   der Fläche Tiefe, ohne bunt zu werden. */
.btn {
  --btn-linie: var(--c-accent);
  --btn-fg:    var(--c-accent);
  --btn-fg-an: #FFFFFF;
  --btn-hell:  var(--c-accent);
  --btn-dunkel:var(--c-accent-deep);

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-6);
  border: 1.5px solid var(--btn-linie);
  border-radius: var(--radius);
  background: transparent;
  color: var(--btn-fg);
  font-family: var(--f-label);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--d-base) var(--e-out);
}

/* Die einlaufende Fläche. transform statt width, damit der Browser sie
   auf der Grafikkarte bewegen kann und nichts neu umbricht. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(100deg, var(--btn-hell), var(--btn-dunkel));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--d-slow) var(--e-out);
}
.btn:hover,
.btn:focus-visible { color: var(--btn-fg-an); }
.btn:hover::before,
.btn:focus-visible::before { transform: scaleX(1); }

/* Beim Loslassen läuft die Fläche nach rechts hinaus, statt einfach zu
   verschwinden — die Bewegung bleibt in einer Richtung. */
.btn:not(:hover)::before { transform-origin: right center; }

.btn:active { transform: translateY(1px); }

.btn--gross { padding: var(--s-5) var(--s-7); font-size: 0.875rem; }

/* Gefüllte Fassung für die wichtigste Handlung einer Seite.
   Beim Überfahren dreht sich der Verlauf, statt zu verblassen. */
.btn--voll {
  --btn-fg: #FFFFFF;
  border-color: transparent;
  background: linear-gradient(100deg, var(--c-accent), var(--c-accent-deep));
}
.btn--voll::before {
  background: linear-gradient(100deg, var(--c-accent-deep), var(--c-accent));
}

/* Auf dunklem Grund: Umriss und Schrift hell, Füllung bleibt farbig. */
.btn--hell {
  --btn-linie: rgba(255, 255, 255, 0.55);
  --btn-fg: #FFFFFF;
  --btn-fg-an: #FFFFFF;
}
.btn--hell:hover { --btn-linie: transparent; }


/* Auf schmalen Geräten: Umbruch erlauben und volle Breite.
   Ohne das schiebt eine lange Beschriftung wie "Kostenloses Angebot
   anfordern" den Button über den rechten Rand hinaus — sichtbar
   abgeschnitten, weil body overflow-x versteckt. */
@media (max-width: 30rem) {
  .btn {
    white-space: normal;
    text-align: center;
    width: 100%;
    padding-inline: var(--s-4);
  }
  .btn--gross { padding-inline: var(--s-4); }
}

/* Reiner Textlink mit animiertem Unterstrich — für Sekundäraktionen */
.link-pfeil {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--f-label);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  color: var(--c-accent);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid currentColor;
}
.link-pfeil svg, .link-pfeil .pfeil {
  transition: transform var(--d-base) var(--e-out);
}
.link-pfeil:hover svg, .link-pfeil:hover .pfeil { transform: translateX(0.4rem); }


/* ==========================================================================
   2 — NAVIGATION
   Sticky, wird beim Scrollen kompakter, blendet beim Runterscrollen aus.
   ========================================================================== */

.site-nav {
  --nav-h: 4.75rem;
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  /* Feiner Verlauf von Weiß in den Papierton. Eine reine Volltonfläche
     wirkt an dieser Stelle stumpf; der Verlauf gibt der Leiste Tiefe,
     ohne dass er als Effekt auffällt. */
  background: linear-gradient(180deg, #FFFFFF 0%, var(--c-paper) 78%, var(--c-paper-warm) 100%);
  border-bottom: 1px solid var(--c-line-soft);
  box-shadow: var(--sh-weich);
  transition: transform var(--d-base) var(--e-out), box-shadow var(--d-base) var(--e-out);
}
/* Beim Runterscrollen ausblenden, beim Hochscrollen sofort zurück.
   Gibt auf Mobil den vollen Bildschirm frei. */
.site-nav[data-versteckt="true"] { transform: translateY(-100%); }

.site-nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  height: var(--nav-h);
  transition: height var(--d-base) var(--e-out);
}
.site-nav[data-gescrollt="true"] { --nav-h: 3.9rem; }

.site-nav__logo {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  text-decoration: none;
  flex: none;
}
.site-nav__logo img, .site-nav__logo svg {
  height: clamp(1.75rem, 3vw, 2.4rem);
  width: auto;
  transition: height var(--d-base) var(--e-out);
}
.site-nav__wortmarke {
  font-family: var(--f-display);
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: var(--ls-tight);
  line-height: 1.05;
  text-transform: uppercase;
}
.site-nav__wortmarke span {
  display: block;
  font-family: var(--f-label);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-mute);
}

/* --- Desktop-Menü --- */
.nav-liste {
  display: none;
  align-items: stretch;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  height: 100%;
}
.nav-liste li { margin: 0; }

.nav-liste a {
  position: relative;
  display: flex;
  align-items: center;
  height: 100%;
  padding: 0 var(--s-5);
  font-family: var(--f-label);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-decoration: none;
  /* Kein Umbruch: "Über uns" darf nicht zweizeilig werden und die
     Nav-Höhe sprengen. Lieber enger setzen als umbrechen lassen. */
  white-space: nowrap;
  overflow: hidden;
}
@media (max-width: 75rem) {
  /* Zwischen 1024 und 1200px wird es eng, sobald Telefonnummer und
     Wortmarke danebenstehen — dann das Innenmaß reduzieren. */
  .nav-liste a { padding-inline: var(--s-4); }
}
/* Akzentbalken fährt von unten ein */
.nav-liste a::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 3px;
  background: var(--c-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-base) var(--e-out);
}
.nav-liste a:hover::after,
.nav-liste a[aria-current="page"]::after { transform: scaleX(1); }
.nav-liste a[aria-current="page"] { font-weight: 700; }

.site-nav__aktion { display: none; flex: none; }

/* --- Mobil-Schalter (Burger → X, animiert) --- */
.nav-schalter {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  background: transparent;
  border: var(--b-bold);
  flex: none;
}
.nav-schalter__balken {
  position: relative;
  width: 1.25rem;
  height: 2px;
  background: var(--c-ink);
  transition: background-color var(--d-fast) var(--e-out);
}
.nav-schalter__balken::before,
.nav-schalter__balken::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--c-ink);
  transition: transform var(--d-base) var(--e-out);
}
.nav-schalter__balken::before { top: -6px; }
.nav-schalter__balken::after  { top:  6px; }

.nav-schalter[aria-expanded="true"] .nav-schalter__balken { background: transparent; }
.nav-schalter[aria-expanded="true"] .nav-schalter__balken::before { transform: translateY(6px) rotate(45deg); }
.nav-schalter[aria-expanded="true"] .nav-schalter__balken::after  { transform: translateY(-6px) rotate(-45deg); }

/* Umschaltpunkt Mobil → Desktop.
   MUSS nach den Basisregeln von .nav-liste, .site-nav__aktion und
   .nav-schalter stehen: alle vier Regeln haben dieselbe Spezifität,
   also entscheidet die Reihenfolge im Dokument. Stünde dieser Block
   weiter oben, bliebe der Burger auch auf dem Desktop sichtbar. */
@media (min-width: 64rem) {
  .nav-liste,
  .site-nav__aktion { display: flex; }
  .nav-schalter { display: none; }
}

/* --- Mobil-Overlay: Einträge staffeln sich herein --- */
.nav-overlay {
  position: fixed;
  inset: var(--nav-h, 4.75rem) 0 0 0;
  z-index: var(--z-overlay);
  display: grid;
  align-content: start;
  padding: var(--s-6) var(--gutter) var(--s-8);
  background: var(--c-paper);
  border-top: var(--b-bold);
  overflow-y: auto;
  overscroll-behavior: contain;
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition:
    clip-path var(--d-slow) var(--e-out),
    visibility 0s linear var(--d-slow);
}
.nav-overlay[data-offen="true"] {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition:
    clip-path var(--d-slow) var(--e-out),
    visibility 0s;
}

.nav-overlay__liste {
  margin: 0 0 var(--s-7);
  padding: 0;
  list-style: none;
  border-top: var(--b-hair);
}
.nav-overlay__liste li {
  margin: 0;
  border-bottom: var(--b-hair);
  /* Staffelung: jedes Element bekommt per JS --i gesetzt */
  opacity: 0;
  transform: translateY(1.25rem);
  transition:
    opacity var(--d-base) var(--e-out),
    transform var(--d-base) var(--e-out);
  transition-delay: calc(var(--i, 0) * 55ms + 180ms);
}
.nav-overlay[data-offen="true"] .nav-overlay__liste li {
  opacity: 1;
  transform: translateY(0);
}
.nav-overlay__liste a {
  display: flex;
  align-items: baseline;
  gap: var(--s-4);
  padding: var(--s-5) 0;
  font-family: var(--f-display);
  font-size: clamp(1.75rem, 8vw, 2.75rem);
  font-weight: 800;
  letter-spacing: var(--ls-tight);
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
}
/* Hier stand bis 08/2026 eine Nummerierung der Menüpunkte (01, 02, 03)
   über content: attr(data-nr). Patrick hat durchnummerierte Sektionen als
   „wirkt sofort nach Claude" beanstandet; die Regel wurde damals in den
   Sektionen entfernt, im Mobilmenü aber übersehen. Ersatzlos gestrichen.
   Die data-nr-Attribute im Markup können bleiben, sie tun nichts. */

@media (min-width: 64rem) {
  .nav-overlay { display: none; }
}


/* ==========================================================================
   3 — HERO mit rotierendem Videohintergrund
   Videos liegen gestapelt übereinander; JS blendet zum nächsten.
   ========================================================================== */

.hero {
  position: relative;
  display: grid;
  align-items: end;
  /* Füllt den sichtbaren Bereich unterhalb der Navigation vollständig.
     svh statt vh: berücksichtigt die eingeblendete Adressleiste auf dem
     Handy, sonst ragt der Hero dort unter den Bildschirmrand. */
  min-height: calc(100svh - var(--nav-h, 4.75rem));
  padding-block: var(--s-8);
  overflow: hidden;
  border-bottom: var(--b-bold);
  background: var(--c-ink);
  color: var(--c-paper);
  isolation: isolate;
}

.hero__medien {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s var(--e-io);
  will-change: opacity;
}
.hero__video[data-aktiv="true"] { opacity: 1; }

/* Bild-Variante der Hero-Medien.
   Wenn kein Videomaterial vorliegt, rotieren stattdessen Standbilder.
   Gleiche Mechanik, gleiche Überblendung, nur ohne Abspielen. */
.hero__bild {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.4s var(--e-io);
  will-change: opacity;
}
.hero__bild[data-aktiv="true"] { opacity: 1; }

/* Verlauf + Raster über dem Video: Text bleibt lesbar (Kontrast!),
   das Raster nimmt dem Video die Stock-Anmutung. */
.hero__medien::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Links dunkler als rechts: Der Text steht links, dort braucht es
     Kontrast. Rechts bleibt das Motiv sichtbar. Eine gleichmäßig dunkle
     Fläche über dem ganzen Bild verschenkt das Foto. */
  /* So dunkel wie nötig, so hell wie möglich. Der Text steht links,
     dort liegt der Verlauf am dichtesten; nach rechts gibt er das Motiv
     frei. Ein gleichmäßig dunkler Schleier über dem ganzen Bild macht
     das Foto wertlos und die Sektion zur schwarzen Fläche. */
  /* Über der gesamten Textspalte (etwa die linke Hälfte) bleibt der
     Verlauf dicht, danach gibt er das Motiv frei. Ein Foto mit hellen
     Flächen macht Text sonst genau dort unlesbar, wo man es beim
     Entwerfen nicht sieht. */
  background:
    linear-gradient(100deg,
      rgba(12,10,9,0.90) 0%,
      rgba(12,10,9,0.84) 38%,
      rgba(12,10,9,0.62) 56%,
      rgba(12,10,9,0.18) 100%),
    linear-gradient(to top, rgba(12,10,9,0.45) 0%, transparent 40%);
}

.hero__inhalt { position: relative; z-index: 1; }

/* Hier stand bis 08/2026 eine umrandete Pille mit einem farbigen Quadrat
   davor. Patrick hat beides am Kaya-Entwurf beanstandet („Hero-Pille weg"),
   die Korrektur wurde in art-direktion.md dokumentiert, im CSS aber nie
   ausgeführt. Jetzt: nur Text, keine Umrandung, kein Zeichen davor. */
.hero__kicker {
  display: block;
  margin-bottom: var(--s-4);
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
@media (max-width: 30rem) {
  /* Das weite Tracking macht den Kicker auf 390px breiter als den
     Bildschirm. Enger setzen und umbrechen lassen, statt abzuschneiden. */
  .hero__kicker {
    flex-wrap: wrap;
    letter-spacing: 0.1em;
    font-size: 0.6875rem;
  }
}

.hero__titel {
  font-size: var(--t-mega);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-mega);
  text-transform: uppercase;
  margin-bottom: var(--s-5);
  max-width: 20ch;
}
/* Hervorgehobene Zeile bleibt WEISS.
   Die Markenfarbe hat auf einem Foto zu wenig Kontrast: Ein mittleres
   Blau vor grauem Untergrund verschwindet, und der wichtigste Satz der
   Seite ist dann der am schlechtesten lesbare. Rhythmus entsteht hier
   über Zeilenumbruch und Größe, nicht über Farbe. */
.hero__titel em {
  font-style: normal;
  color: inherit;
}
.hero__titel .umrandet {
  -webkit-text-stroke: 1.5px var(--c-paper);
  color: transparent;
}

.hero__text {
  font-size: var(--t-lead);
  line-height: 1.5;
  color: rgba(246,242,235,0.85);
  max-width: 44ch;
  margin-bottom: var(--s-6);
}

.hero__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
}

/* Schaltflächen auf dem Hero
   --------------------------------------------------------------------
   Der Haupt-CTA ist hier WEISS GEFÜLLT mit dunkler Schrift. Ein blauer
   Umriss auf einem Foto ist kaum zu erkennen, und genau die wichtigste
   Handlung der Seite darf nicht die unauffälligste sein.
   Beim Überfahren läuft die Markenfarbe ein und die Schrift wird weiß. */
.hero .btn {
  --btn-linie: #FFFFFF;
  --btn-fg: var(--c-ink);
  --btn-fg-an: #FFFFFF;
  background: #FFFFFF;
}
.hero .btn::before {
  background: linear-gradient(100deg, var(--c-accent), var(--c-accent-deep));
}

/* Zweitrangige Handlung: nur Umriss, damit die Rangfolge sichtbar bleibt. */
/* border-color und background ausgeschrieben, weil die Regel darüber
   beides für alle .btn im Hero festlegt. */
.hero .btn--offen {
  --btn-fg: #FFFFFF;
  --btn-fg-an: #FFFFFF;
  border-color: rgba(255, 255, 255, 0.7);
  background: transparent;
  backdrop-filter: blur(2px);
}
.hero .btn--offen:hover { border-color: transparent; }

/* Faktenzeile am unteren Rand des Hero */
.hero__fakten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0;
  margin-top: var(--s-8);
  border-top: 1.5px solid rgba(246,242,235,0.3);
}
.hero__fakt {
  padding: var(--s-5) var(--s-4) 0 0;
}
.hero__fakt b {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(1.75rem, 3.5vw, 2.6rem);
  font-weight: 800;
  letter-spacing: var(--ls-tight);
  line-height: 1;
}
.hero__fakt span {
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(246,242,235,0.65);
}

/* Video-Fortschrittsanzeige: zeigt, welches Video läuft */
.hero__punkte {
  position: absolute;
  right: var(--gutter);
  bottom: var(--s-6);
  z-index: 2;
  display: flex;
  gap: var(--s-2);
}
.hero__punkt {
  width: 2rem;
  height: 3px;
  padding: 0;
  border: 0;
  background: rgba(246,242,235,0.3);
}
.hero__punkt[aria-current="true"] { background: var(--c-accent); }

@media (max-width: 47.9375rem) {
  .hero__punkte { display: none; }
  .hero { min-height: min(38rem, 88svh); }
}

/* Deutsche Komposita sind lang: "Malerhandwerk", "Fassadensanierung",
   "Wärmedämmverbundsystem". Ein einzelnes solches Wort sprengt auf 390 px
   die Zeile und wird von overflow-x: hidden lautlos abgeschnitten.
   Deshalb geht der Schriftgrad hier deutlich weiter herunter, als die
   clamp-Formel allein es täte. */
@media (max-width: 30rem) {
  .hero__titel { font-size: clamp(1.75rem, 8.2vw, 2.6rem); }
}
@media (max-width: 22rem) {
  .hero__titel { font-size: 1.6rem; }
}


/* ==========================================================================
   4 — BEWERTUNGS-LAUFBAND (echte Google-Rezensionen)
   Endlos von links nach rechts, pausiert bei Hover und Fokus.
   ========================================================================== */

.laufband {
  --tempo: 60s;
  position: relative;
  padding-block: var(--s-6);
  border-block: 1px solid var(--c-line-soft);
  background: var(--c-paper-warm);
  overflow: hidden;
}

.laufband__kopf {
  /* Wird nicht mehr verwendet: Note, Anzahl und Quelle interessieren
     niemanden, die Bewertungen selbst schon. Regel bleibt für den Fall,
     dass ein Betrieb wirklich viele Bewertungen hat (ab etwa 50). */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-5);
  margin-bottom: var(--s-5);
  padding-inline: var(--gutter);
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.laufband__note {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--c-ink);
  font-weight: 700;
}
.laufband__note b { font-size: 1rem; }

.laufband__spur {
  display: flex;
  width: max-content;
  gap: var(--s-4);
  animation: laufband-links var(--tempo) linear infinite;
}
/* Läuft bewusst DURCH — auch beim Überfahren und bei Berührung.
   Ein Band, das unter dem Finger stehen bleibt, wirkt wie ein Fehler,
   und auf dem Handy löst jede Wischgeste ungewollt den Halt aus.
   Ausgenommen: Tastaturfokus, damit ein Link erreichbar bleibt. */
.laufband:focus-within .laufband__spur { animation-play-state: paused; }

@keyframes laufband-links {
  from { transform: translateX(0); }
  /* -50%, weil die Liste im HTML zweimal steht (nahtlose Schleife) */
  to   { transform: translateX(-50%); }
}

.rezension {
  flex: none;
  width: min(24rem, 82vw);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-5);
  background: #FFFFFF;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--sh-weich);
}
.rezension__sterne {
  display: flex;
  gap: 2px;
  color: var(--c-accent);
  font-size: 0.875rem;
  letter-spacing: 0.1em;
}
.rezension__text {
  margin: 0;
  font-size: var(--t-small);
  line-height: 1.55;
  max-width: none;
  /* Lange Rezensionen sauber kürzen, statt Kartenhöhe zu sprengen */
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.rezension__quelle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-top: auto;
  padding-top: var(--s-3);
  border-top: var(--b-soft);
  font-family: var(--f-label);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.rezension__quelle b { color: var(--c-ink); }


/* ==========================================================================
   5 — KARTEN / KACHELN
   ========================================================================== */

/* Leistungs- oder Verweiskachel mit Nummer und Hover-Füllung */
.kachel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-6);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius-lg);

  /* ACHTUNG, hier lag ein Fehler:
     Die Kachel hatte eine feste weiße Fläche, aber die Textfarbe kam aus
     var(--c-ink). Innerhalb einer .ist-dunkel-Sektion ist --c-ink hell,
     also stand heller Text auf weißem Grund und war unlesbar.
     Deshalb wird die Textfarbe hier zusammen mit der Fläche fest gesetzt.
     Regel für alle künftigen Komponenten: Wer den Hintergrund festschreibt,
     muss auch die Schriftfarbe festschreiben. */
  --kachel-grund: #FFFFFF;
  --kachel-text:  #14110F;
  --kachel-meta:  #6E6862;
  background: var(--kachel-grund);
  color: var(--kachel-text);

  /* Lange Wörter wie "Wärmedämmverbundsystem" dürfen die Kachel nicht
     sprengen — sie werden umbrochen statt überzulaufen. */
  overflow-wrap: break-word;
  min-width: 0;
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
  /* Zur Farbe siehe den Block unten — sie darf nicht mitlaufen. */
  transition:
    transform var(--d-base) var(--e-out),
    box-shadow var(--d-base) var(--e-out),
    color 90ms linear;
}
/* Fläche fährt von unten hoch */
.kachel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--c-ink);
  transform: translateY(101%);
  /* Rückweg zügig, damit das Fenster unten kurz bleibt. */
  transition: transform 200ms var(--e-out);
}
/* Die Schrift wird hell, weil die dunkle Fläche darunter liegt. Der
   Wechsel muss deshalb an die Fläche gekoppelt sein, nicht an eine
   eigene Dauer.

   Vorher lief die Fläche 620 ms, die Farbe 320 ms. Für rund 300 ms stand
   damit helle Schrift auf noch weißer Kachel — unlesbar. Genau das hat
   der Kunde gemeldet.

   Jetzt: Fläche 320 ms, Farbe schaltet erst nach 170 ms, wenn die Fläche
   die Kachel im Wesentlichen bedeckt. Auf dem Rückweg schaltet die Farbe
   sofort zurück (Regel oben, ohne Verzögerung), während die Fläche in
   200 ms abfährt.

   Wer hier die Zeiten anfasst, prüft beide Richtungen einzeln. */
.kachel:hover {
  --kachel-text: #F5F3EF;
  --kachel-meta: rgba(245, 243, 239, 0.7);
  transform: translateY(-4px);
  box-shadow: var(--sh-hoch);
  transition:
    transform var(--d-base) var(--e-out),
    box-shadow var(--d-base) var(--e-out),
    color 90ms linear 170ms;
}
.kachel:hover .kachel__fuss { color: #FFFFFF; border-top-color: rgba(245,243,239,0.25); }
.kachel:hover::before {
  transform: translateY(0);
  transition: transform var(--d-base) var(--e-out);
}
.kachel:hover .kachel__nr { color: var(--c-accent); }

.kachel__nr {
  font-family: var(--f-label);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--kachel-meta);
  transition: color var(--d-base) var(--e-out);
}
.kachel__titel {
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  line-height: 1.15;
  letter-spacing: var(--ls-tight);
  hyphens: auto;
}
.kachel p { font-size: var(--t-small); margin: 0; max-width: none; color: var(--kachel-text); }
.kachel h3 { color: var(--kachel-text); }
.kachel__fuss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  margin-top: auto;
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-line-soft);
  font-family: var(--f-label);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-accent);
}
.kachel__fuss .pfeil { transition: transform var(--d-base) var(--e-out); }
.kachel:hover .kachel__fuss .pfeil { transform: translateX(0.4rem); }

/* Große Bildkachel für Sektionsverweise (Startseite → Unterseiten) */
.bildkachel {
  position: relative;
  display: grid;
  align-content: end;
  gap: var(--s-3);
  min-height: 22rem;
  padding: var(--s-6);
  border: var(--b-bold);
  color: var(--c-paper);
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
}
.bildkachel img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--e-out), filter var(--d-slow) var(--e-out);
}
.bildkachel::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(10,8,7,0.9), rgba(10,8,7,0.15) 70%);
  transition: background var(--d-slow) var(--e-out);
}
.bildkachel:hover img { transform: scale(1.05); }
.bildkachel:hover::after { background: linear-gradient(to top, rgba(198,58,23,0.85), rgba(10,8,7,0.25) 75%); }
.bildkachel__titel {
  font-size: var(--t-h2);
  text-transform: uppercase;
  letter-spacing: var(--ls-tight);
}
.bildkachel p { max-width: 34ch; font-size: var(--t-small); color: rgba(246,242,235,0.85); }

/* Faktenblock mit Zähler-Animation */
.fakten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #FFFFFF;
}
.fakt {
  padding: var(--s-6) var(--s-5);
  border-right: var(--b-hair);
  border-bottom: var(--b-hair);
}
.fakt b {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(2rem, 4.5vw, 3.25rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: var(--ls-mega);
  color: var(--c-accent);
}
.fakt span {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-mute);
}


/* ==========================================================================
   6 — LEISTUNGS-AKKORDEON
   Reine <details>-Elemente: funktioniert ohne JS, wird nur verschönert.
   ========================================================================== */

.leistungen { border-top: var(--b-bold); }

.leistung {
  border-bottom: var(--b-bold);
}
.leistung > summary {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding: var(--s-6) 0;
  cursor: pointer;
  list-style: none;
  transition: padding-inline var(--d-base) var(--e-out), color var(--d-base) var(--e-out);
}
.leistung > summary::-webkit-details-marker { display: none; }
.leistung > summary:hover { padding-inline: var(--s-4); color: var(--c-accent); }

.leistung__nr {
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  color: var(--c-ink-mute);
  flex: none;
}
.leistung__titel {
  flex: 1;
  font-family: var(--f-display);
  font-size: clamp(1.35rem, 3.2vw, 2.15rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-tight);
  line-height: 1.05;
}
/* Plus wird zu Minus */
.leistung__zeichen {
  position: relative;
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
}
.leistung__zeichen::before,
.leistung__zeichen::after {
  content: "";
  position: absolute;
  top: 50%; left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
  transition: transform var(--d-base) var(--e-out);
}
.leistung__zeichen::after { transform: rotate(90deg); }
.leistung[open] .leistung__zeichen::after { transform: rotate(0deg); }

.leistung__inhalt {
  display: grid;
  gap: var(--s-6);
  padding-bottom: var(--s-7);
}
@media (min-width: 62rem) {
  .leistung__inhalt { grid-template-columns: 1fr 1fr; align-items: start; }
}
.leistung__liste {
  margin: 0;
  padding: 0;
  list-style: none;
  columns: 2;
  column-gap: var(--s-5);
}
.leistung__liste li {
  margin: 0 0 var(--s-2);
  padding-left: var(--s-5);
  font-size: var(--t-small);
  position: relative;
  break-inside: avoid;
}
.leistung__liste li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.62em;
  width: 8px; height: 8px;
  background: var(--c-accent);
}
@media (max-width: 34rem) {
  .leistung__liste { columns: 1; }
}


/* ==========================================================================
   7 — GALERIE
   Versetztes Raster; Bilder werden erst beim Klick groß (Lightbox via JS).
   ========================================================================== */

.galerie {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
}
.galerie__figur {
  position: relative;
  margin: 0;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-paper-warm);
}
/* Jedes dritte Bild höher — bricht das Rasterschema auf */
@media (min-width: 48rem) {
  .galerie__figur:nth-child(3n+1) { grid-row: span 2; }
  .galerie__figur:nth-child(3n+1) img { aspect-ratio: 3 / 4; }
}
.galerie__figur img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 1s var(--e-out), filter var(--d-slow) var(--e-out);
}
.galerie__figur:hover img { transform: scale(1.04); }

.galerie__bild-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.galerie__legende {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-4);
  background: linear-gradient(to top, rgba(10,8,7,0.88), transparent);
  color: var(--c-paper);
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  text-align: left;
  transform: translateY(0.5rem);
  opacity: 0;
  transition: opacity var(--d-base) var(--e-out), transform var(--d-base) var(--e-out);
}
.galerie__figur:hover .galerie__legende,
.galerie__bild-btn:focus-visible .galerie__legende {
  opacity: 1;
  transform: translateY(0);
}

/* Vor/Nach-Vergleich mit Schieberegler — starkes Argument für Malerbetriebe */
.vergleich {
  position: relative;
  border: var(--b-bold);
  overflow: hidden;
  touch-action: pan-y;
  cursor: ew-resize;
  user-select: none;
}
.vergleich img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  display: block;
}
.vergleich__nachher {
  position: absolute;
  inset: 0;
  clip-path: inset(0 0 0 var(--pos, 50%));
}
.vergleich__griff {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos, 50%);
  width: 3px;
  background: var(--c-paper);
  pointer-events: none;
}
.vergleich__griff::after {
  content: "↔";
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  background: var(--c-paper);
  border: var(--b-bold);
  color: var(--c-ink);
  font-size: 1rem;
}
.vergleich__marke {
  position: absolute;
  top: var(--s-4);
  padding: var(--s-2) var(--s-3);
  background: var(--c-ink);
  color: var(--c-paper);
  font-family: var(--f-label);
  font-size: 0.625rem;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
.vergleich__marke--vor    { left: var(--s-4); }
.vergleich__marke--nachher{ right: var(--s-4); background: var(--c-accent); }

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  gap: var(--s-4);
  padding: var(--gutter);
  background: rgba(10,8,7,0.94);
  border: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--d-base) var(--e-out);
}
.lightbox[open] { opacity: 1; pointer-events: auto; }
.lightbox::backdrop { background: rgba(10,8,7,0.94); }
.lightbox img {
  max-width: min(78rem, 100%);
  max-height: 82svh;
  object-fit: contain;
  border: var(--b-bold);
  border-color: var(--c-paper);
}
.lightbox__zu {
  position: absolute;
  top: var(--gutter);
  right: var(--gutter);
  width: 3rem; height: 3rem;
  background: transparent;
  border: 2px solid var(--c-paper);
  color: var(--c-paper);
  font-size: 1.25rem;
}
.lightbox__text {
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(246,242,235,0.8);
}


/* ==========================================================================
   8 — KONTAKT / FORMULAR
   ========================================================================== */

.formular {
  display: grid;
  gap: var(--s-5);
}
.feld { display: grid; gap: var(--s-2); }
.feld--zeile { grid-template-columns: 1fr 1fr; gap: var(--s-5); display: grid; }
@media (max-width: 40rem) { .feld--zeile { grid-template-columns: 1fr; } }

.feld label {
  font-family: var(--f-label);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-soft);
}
.feld label .pflicht { color: var(--c-accent); }

.feld input,
.feld textarea,
.feld select {
  width: 100%;
  padding: var(--s-4);
  background: #FFFFFF;
  /* Textfarbe fest, nicht geerbt.
     Der Feldgrund ist immer weiß. Ohne diese Zeile erbt das Feld color
     vom Elternteil — und in einer .ist-dunkel-Sektion ist das eine helle
     Farbe. Ergebnis: weiße Schrift auf weißem Grund, sowohl beim
     Platzhalter als auch bei der Eingabe. Aufgefallen im ZIA-Projekt
     (August 2026) an einem Auswahlfeld in der dunklen Anfrage-Sektion. */
  color: #14110F;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius);
  font-size: var(--t-body);
  transition: box-shadow var(--d-fast) var(--e-out), background-color var(--d-fast) var(--e-out);
}
.feld input:focus,
.feld textarea:focus,
.feld select:focus {
  outline: none;
  box-shadow: var(--sh-weich);
  background: #fff;
}
.feld textarea { min-height: 9rem; resize: vertical; }

.feld input:user-invalid,
.feld textarea:user-invalid { border-color: var(--c-error); }
.feld__fehler { font-size: var(--t-small); color: var(--c-error); }

/* Einwilligung */
.zustimmung {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: start;
  font-size: var(--t-small);
  line-height: 1.5;
}
.zustimmung input[type="checkbox"] {
  width: 1.35rem;
  height: 1.35rem;
  margin-top: 0.15rem;
  accent-color: var(--c-accent);
  flex: none;
}

.formular__hinweis {
  font-size: var(--t-small);
  color: var(--c-ink-mute);
}
.formular__meldung {
  padding: var(--s-4);
  border: var(--b-bold);
  font-size: var(--t-small);
}
.formular__meldung[data-typ="erfolg"] { border-color: var(--c-success); color: var(--c-success); }
.formular__meldung[data-typ="fehler"] { border-color: var(--c-error);   color: var(--c-error); }

/* Kontaktdaten-Block neben dem Formular */
.kontaktdaten {
  display: grid;
  gap: 0;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #FFFFFF;
}
.kontaktdaten__zeile {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: var(--s-4);
  padding: var(--s-5);
  border-bottom: var(--b-hair);
  align-items: baseline;
}
.kontaktdaten__zeile:last-child { border-bottom: 0; }
.kontaktdaten__zeile dt {
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.kontaktdaten__zeile dd { margin: 0; font-weight: 500; }
.kontaktdaten__zeile a { text-decoration: none; border-bottom: var(--b-thin); }
@media (max-width: 32rem) {
  .kontaktdaten__zeile { grid-template-columns: 1fr; gap: var(--s-1); }
}


/* ==========================================================================
   9 — KARTE (Google Maps, erst nach Einwilligung)
   DSGVO: Vor dem Klick wird KEINE Verbindung zu Google aufgebaut.
   Der iframe wird per JS erzeugt, die URL steht in data-karte-src.
   ========================================================================== */

.karte {
  position: relative;
  min-height: min(34rem, 70svh);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius-lg);
  background: var(--c-paper-warm);
  background-image: var(--bg-raster);
  overflow: hidden;
}
.karte iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: inherit;
  border: 0;
}

.karte-platzhalter {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: start;
  gap: var(--s-4);
  padding: var(--s-7) var(--s-6);
  text-align: left;
}
.karte-platzhalter__titel {
  font-family: var(--f-display);
  font-size: var(--t-h3);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--ls-tight);
}
.karte-platzhalter p {
  font-size: var(--t-small);
  color: var(--c-ink-soft);
  max-width: 44ch;
}
.karte-platzhalter__meta {
  font-family: var(--f-label);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}


/* ==========================================================================
   10 — FOOTER + ZUM-ANFANG
   ========================================================================== */

/* ACHTUNG, hier lag ein Fehler:
   Der Block hat zuerst `background: var(--c-ink)` gesetzt und im selben
   Block danach `--c-ink` auf einen hellen Wert umdefiniert. Custom
   Properties werden aufgelöst, BEVOR die Deklarationen greifen — der
   Hintergrund bekam also den neuen hellen Wert, und heller Text stand
   auf hellem Grund. Der Footer war praktisch unlesbar.

   Deshalb: Hintergrund- und Textfarbe hier fest ausschreiben, und die
   Variablen erst danach für die Kindelemente umdefinieren. */
.site-footer {
  --fuss-grund: #14110F;
  --fuss-text:  #F5F3EF;

  border-top: 1px solid rgba(245, 243, 239, 0.14);
  background: var(--fuss-grund);
  color: var(--fuss-text);

  /* Gilt ab hier für alle Kindelemente, nicht mehr für den Block selbst */
  --c-ink: #F5F3EF;
  --c-line: #F5F3EF;
  --c-line-soft: rgba(245, 243, 239, 0.16);
  --c-ink-mute: #9A938A;
}

.site-footer__haupt {
  display: grid;
  gap: var(--s-8) var(--s-6);
  padding-block: var(--s-9) var(--s-8);
}
@media (min-width: 62rem) {
  .site-footer__haupt {
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  }
}

.footer-marke { display: grid; gap: var(--s-4); align-content: start; }
.footer-marke img, .footer-marke svg {
  height: clamp(2.25rem, 4vw, 3rem);
  width: auto;
  /* Falls das Kundenlogo dunkel ist: auf dunklem Grund invertieren.
     Klasse gezielt setzen, nicht global. */
}
.footer-marke img.invertieren { filter: invert(1) brightness(1.9); }
.footer-marke p {
  font-size: var(--t-small);
  color: rgba(246,242,235,0.72);
  max-width: 34ch;
}

.footer-spalte h2 {
  margin-bottom: var(--s-5);
  padding-bottom: var(--s-3);
  border-bottom: var(--b-soft);
  font-family: var(--f-label);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.footer-spalte ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s-3);
}
.footer-spalte li { margin: 0; }
.footer-spalte a {
  display: inline-block;
  font-size: var(--t-small);
  text-decoration: none;
  color: rgba(245, 243, 239, 0.82);
  padding-bottom: 2px;
  /* Unterstrich wächst von links, statt dass ein Strich VOR dem Wort
     erscheint. Der vorangestellte Strich verschob den Text seitlich und
     sah aus wie ein Gedankenstrich im Menü. */
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--d-base) var(--e-out), color var(--d-base) var(--e-out);
}
.footer-spalte a:hover,
.footer-spalte a:focus-visible {
  color: #FFFFFF;
  background-size: 100% 1px;
}

.footer-spalte--einstellung button {
  background: none;
  border: 0;
  padding: 0;
  font-size: var(--t-small);
  color: rgba(246,242,235,0.82);
  text-align: left;
  font-family: inherit;
}
.footer-spalte--einstellung button {
  padding-bottom: 2px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--d-base) var(--e-out), color var(--d-base) var(--e-out);
}
.footer-spalte--einstellung button:hover { color: #FFFFFF; background-size: 100% 1px; }

.site-footer__unten {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-5);
  border-top: var(--b-soft);
  font-family: var(--f-label);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.site-footer__unten a { text-decoration: none; }
.site-footer__unten a:hover { color: var(--c-paper); }

/* Zurück nach oben — erscheint erst nach etwas Scrollen */
.zum-anfang {
  position: fixed;
  right: var(--s-5);
  bottom: var(--s-5);
  z-index: var(--z-sticky);
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  background: var(--c-ink);
  color: var(--c-paper);
  border: var(--b-bold);
  border-color: var(--c-paper);
  box-shadow: var(--sh-weich);
  opacity: 0;
  transform: translateY(1rem);
  pointer-events: none;
  transition: opacity var(--d-base) var(--e-out), transform var(--d-base) var(--e-out);
}
.zum-anfang[data-sichtbar="true"] {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Aliase für die bisherigen Namen, damit bestehende Seiten weiterlaufen.
   .btn--akzent war die gefüllte Fassung, .btn--offen die Umrissfassung. */
.btn--akzent { --btn-fg: #FFFFFF; border-color: transparent;
               background: linear-gradient(100deg, var(--c-accent), var(--c-accent-deep)); }
.btn--akzent::before { background: linear-gradient(100deg, var(--c-accent-deep), var(--c-accent)); }
.btn--offen  { /* entspricht der Grundform */ }


/* ==========================================================================
   11 — SEITENKOPF MIT BILD
   --------------------------------------------------------------------------
   Ersetzt den flächig dunklen Kopf der Unterseiten. Eine stumpfe schwarze
   Fläche wirkt wie ein Platzhalter, den jemand zu füllen vergessen hat.
   Mit Foto wird daraus ein Auftakt, der zur Startseite passt.

   Bewusst niedriger als der Hero der Startseite: Eine Unterseite soll
   schnell zum Inhalt kommen, nicht noch einmal groß auftreten.
   ========================================================================== */

.seitenkopf {
  position: relative;
  display: grid;
  align-items: end;
  min-height: min(26rem, 52svh);
  padding-block: var(--s-9) var(--s-7);
  overflow: hidden;
  isolation: isolate;
  background: var(--c-ink);
  color: #F5F3EF;
}

.seitenkopf__bild {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Gleiche Logik wie im Hero: links dunkler, weil dort der Text steht. */
.seitenkopf::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(100deg, rgba(12,10,9,0.88) 0%, rgba(12,10,9,0.70) 45%, rgba(12,10,9,0.35) 100%),
    linear-gradient(to top, rgba(12,10,9,0.55) 0%, transparent 50%);
}

.seitenkopf .kicker { color: rgba(245, 243, 239, 0.75); }

.seitenkopf h1 {
  font-size: clamp(2rem, 5vw, 4rem);
  max-width: 22ch;
  margin-top: var(--s-3);
}

.seitenkopf__text {
  margin-top: var(--s-5);
  max-width: 60ch;
  font-size: clamp(1rem, 1.15vw, 1.1875rem);
  line-height: 1.55;
  color: rgba(245, 243, 239, 0.85);
}


/* ==========================================================================
   12 — SEKTION MIT BILDHINTERGRUND
   Für Abschnitte, die sich abheben sollen, ohne in eine schwarze Fläche
   zu kippen. Das Bild bleibt erkennbar, der Text bleibt lesbar.
   ========================================================================== */

.sektion--bild {
  position: relative;
  isolation: isolate;
  color: #F5F3EF;
  background: var(--c-ink);
}
.sektion--bild > img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sektion--bild::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(12,10,9,0.90) 0%, rgba(12,10,9,0.82) 55%, rgba(12,10,9,0.92) 100%);
}
.sektion--bild .kicker { color: rgba(245, 243, 239, 0.75); }
.sektion--bild .sektion-kopf p { color: rgba(245, 243, 239, 0.82); }


/* ==========================================================================
   13 — ABSCHLUSSBAND (Handlungsaufforderung vor dem Footer)
   --------------------------------------------------------------------------
   Nimmt den Farbton des Footers auf und geht nahtlos in ihn über. Eine
   eigene Signalfarbe an dieser Stelle zerschneidet das Seitenende in zwei
   fremde Blöcke.

   Die Schaltfläche steht in der Markenfarbe und hebt sich damit klar vom
   Untergrund ab. Farbe auf Farbe war der Fehler der ersten Fassung.
   ========================================================================== */

.abschluss {
  padding-block: var(--s-10);
  background: #14110F;
  color: #F5F3EF;
  text-align: center;
}
.abschluss__inner {
  display: grid;
  justify-items: center;
  gap: var(--s-6);
  max-width: 46rem;
  margin-inline: auto;
}
.abschluss h2 {
  font-size: clamp(1.75rem, 3.6vw, 3rem);
  max-width: 20ch;
}
.abschluss p {
  max-width: 52ch;
  color: rgba(245, 243, 239, 0.78);
  margin: 0;
}
.abschluss__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: center;
}
/* Haupt-CTA: gefüllt in der Markenfarbe, damit er auf dem dunklen
   Untergrund sofort ins Auge fällt. */
.abschluss .btn {
  --btn-fg: #FFFFFF;
  --btn-fg-an: #FFFFFF;
  border-color: transparent;
  background: linear-gradient(100deg, var(--c-accent), var(--c-accent-deep));
}
.abschluss .btn::before {
  background: linear-gradient(100deg, var(--c-accent-deep), var(--c-accent));
}
/* Zweitrangig: heller Umriss, keine Füllung.
   border-color muss hier ausgeschrieben werden: Die Regel darüber setzt
   sie für alle .btn im Abschlussband auf transparent, und eine bloße
   Neubelegung von --btn-linie erreicht die bereits aufgelöste
   border-color-Deklaration nicht mehr. */
.abschluss .btn--offen {
  --btn-fg: #F5F3EF;
  --btn-fg-an: #FFFFFF;
  border-color: rgba(245, 243, 239, 0.55);
  background: transparent;
}
.abschluss .btn--offen:hover { border-color: transparent; }

/* Direkt vor dem Footer: keine Kante zwischen beiden Flächen. */
.abschluss + .site-footer { border-top: 0; }


/* ==========================================================================
   14 — BILDRASTER MIT VERSETZTEN HÖHEN (Referenzen)
   --------------------------------------------------------------------------
   Spaltenbasiert statt Zeilenraster: Hoch- und Querformate stehen
   nebeneinander, ohne beschnitten zu werden. Jede Aufnahme behält ihr
   eigenes Seitenverhältnis, das Raster füllt sich von selbst.
   ========================================================================== */

.bildraster {
  columns: 4;
  column-gap: var(--s-4);
}
@media (max-width: 74rem)   { .bildraster { columns: 3; } }
@media (max-width: 52rem)   { .bildraster { columns: 2; } }
@media (max-width: 30rem)   { .bildraster { columns: 1; } }

.bildraster__figur {
  position: relative;
  display: block;
  width: 100%;
  margin: 0 0 var(--s-4);
  /* Verhindert, dass eine Kachel über den Spaltenumbruch zerrissen wird */
  break-inside: avoid;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--c-paper-warm);
  text-decoration: none;
  color: inherit;
  transition: transform var(--d-base) var(--e-out), box-shadow var(--d-base) var(--e-out);
}
.bildraster__figur:hover,
.bildraster__figur:focus-visible {
  transform: translateY(-4px) scale(1.015);
  box-shadow: var(--sh-hoch);
  z-index: 2;
}
.bildraster__figur img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform var(--d-slow) var(--e-out);
}
.bildraster__figur:hover img { transform: scale(1.05); }

/* Beschriftung liegt auf dem Bild, mit Verlauf für die Lesbarkeit.
   Auf dem Handy dauerhaft sichtbar, weil es dort kein Überfahren gibt. */
.bildraster__text {
  position: absolute;
  inset: auto 0 0 0;
  display: grid;
  gap: 2px;
  padding: var(--s-6) var(--s-4) var(--s-4);
  /* Kräftiger Verlauf: Die Bildunterkante ist mal dunkel, mal hell.
     Ein schwacher Verlauf lässt die Schrift auf hellen Motiven
     verschwinden, und man sieht es beim Entwerfen nicht, weil man auf
     das dunkle Beispielbild schaut. */
  background: linear-gradient(to top,
    rgba(12,10,9,0.94) 0%, rgba(12,10,9,0.80) 40%, rgba(12,10,9,0.35) 72%, transparent 100%);
  color: #FFFFFF;
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--d-base) var(--e-out), transform var(--d-base) var(--e-out);
}
@media (hover: hover) {
  .bildraster__text { opacity: 0; transform: translateY(0.75rem); }
  .bildraster__figur:hover .bildraster__text,
  .bildraster__figur:focus-visible .bildraster__text {
    opacity: 1;
    transform: translateY(0);
  }
}
.bildraster__kategorie {
  font-family: var(--f-label);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* Helles Blau statt der Signalfarbe: Rot auf dunklem Verlauf hat zu
     wenig Kontrast und war praktisch unlesbar. */
  color: #9DBBF0;
}
.bildraster__titel {
  font-family: var(--f-display);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  line-height: 1.2;
}


/* ==========================================================================
   15 — KONTAKT MIT GROSSER KARTE
   Kontaktdaten links, Karte rechts, beide über die volle Breite. Eine
   kleine Karte in einer engen Spalte wirkt wie ein nachträglich
   eingeschobener Hinweis; großzügig gesetzt wird sie zur Einladung.
   ========================================================================== */

.kontakt-breit {
  display: grid;
  gap: var(--s-7);
  align-items: stretch;
}
@media (min-width: 62rem) {
  .kontakt-breit { grid-template-columns: 5fr 7fr; gap: var(--s-8); }
}
.kontakt-breit .karte {
  min-height: min(38rem, 74svh);
  height: 100%;
}
.kontakt-breit__daten {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  justify-content: center;
}


/* ==========================================================================
   16 — SEKTIONSÜBERGÄNGE
   --------------------------------------------------------------------------
   Der wichtigste Befund aus der Bremen-Recherche: Bei vier von fünf
   Seiten, die dem Kunden gefielen, ist die Kante zwischen den Sektionen
   NICHT gerade. Gerade Kanten stapeln Blöcke, und genau so liest sich
   eine Vorlage.

   REGEL: Eine Sorte pro Seite. Welle ODER Schräge, nie beides gemischt.
   Nagengast hält die Schräge über die ganze Seite durch, und genau das
   macht den Unterschied zu einem Effekt, der einmal vorkommt.

   Beide Varianten arbeiten mit --uebergang-farbe. Diese Variable muss
   die Farbe der FOLGENDEN Fläche tragen, denn der Übergang gehört
   optisch zur nächsten Sektion, auch wenn er technisch an der
   vorherigen hängt.
   ========================================================================== */

.uebergang {
  /* ZWEI Farben, nicht eine: --von trägt die Fläche darüber, --farbe die
     darunter. Damit braucht der Übergang keine negative Margin und
     schneidet nichts aus der vorherigen Sektion heraus.

     Die erste Fassung überlappte die Sektion darüber und hat prompt die
     letzten beiden Spalten des Zahlenbands angeschnitten. */
  --uebergang-von: var(--c-paper);
  --uebergang-farbe: var(--c-paper);

  /* Deutlich, nicht dezent. Bei 4 vw ist die Schräge über 1440 px so
     flach, dass sie wie ein Renderfehler aussieht statt wie eine
     Gestaltungsentscheidung. Nagengast setzt sie kräftig, und genau das
     macht dort die Wirkung. */
  --uebergang-hoehe: clamp(3rem, 6.5vw, 8rem);

  position: relative;
  display: block;
  width: 100%;
  height: var(--uebergang-hoehe);
  background: var(--uebergang-von);
  overflow: hidden;
  pointer-events: none;
}
.uebergang svg {
  display: block;
  width: 100%;
  height: 100%;
}
.uebergang path { fill: var(--uebergang-farbe); }

/* --- Schräge ------------------------------------------------------------
   Reines clip-path, kein SVG nötig. Die Richtung wird über die Variante
   gesteuert, damit aufeinanderfolgende Schrägen parallel laufen und
   nicht gegeneinander zeigen. */
.uebergang--schraeg::after,
.uebergang--schraeg-links::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--uebergang-farbe);
}
.uebergang--schraeg::after       { clip-path: polygon(0 100%, 100% 0, 100% 100%); }
.uebergang--schraeg-links::after { clip-path: polygon(0 0, 100% 100%, 0 100%); }

/* --- Welle --------------------------------------------------------------
   Als Inline-SVG im Markup, damit die Kurve sauber skaliert. Das Markup
   steht in den Seiten, hier nur die Darstellung. */
.uebergang--welle { background: transparent; }

/* Auf schmalen Geräten flacher: Eine steile Schräge frisst dort zu viel
   Höhe und schneidet Text an. */
@media (max-width: 47.9375rem) {
  .uebergang { --uebergang-hoehe: clamp(1.75rem, 7vw, 2.75rem); }
}


/* ==========================================================================
   17 — FARBKLECKS
   --------------------------------------------------------------------------
   Für einen Malerbetrieb die naheliegendste Bildmarke. Als SVG umgesetzt
   und nicht als Bilddatei: So nimmt der Klecks jede Markenfarbe an,
   skaliert verlustfrei und wiegt nichts.

   Sparsam einsetzen. Zwei bis drei pro Seite, in unterschiedlicher Größe
   und Deckkraft. Fünf Kleckse sind Konfetti.
   ========================================================================== */

.klecks {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  color: var(--c-accent);
  opacity: 0.10;
  width: clamp(12rem, 26vw, 28rem);
  aspect-ratio: 1;
}
.klecks svg { width: 100%; height: 100%; display: block; }
.klecks path { fill: currentColor; }

.klecks--klein  { width: clamp(6rem, 12vw, 12rem); }
.klecks--gross  { width: clamp(18rem, 40vw, 44rem); }
.klecks--zart   { opacity: 0.05; }
.klecks--kraeftig { opacity: 0.18; }

/* Ausrichtung. Der Klecks darf über die Sektionskante hinausragen,
   deshalb sitzt er mit negativen Werten. */
.klecks--oben-rechts  { top: -8%;    right: -6%; }
.klecks--unten-links  { bottom: -10%; left: -8%; }
.klecks--mitte-rechts { top: 30%;    right: -12%; }

/* Sektionen, die einen Klecks tragen, brauchen einen Bezugsrahmen und
   müssen ihren Inhalt darüber legen. */
.hat-klecks { position: relative; overflow: hidden; isolation: isolate; }
.hat-klecks > .wrap { position: relative; z-index: 1; }

@media (max-width: 47.9375rem) {
  /* Auf dem Handy nur der größte, sonst wird es unruhig. */
  .klecks--klein, .klecks--mitte-rechts { display: none; }
}


/* ==========================================================================
   18 — HERO OHNE NAVIGATION
   --------------------------------------------------------------------------
   Aus dem Miro-Beispiel der Bremen-Recherche: Im Hero liegt kein Text
   über dem Foto, deshalb braucht es keinen abdunkelnden Verlauf. Das
   Bild wirkt voll. Die Navigation blendet erst beim Scrollen ein.

   Voraussetzung: Der Hero trägt seine Aussage über eine eigene Fläche,
   etwa ein Banner am Rand. Text mitten im Bild ohne Verlauf ist nicht
   lesbar, und genau das war die Kritik an den bisherigen Entwürfen in
   der Gegenrichtung.

   Aktiviert über <body class="hero-ohne-nav">.
   ========================================================================== */

.hero-ohne-nav .site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  transform: translateY(-100%);
  transition: transform var(--d-slow) var(--e-out);
}
/* site.js setzt data-eingeblendet, sobald der Hero verlassen wird. */
.hero-ohne-nav .site-nav[data-eingeblendet="true"] { transform: translateY(0); }

/* Der Hero rückt unter die Leiste, weil sie ihn nicht mehr verdrängt. */
.hero-ohne-nav .hero { min-height: 100svh; }

/* Ohne Text im Bild entfällt der Verlauf vollständig. */
.hero-ohne-nav .hero__medien::after { background: none; }

/* Sprunglink und Mobilschalter müssen trotzdem erreichbar bleiben:
   Ein Menü, das erst nach dem Scrollen existiert, sperrt sonst die
   Bedienung per Tastatur aus. */
.hero-ohne-nav .site-nav:focus-within { transform: translateY(0); }


/* ===== 05-animationen.css ===== */
/* ==========================================================================
   05-ANIMATIONEN
   --------------------------------------------------------------------------
   Regeln, die diese Datei durchhält:
   • Reveals arbeiten mit clip-path und Verschiebung, NICHT mit reinem
     opacity-Fade. Fades allein sind das Erkennungszeichen von
     Vorlagen-Seiten; ein Vorhang, der aufzieht, wirkt gestaltet.
   • Nichts wackelt dauerhaft. Bewegung hat immer einen Anlass.
   • Alles hier wird von prefers-reduced-motion in 02-base.css abgeschaltet.
   ========================================================================== */


/* ==========================================================================
   SCROLL-REVEALS
   Startzustand hier, Freigabe per [data-reveal="sichtbar"] durch den
   IntersectionObserver in js/reveal.js.
   ========================================================================== */

[data-reveal] {
  --reveal-verzug: 0ms;
  transition:
    opacity var(--d-reveal) var(--e-out) var(--reveal-verzug),
    transform var(--d-reveal) var(--e-out) var(--reveal-verzug),
    clip-path var(--d-reveal) var(--e-out) var(--reveal-verzug);
  will-change: transform, opacity;
}

/* Standard: Vorhang von unten */
[data-reveal="bereit"] {
  opacity: 0;
  transform: translateY(2.5rem);
  clip-path: inset(0 0 100% 0);
}
[data-reveal="sichtbar"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
}

/* Varianten über data-reveal-art */
[data-reveal-art="links"][data-reveal="bereit"] {
  transform: translateX(-3rem);
  clip-path: inset(0 100% 0 0);
}
[data-reveal-art="rechts"][data-reveal="bereit"] {
  transform: translateX(3rem);
  clip-path: inset(0 0 0 100%);
}
[data-reveal-art="vorhang"][data-reveal="bereit"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 100% 0 0);   /* Bild wird freigewischt */
}
[data-reveal-art="skalieren"][data-reveal="bereit"] {
  opacity: 0;
  transform: scale(1.06);
  clip-path: none;
}
[data-reveal-art="skalieren"][data-reveal="sichtbar"] {
  transform: scale(1);
}
/* Nur Verschiebung, kein Clip — für Textabsätze */
[data-reveal-art="sanft"][data-reveal="bereit"] {
  opacity: 0;
  transform: translateY(1.25rem);
  clip-path: none;
}

/* Gestaffelte Kinder: Container bekommt data-reveal-staffel,
   reveal.js setzt --i auf jedem Kind. */
[data-reveal-staffel] > * {
  transition:
    opacity var(--d-slow) var(--e-out),
    transform var(--d-slow) var(--e-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}
[data-reveal-staffel][data-reveal="bereit"] > * {
  opacity: 0;
  transform: translateY(2rem);
}
[data-reveal-staffel][data-reveal="sichtbar"] > * {
  opacity: 1;
  transform: none;
}


/* ==========================================================================
   HEADLINE-ZEILEN-REVEAL
   Jede Zeile sitzt in einem Maskenrahmen und fährt von unten herein.
   Das ist der wirkungsvollste Effekt im ganzen System — sparsam einsetzen,
   nur bei Hero- und Sektionsheadlines.
   Markup:  <h1 class="zeilen"><span><i>Zeile eins</i></span>…</h1>
   ========================================================================== */

.zeilen span {
  display: block;
  overflow: hidden;
}
.zeilen i {
  display: block;
  font-style: inherit;
  transform: translateY(105%);
  transition: transform 1s var(--e-out);
  transition-delay: calc(var(--i, 0) * 110ms);
}
.zeilen[data-reveal="sichtbar"] i,
.ist-geladen .hero .zeilen i { transform: translateY(0); }

/* ACHTUNG, hier lag ein Fehler (gefunden 11.08.2026 bei Brühne):
   Die Regeln oben verstecken jede Zeile mit translateY(105%) und holen sie
   erst zurück, wenn site.js entweder data-reveal="sichtbar" oder die Klasse
   .ist-geladen gesetzt hat. Ist JavaScript deaktiviert oder site.js
   fehlerhaft, bleibt die H1 der Startseite dauerhaft unsichtbar — die Seite
   hat dann sichtbar keine Überschrift.

   Die Klasse "js" wird ganz oben im <head> per Inline-Script gesetzt und
   fehlt ohne JavaScript. Genau daran hängt der Rückfall: Ohne JavaScript
   stehen die Zeilen einfach da, ohne Animation. */
html:not(.js) .zeilen i {
  transform: none;
  transition: none;
}


/* ==========================================================================
   TEXT-LAUFBAND (großes Wortband, z. B. LEISTUNGEN)
   Zwei identische Spuren nebeneinander → nahtlose Schleife.
   ========================================================================== */

.wortband {
  --tempo: 70s;
  position: relative;
  display: flex;
  overflow: hidden;
  padding-block: var(--s-4);
  border-block: var(--b-bold);
  background: var(--c-accent);
  color: var(--c-accent-ink);
  user-select: none;
}
.wortband--ruhig { background: var(--c-paper-warm); color: var(--c-ink); }

.wortband__spur {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--s-6);
  padding-right: var(--s-6);
  white-space: nowrap;
  animation: wortband-lauf var(--tempo) linear infinite;
}
.wortband--rueckwaerts .wortband__spur { animation-direction: reverse; }
/* Läuft durch, auch beim Überfahren — siehe Begründung beim Laufband. */

.wortband__spur > span {
  display: inline-flex;
  align-items: center;
  gap: var(--s-6);
  font-family: var(--f-display);
  font-size: clamp(0.8125rem, 1.15vw, 1.0625rem);
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
/* Trennzeichen zwischen den Begriffen */
.wortband__spur > span::after {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.45;
}

@keyframes wortband-lauf {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}


/* ==========================================================================
   ZÄHLER
   Zahl läuft beim Sichtbarwerden hoch (js/zaehler.js).
   Tabellenziffern verhindern das nervöse Zappeln der Breite.
   ========================================================================== */

[data-zaehler] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}


/* ==========================================================================
   BILD-HOVER: Farbwischer
   Beim Überfahren zieht ein Akzentbalken diagonal über das Bild —
   passende Metapher für einen Malerbetrieb.
   ========================================================================== */

.wischer {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.wischer::after {
  content: "";
  position: absolute;
  inset: -20%;
  z-index: 1;
  background: var(--c-accent);
  mix-blend-mode: multiply;
  transform: translateX(-115%) skewX(-12deg);
  transition: transform var(--d-slow) var(--e-io);
  pointer-events: none;
}
.wischer:hover::after { transform: translateX(115%) skewX(-12deg); }


/* ==========================================================================
   SEITENEINSTIEG
   Kurzer Vorhang beim ersten Laden. Bewusst schnell (450 ms) —
   lange Intros nerven Kunden und kosten Ladezeit-Wahrnehmung.
   Wird entfernt, sobald <html> die Klasse ist-geladen bekommt.
   ========================================================================== */

.einstieg {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: grid;
  place-items: center;
  background: var(--c-ink);
  clip-path: inset(0 0 0 0);
  transition: clip-path 620ms var(--e-io) 120ms;
  pointer-events: none;
}
.ist-geladen .einstieg { clip-path: inset(0 0 100% 0); }

.einstieg__marke {
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-paper);
  opacity: 1;
  transition: opacity 260ms var(--e-out);
}
.ist-geladen .einstieg__marke { opacity: 0; }

/* Ohne JS darf der Vorhang die Seite nicht blockieren */
html:not(.js) .einstieg { display: none; }


/* ==========================================================================
   KLEINE DETAILS
   ========================================================================== */

/* Pulsierender Punkt für "Jetzt erreichbar" — der einzige Dauerloop im
   System, weil er eine Statusinformation trägt. */
.status-punkt {
  display: inline-block;
  width: 8px;
  height: 8px;
  background: var(--c-success);
  animation: status-puls 2.4s var(--e-io) infinite;
}
@keyframes status-puls {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.75); }
}

/* Scroll-Hinweis im Hero */
.scroll-hinweis {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--f-label);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
.scroll-hinweis__linie {
  position: relative;
  width: 2.5rem;
  height: 1.5px;
  background: rgba(246,242,235,0.35);
  overflow: hidden;
}
.scroll-hinweis__linie::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c-accent);
  animation: linie-lauf 2.2s var(--e-io) infinite;
}
@keyframes linie-lauf {
  0%   { transform: translateX(-100%); }
  55%  { transform: translateX(0); }
  100% { transform: translateX(100%); }
}

/* Fortschrittsbalken am oberen Rand (Leseposition) */
.lesefortschritt {
  position: fixed;
  top: 0; left: 0;
  z-index: calc(var(--z-nav) + 1);
  height: 3px;
  width: 100%;
  transform: scaleX(var(--fortschritt, 0));
  transform-origin: left;
  background: var(--c-accent);
  pointer-events: none;
}


/* ===== 06-einwilligung.css ===== */
/* ==========================================================================
   06-EINWILLIGUNG (Cookie-/Karten-Einstellungen)
   --------------------------------------------------------------------------
   Grundhaltung dieses Systems: Die Seiten setzen von sich aus KEINE
   Cookies und laden KEINE Drittanbieter. Fonts liegen lokal, es gibt
   kein Analytics, keine Google-Fonts-CDN, kein YouTube-Embed.

   Damit ist ein aufdringliches Cookie-Banner beim Seitenaufruf weder
   nötig noch erlaubt-relevant — der einzige Drittanbieter ist Google
   Maps, und der wird erst nach ausdrücklichem Klick geladen.

   Deshalb: KEIN Banner beim Einstieg, sondern
   • ein Platzhalter an der Karte (siehe .karte-platzhalter)
   • dieser Einstellungsdialog, erreichbar über den Footer,
     in dem die Entscheidung jederzeit widerrufen werden kann.

   Sobald ein Kunde Analytics oder Pixel will, wird daraus ein echtes
   Consent-Banner — dann greift _system/checklisten/dsgvo.md.
   ========================================================================== */

.einwilligung {
  width: min(38rem, calc(100vw - 2 * var(--gutter)));
  max-height: 85svh;
  padding: 0;
  border: var(--b-heavy);
  background: var(--c-paper);
  color: var(--c-ink);
  box-shadow: 8px 8px 0 var(--c-ink);
  overflow: auto;
}
.einwilligung::backdrop {
  background: rgba(10, 8, 7, 0.72);
  backdrop-filter: blur(2px);
}

.einwilligung__kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-6);
  border-bottom: var(--b-bold);
}
.einwilligung__kopf h2 {
  font-size: var(--t-h3);
  text-transform: uppercase;
  letter-spacing: var(--ls-tight);
}
.einwilligung__kopf p {
  margin: var(--s-3) 0 0;
  font-size: var(--t-small);
  color: var(--c-ink-soft);
}
.einwilligung__zu {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  background: transparent;
  border: var(--b-bold);
  font-size: 1.1rem;
  line-height: 1;
}
.einwilligung__zu:hover { background: var(--c-ink); color: var(--c-paper); }

.einwilligung__koerper { padding: var(--s-6); display: grid; gap: var(--s-5); }

.einwilligung__gruppe {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s-3) var(--s-5);
  align-items: start;
  padding: var(--s-5);
  border: var(--b-thin);
}
.einwilligung__gruppe h3 {
  font-family: var(--f-label);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
.einwilligung__gruppe p {
  grid-column: 1 / -1;
  margin: 0;
  font-size: var(--t-small);
  color: var(--c-ink-soft);
  max-width: none;
}
.einwilligung__gruppe--fest { background: var(--c-paper-warm); }

/* Schalter: eckig, wie alles hier */
.schalter {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: none;
  width: 3.5rem;
  height: 1.75rem;
  padding: 0;
  border: var(--b-bold);
  background: var(--c-paper);
  cursor: pointer;
}
.schalter::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: calc(50% - 3px);
  height: calc(100% - 4px);
  background: var(--c-ink-mute);
  transition: transform var(--d-base) var(--e-out), background-color var(--d-base) var(--e-out);
}
.schalter[aria-checked="true"]::after {
  transform: translateX(calc(100% + 2px));
  background: var(--c-accent);
}
.schalter[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.schalter[aria-disabled="true"]::after {
  transform: translateX(calc(100% + 2px));
  background: var(--c-ink);
}
.schalter__text {
  position: absolute;
  inset: auto 0 -1.5rem 0;
  font-family: var(--f-label);
  font-size: 0.625rem;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-mute);
  text-align: center;
}

.einwilligung__fuss {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  padding: var(--s-6);
  border-top: var(--b-bold);
  background: var(--c-paper-warm);
}
.einwilligung__fuss .btn { flex: 1 1 12rem; }


/* ===== handschrift.css ===== */
/* ==========================================================================
   HANDSCHRIFT: POLITUR
   --------------------------------------------------------------------------
   Kühl, präzise, hell. Diese Handschrift verkauft nicht Kraft, sondern
   Makellosigkeit — der Unterschied zwischen "wir packen an" und "danach
   ist keine Spur mehr davon zu sehen".

   Tiefe entsteht ausschließlich durch Haarlinien und Flächenwechsel.
   Keine Schatten, keine Verläufe: Ein Weichzeichner ist auf einer Seite,
   die Sauberkeit behauptet, ein Widerspruch in sich.

   Passt zu: Gebäudereinigung, Glasreinigung, Fensterbau, Sanitär,
   Laborbedarf, Dentaltechnik, Lackaufbereitung — Betrieben, deren
   Ergebnis daran gemessen wird, dass nichts mehr zu sehen ist.

   Passt NICHT zu: Betrieben, die Wärme oder Wucht verkaufen — Bestatter,
   Bäcker, Abbruch, Gerüstbau.

   Wird als css/handschrift.css ins Projekt kopiert und NACH den Dateien
   01–06, aber VOR brand.css geladen. Kundenspezifische Farben kommen in
   brand.css und überschreiben von hier nur die Farbwerte.
   ========================================================================== */

:root {
  /* Fast gerade, aber nicht scharf. 2px liest sich als geschnitten,
     0px als unfertig, 8px+ als weich. Präzision liegt bei 2. */
  --radius:    2px;
  --radius-sm: 2px;
  --radius-lg: 3px;

  /* Schatten komplett aus. Siehe Kopfkommentar. */
  --sh-weich: none;
  --sh-karte: none;
  --sh-hoch:  none;

  /* Mittel-eng. Genug Luft, dass es sortiert wirkt, zu wenig für den
     Konzern-Weißraum, den jede Agenturseite fährt. */
  --sektion-y: clamp(3.5rem, 6.5vw, 6.5rem);

  --max-w: 78rem;

  /* Kühles Grundthema. Der Baukasten liefert warmes Papier und warmes
     Schwarz — das liest sich gemütlich und arbeitet hier gegen die
     Sache. Blaustichig gesetzt, aber nicht kalt genug für Klinik. */
  --c-ink:        #0E1720;
  --c-ink-soft:   #35434F;
  /* #6B7883 wäre der optisch naheliegende Wert, erreicht auf dem kühlen
     Papier aber nur 4,20:1. Kicker und Meta-Zeilen sind Kleinschrift und
     brauchen 4,5:1 — dieser Ton liefert 5,30:1. */
  --c-ink-mute:   #5B6874;
  --c-paper:      #F4F7F9;
  --c-paper-warm: #E7EEF3;   /* trotz des Namens die kühle Absetzfläche */
  --c-line:       #0E1720;
  --c-line-soft:  #C6D3DC;

  /* Ruhigere Typo als werkstatt: keine gequetschten Zeilen. Was sauber
     ist, drängelt nicht. */
  --lh-tight: 1.0;
  --ls-mega:  -0.03em;
}

/* Karten: Fläche mit Haarlinie statt fettem Rahmen. Beim Überfahren
   färbt sich nur die Linie und ein Streifen an der Oberkante — die
   Karte selbst bewegt sich nicht. */
.kachel {
  border: 1px solid var(--c-line-soft);
  background: #FFFFFF;
  --kachel-grund: #FFFFFF;
  position: relative;
  transition: border-color var(--d-base) var(--e-out);
}
.kachel::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 2px;
  background: var(--c-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-base) var(--e-out);
}
.kachel:hover,
.kachel:focus-visible {
  transform: none;
  box-shadow: none;
  border-color: var(--c-accent);
}
.kachel:hover::before,
.kachel:focus-visible::before { transform: scaleX(1); }

/* Schaltflächen: flach, mit Rahmen. Kein Versatzschatten — der wäre
   der Aufkleber-Effekt, den werkstatt bewusst will und politur nicht. */
.btn {
  border-width: 1.5px;
  box-shadow: none;
  transition: background-color var(--d-fast) var(--e-out),
              color var(--d-fast) var(--e-out),
              border-color var(--d-fast) var(--e-out);
}
.btn:hover,
.btn:focus-visible { transform: none; box-shadow: none; }

/* Kicker als feine Versalzeile mit nachlaufender Linie — das Gegenstück
   zum vorangestellten Balken der werkstatt. */
.kicker {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  color: var(--c-ink-mute);
}
.kicker::after {
  content: "";
  flex: 1 1 auto;
  block-size: 1px;
  background: var(--c-line-soft);
  max-inline-size: 8rem;
}

/* Sektionswechsel als Haarlinie, nicht als harte Kante. */
.sektion--warm { border-block: 1px solid var(--c-line-soft); }

/* Bilder: Haarlinie statt Rahmen, minimal gerundet wie alles andere. */
.wischer img,
.galerie__figur img {
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius);
}

/* Der Footer bringt eigene, hart gesetzte Farben mit (warmes Schwarz auf
   warmem Weiß). Das ist für die übrigen Handschriften richtig und hier
   falsch: ein brauner Streifen unter einer kühl gesetzten Seite fällt
   sofort auf. */
.site-footer {
  --fuss-grund: #0E1720;
  --fuss-text:  #F4F7F9;
  --c-ink:      #F4F7F9;
  --c-line:     #F4F7F9;
  --c-line-soft: rgba(244, 247, 249, 0.16);
  --c-ink-mute: #8496A4;
}

/* Dunkle Sektionen bleiben kühl statt warm umzuschlagen. */
.ist-dunkel {
  --c-ink:        #F4F7F9;
  --c-ink-soft:   #C0CDD7;
  --c-ink-mute:   #8496A4;
  --c-paper:      #0E1720;
  --c-paper-warm: #16222E;
  --c-line:       #F4F7F9;
  --c-line-soft:  #2C3B48;
}
.ist-dunkel .kachel {
  background: transparent;
  --kachel-grund: transparent;
}


/* ===== brand.css ===== */
/* ==========================================================================
   BRAND — ZIA Gebäude & Glasreinigung
   --------------------------------------------------------------------------
   Reihenfolge im <head>:
   01 → 02 → 03 → 04 → 05 → 06 → handschrift.css (politur) → brand.css

   Arbeitsteilung:
   • handschrift.css  Kantenform, Schatten, Dichte, Breite, kühles Papier
   • brand.css        NUR was diesen Betrieb ausmacht: Farben, Schriften
                      und die neu gebauten Elemente

   Alle Entscheidungen sind in SEELE.md begründet.
   ========================================================================== */

:root {

  /* === PFLICHT 1 — Markenfarben ==========================================
     Herkunft: Logo-Blau, gemessen mit ImageMagick = #007CD6.

     Dieses Blau erreicht auf Weiß nur 4,33:1 und ist damit für Fließtext
     NICHT zulässig. Es wird deshalb ausschließlich als Fläche und Grafik
     verwendet (--c-accent-2). Für alles, was Text trägt, steht die
     abgedunkelte Fassung.

     Gemessene Werte:
       #0067B4 auf #F4F7F9  = 5,7:1  ✓ Fließtext
       #FFFFFF auf #0067B4  = 5,9:1  ✓ Text auf blauer Fläche */
  --c-accent:      #0067B4;
  --c-accent-ink:  #FFFFFF;
  --c-accent-deep: #004E88;
  --c-accent-2:    #007CD6;   /* Logo-Original — nur Flächen und Grafik */

  /* === PFLICHT 2 — Papierton =============================================
     Entschieden: kühl statt des warmen Baukastentons. Ein Reinigungs-
     betrieb, dessen Seite auf cremefarbenem Papier liegt, widerspricht
     seiner eigenen Aussage. Die Werte kommen aus handschrift.css
     (politur) und werden hier bestätigt, nicht verändert. */
  --c-paper:      #F4F7F9;
  --c-paper-warm: #E7EEF3;

  /* === PFLICHT 3 — Schriften =============================================
     Chivo, eine Familie für Display und Text. Begründung in SEELE.md,
     Punkt 4: geschlossen statt kontrastreich — ein Betrieb, eine Stimme.
     Keine der acht Branchenschriften aus dem Marktscan.

     Liegt lokal in fonts/. NIE über die Google-Fonts-CDN einbinden. */
  --f-display: "Kunde Display", "Chivo", system-ui, sans-serif;
  --f-text:    "Kunde Text", "Chivo", system-ui, sans-serif;
}

/* Eine einzige Datei für beide Rollen: Chivo ist eine Variable Font mit
   der Achse wght 100–900. Display und Text greifen auf dieselben 33 KB
   zu, es wird also nichts doppelt geladen.

   Liegt lokal (OFL erlaubt das ausdrücklich, nur der CDN-Aufruf zur
   Laufzeit wäre das Problem). Der Zeichensatz ist Googles latin-Subset:
   deckt Umlaute und ß ab. */
@font-face {
  font-family: "Kunde Display";
  src: url("../fonts/chivo-var.woff2") format("woff2-variations"),
       url("../fonts/chivo-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Kunde Text";
  src: url("../fonts/chivo-var.woff2") format("woff2-variations"),
       url("../fonts/chivo-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}


/* ==========================================================================
   HERO — Abweichung vom Baukasten

   Der Baukasten-Hero legt Videos vollflächig hinter den Text. Das
   einzige Material des Betriebs ist aber ein Hochkant-Handyvideo
   (720 × 1280): vollflächig wären auf Desktop nur 23 % der Bildhöhe
   sichtbar, 2,7-fach vergrößert. Deshalb steht das Video hier als
   Hochformat neben dem Text.
   ========================================================================== */

.hero--zia {
  align-items: center;
  /* Nicht die volle Bildschirmhöhe: der Beleg direkt darunter soll
     angeschnitten sichtbar sein und zum Weiterlesen ziehen. */
  min-height: auto;
  padding-block: clamp(3rem, 7vw, 6rem);
  background: var(--c-ink);
}

.hero--zia__raster {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

@media (min-width: 60rem) {
  .hero--zia__raster {
    /* 7/5 statt 6/6 — asymmetrisch wirkt komponiert statt geteilt. */
    grid-template-columns: 1.35fr 1fr;
  }
}

.hero--zia__wort { min-width: 0; }

/* Der Titel steht hier in einer Spalte, nicht über die volle Breite.
   Mit dem Baukastenwert (--t-mega, bis 7,5rem) bricht "Sauber ist erst,"
   in zwei Zeilen um — aus drei gesetzten Zeilen werden fünf, und der
   Hero schiebt alles darunter aus dem Bild. */
.hero--zia .hero__titel {
  font-size: clamp(2.25rem, 4.6vw, 4rem);
  text-wrap: balance;
}

/* Auszeichnung im Titel: Akzentlinie statt Farbwechsel. "weiß" in Blau
   zu setzen wäre ein Widerspruch zum Wort selbst. */
.hero--zia .hero__titel em {
  font-style: normal;
  color: inherit;
  box-shadow: inset 0 -0.14em 0 var(--c-accent-2);
}

/* Der O-Ton des Betriebs. Steht bewusst UNTER den Schaltflächen und
   nicht als Überschrift: er ist eine Unterschrift, kein Werbeslogan.
   Kleinschreibung von "sauber" ist original und bleibt. */
.hero--zia__oton {
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(244, 247, 249, 0.22);
  font-family: var(--f-display);
  font-size: var(--t-h4);
  letter-spacing: 0.02em;
  color: rgba(244, 247, 249, 0.9);
}

.hero--zia__film {
  margin: 0;
  justify-self: center;
  max-width: 22rem;
  width: 100%;
}
.hero--zia__film video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  border-radius: var(--radius);
  /* Feine helle Kante statt Schatten — politur kennt keine Schatten. */
  outline: 1px solid rgba(244, 247, 249, 0.25);
  outline-offset: -1px;
}
.hero--zia__film figcaption {
  margin-top: var(--s-4);
  font-size: var(--t-small);
  line-height: 1.45;
  color: rgba(244, 247, 249, 0.6);
  max-width: 30ch;
}

/* Unter 60rem steht das Video unter dem Text und läuft über die volle
   Breite — bis an beide Bildschirmkanten, ohne Seitenrand. Ein
   Hochkantvideo mit Rand links und rechts sieht auf dem Handy nach
   Fehler aus; formatfüllend wirkt es wie das, was es ist: eine
   Aufnahme vom Telefon.

   Der negative Rand hebt den Seitenrand von .wrap wieder auf. 100vw
   statt 100% erzwingt die volle Fensterbreite auch dann, wenn der
   Rasterplatz schmaler ist. */
@media (max-width: 59.999rem) {
  .hero--zia__raster { grid-template-areas: "wort" "film"; }
  .hero--zia__wort { grid-area: wort; }
  .hero--zia__film {
    grid-area: film;
    max-width: none;
    width: 100vw;
    margin-inline: calc(50% - 50vw);
  }
  .hero--zia__film video {
    border-radius: 0;
    outline: none;
    /* Nicht die volle Videohöhe: hochkant 9/16 füllt sonst mehr als
       einen Bildschirm und drängt alles Folgende weg. */
    max-height: 70svh;
  }
}


/* ==========================================================================
   BELEG-STREIFEN — die für diesen Betrieb neu gebaute Komponente
   (Richtlinie 10)

   Vier Standbilder eines einzigen Arbeitsgangs, verbunden durch eine
   Zeitachse. Bewusst KEIN .vergleich-Regler: der zeigt zwei Zustände,
   dieser Streifen zeigt den Ablauf — also die Arbeit statt nur das
   Ergebnis. Der Regler steht außerdem auf der Slop-Liste.

   Der Versatz jeder zweiten Kachel ist Absicht: perfekte Ausrichtung
   auf allen Achsen ist laut Richtlinie das stärkste KI-Signal.
   ========================================================================== */

.beleg-streifen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--s-5);
  margin: var(--s-8) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: beleg;
}

.beleg-streifen__schritt { margin: 0; }
.beleg-streifen__schritt figure { margin: 0; }

/* Jede zweite Kachel sitzt tiefer. Auf schmalen Bildschirmen aufgehoben,
   dort stehen die Bilder ohnehin untereinander. */
@media (min-width: 48rem) {
  .beleg-streifen__schritt:nth-child(even) { margin-top: var(--s-6); }
}

.beleg-streifen img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius);
}

.beleg-streifen figcaption {
  display: grid;
  gap: var(--s-1);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  /* Die Zeitachse: eine Linie über jeder Beschriftung, dazu der Punkt
     unten. Zusammen ergeben sie den Streifen. */
  border-top: 1px solid var(--c-line-soft);
  position: relative;
}
.beleg-streifen figcaption::before {
  content: "";
  position: absolute;
  inset-block-start: -0.25rem;
  inset-inline-start: 0;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--c-accent);
}
.beleg-streifen figcaption b {
  font-family: var(--f-display);
  font-size: var(--t-h4);
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}
.beleg-streifen figcaption span {
  font-size: var(--t-small);
  line-height: 1.4;
  color: var(--c-ink-soft);
}

.beleg-streifen__fuss {
  margin-top: var(--s-7);
  max-width: 46ch;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--c-ink-soft);
  border-left: 2px solid var(--c-accent);
  padding-left: var(--s-5);
}


/* ==========================================================================
   LEISTUNGSLISTE

   Ersetzt das Kachelraster. Sechs gleich hohe Karten sind ein
   Slop-Element; eine nummerierte Liste mit Haarlinien passt zur
   Handschrift politur und kommt ohne Baukasten-Komponente aus.
   ========================================================================== */

.leistungsliste {
  margin: var(--s-8) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--c-line-soft);
}

.leistungsliste__zeile {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-2) var(--s-5);
  align-items: start;
  padding: var(--s-5) 0;
  border-bottom: 1px solid var(--c-line-soft);
}

@media (min-width: 52rem) {
  .leistungsliste__zeile {
    /* 20rem statt 16rem: "Unterhaltsreinigung" und
       "Treppenhausreinigung" sind einzelne Wörter, die nicht umbrechen
       können. Bei 16rem liefen sie in die Textspalte hinein. */
    grid-template-columns: 3.5rem 20rem 1fr;
    gap: var(--s-6);
    align-items: baseline;
  }
}

.leistungsliste__nr {
  font-family: var(--f-display);
  font-size: var(--t-small);
  letter-spacing: 0.12em;
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}
.leistungsliste__titel {
  margin: 0;
  font-size: clamp(1.2rem, 1.7vw, 1.55rem);
  line-height: 1.15;
  hyphens: auto;
  overflow-wrap: break-word;
}
.leistungsliste__text {
  margin: 0;
  color: var(--c-ink-soft);
  max-width: 52ch;
  /* Schmal ist die Zeile zweispaltig: Nummer und Titel nebeneinander,
     der Beschreibungstext darunter über die volle Breite. Ohne diese
     Zeile rutscht der Text in die Nummernspalte und steht dort auf
     halber Breite. */
  grid-column: 1 / -1;
}
@media (min-width: 52rem) {
  .leistungsliste__text { grid-column: auto; }
}


/* ==========================================================================
   OBJEKTE — die blaue Vollflächen-Sektion

   In Patricks Referenz trug diese Fläche vier Icons mit unbelegten
   Zahlen. Hier trägt sie die Objektarten, rein typografisch: für Objekte
   gibt es kein eigenes Bildmaterial, und Stockfotos fremder Gebäude
   neben echten Arbeitsbildern entwerten das echte Material.
   ========================================================================== */

.objekte {
  background: var(--c-accent);
  color: var(--c-accent-ink);
  border-block: 1px solid var(--c-accent-deep);
}
.objekte__kopf { max-width: 46ch; }
.objekte__kopf h2 { color: var(--c-accent-ink); margin-bottom: var(--s-4); }
.objekte__kopf p {
  color: rgba(255, 255, 255, 0.82);
  font-size: var(--t-lead);
  line-height: 1.5;
}

.objekte__liste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0;
  margin: var(--s-8) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(255, 255, 255, 0.35);
}
.objekte__liste li {
  display: grid;
  gap: var(--s-2);
  align-content: start;
  padding: var(--s-6) var(--s-5) var(--s-6) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.35);
}
/* Senkrechte Trenner nur zwischen den Spalten, nicht am Rand. */
@media (min-width: 52rem) {
  .objekte__liste li + li {
    border-left: 1px solid rgba(255, 255, 255, 0.35);
    padding-left: var(--s-5);
  }
}
.objekte__liste b {
  font-family: var(--f-display);
  font-size: var(--t-h3);
  line-height: 1.1;
}
.objekte__liste span {
  font-size: var(--t-small);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.82);
}


/* ==========================================================================
   BETRIEB — Zahlenblock

   Statt der Baukasten-.fakten mit Zähleranimation. Seit dem Fragebogen
   (14.09.2026) stehen hier keine Zahlen mehr, sondern drei bestätigte
   Angaben — Sitz, Einsatzgebiet, Kunden.
   ========================================================================== */

.betrieb-zahlen {
  display: grid;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--c-line-soft);
}
.betrieb-zahlen > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-5) 0;
  border-bottom: 1px solid var(--c-line-soft);
}
.betrieb-zahlen dt {
  font-size: var(--t-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-ink-mute);
}
.betrieb-zahlen dd {
  margin: 0;
  font-family: var(--f-display);
  font-size: var(--t-h2);
  line-height: 1;
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   ANFRAGE-WEGE
   ========================================================================== */

.anfrage-wege { display: grid; gap: var(--s-4); }

.anfrage-weg {
  display: grid;
  gap: var(--s-1);
  padding: var(--s-5);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--d-base) var(--e-out),
              background-color var(--d-base) var(--e-out);
}
.anfrage-weg:hover,
.anfrage-weg:focus-visible {
  border-color: var(--c-accent);
  background: rgba(0, 103, 180, 0.08);
}
.anfrage-weg b {
  font-family: var(--f-display);
  font-size: var(--t-h3);
  line-height: 1.1;
}
.anfrage-weg span {
  font-size: var(--t-small);
  color: var(--c-ink-mute);
}


/* ==========================================================================
   WHATSAPP-KNOPF

   Fest am unteren Rand, auf jeder Seite. Reiner Link auf wa.me — kein
   Skript, kein Cookie, keine Verbindung zu Meta, bevor der Besucher
   tippt. Das ist der Grund, warum hier kein fertiges WhatsApp-Widget
   eingebunden ist: die laden beim Seitenaufruf mit.

   Auf Mobil nur das Zeichen, damit der Knopf keine Inhalte verdeckt.
   ========================================================================== */

.wa-knopf {
  position: fixed;
  inset-block-end: clamp(1rem, 3vw, 1.75rem);
  inset-inline-end: clamp(1rem, 3vw, 1.75rem);
  z-index: var(--z-sticky);

  /* Reiner Kreis mit dem Zeichen, auf jeder Breite. Die Beschriftung
     bleibt im Markup und ist für Screenreader da — sie wird nur optisch
     ausgeblendet, nicht per display:none entfernt. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 3.5rem;
  block-size: 3.5rem;
  padding: 0;
  border-radius: 50%;

  /* WhatsApp-Grün, deutlich abgedunkelt. Der Markenton #25D366 und auch
     das dunklere #128C7E tragen weiße Schrift nur mit 2,0:1 bzw. 4,1:1 —
     beides zu wenig für eine 17-px-Beschriftung, die kein Großtext ist.
     Dieser Ton liefert 5,07:1 und bleibt als WhatsApp erkennbar. */
  background: #157F3F;
  color: #FFFFFF;
  text-decoration: none;
  font-family: var(--f-display);
  font-size: 1.0625rem;
  line-height: 1;

  transition: background-color var(--d-fast) var(--e-out),
              transform var(--d-fast) var(--e-out);
}
.wa-knopf:hover,
.wa-knopf:focus-visible {
  background: #0F6431;
  color: #FFFFFF;
  transform: translateY(-2px);
}
.wa-knopf__zeichen {
  width: 1.85rem;
  height: 1.85rem;
  flex: none;
}
.wa-knopf__text {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Der Baukasten setzt "zum Anfang" ebenfalls unten rechts. Seit der
   WhatsApp-Knopf dort sitzt, würden sich beide überlagern — also rückt
   er eine Knopfhöhe nach oben und teilt sich die Spalte mit ihm. */
.zum-anfang {
  /* Dieselbe Eigenschaft wie im Baukasten (bottom/right, nicht die
     logischen Varianten), sonst gewinnt je nach Reihenfolge die falsche. */
  right: clamp(1rem, 3vw, 1.75rem);
  bottom: calc(clamp(1rem, 3vw, 1.75rem) + 3.5rem + var(--s-3));
  /* Auf die Kreisform des WhatsApp-Knopfes abgestimmt. */
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
}


/* ==========================================================================
   NAVIGATION — Aktiv-Markierung beim Onepager

   Der Baukasten markiert die aktive Seite mit aria-current="page". Hier
   wechselt die Seite nicht, es wechselt der Abschnitt — js/onepager.js
   setzt dafür aria-current="true" (das aktuelle Element). Die
   Unterstrich-Regel muss beide Werte kennen, sonst bleibt der Scrollspy
   unsichtbar.
   ========================================================================== */

.nav-liste a[aria-current="true"]::after { transform: scaleX(1); }
.nav-liste a[aria-current="true"] { font-weight: 700; }
.nav-overlay__liste a[aria-current="true"] { color: var(--c-accent); }


/* ==========================================================================
   FOOTER-LOGO

   Das Logo ist ein freigestelltes Rundzeichen mit blauer Zeichnung. Auf
   dem dunklen Footer verschwindet die Zeichnung fast. Es bekommt deshalb
   eine helle Scheibe als Untergrund, statt es aufzuhellen — das Logo
   selbst bleibt unverändert, wie es der Betrieb verwendet.
   ========================================================================== */

.footer-marke img {
  background: #FFFFFF;
  border-radius: 50%;
  padding: 3px;
}


/* ==========================================================================
   ENTWURFS-HINWEIS auf Impressum und Datenschutz

   Dem Betrieb fehlen Anschrift, Rechtsform und Kammer. Diese Angaben zu
   erfinden wäre in einem Impressum besonders heikel, sie wegzulassen
   sieht nach Fehler aus. Also stehen sie sichtbar als offene Punkte da,
   und dieser Kasten erklärt einmal, warum.

   Fällt beim Livegang ersatzlos weg — dann sind die Angaben vollständig.
   ========================================================================== */

.entwurf-hinweis {
  margin: var(--s-7) 0 0;
  padding: var(--s-5);
  border: 1px solid var(--c-accent);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: rgba(0, 103, 180, 0.06);
  font-size: var(--t-small);
  line-height: 1.55;
  max-width: 62ch;
}

/* Angaben statt Zahlen: „Privat & Gewerbe" in Überschriftengröße bricht
   neben der Beschriftung um. Eine Stufe kleiner hält jede Zeile einzeilig,
   die Akzentfarbe bleibt als Anker. */
.betrieb-zahlen--angaben dd {
  font-size: var(--t-h3);
  text-align: right;
}

/* --------------------------------------------------------------------------
   OBJEKTE — sechs statt vier Einträge (Fragebogen 14.09.2026)
   Das auto-fit-Raster war für vier Objektarten gebaut. Mit sechs setzte es
   fünf nebeneinander: „Treppenhäuser" lief in „Neubauten", „Privathaushalte"
   über den rechten Rand, und „Küchen" landete allein in einer zweiten Reihe
   — mit einem Trenner links, weil `li + li` jede Folgezeile erfasst.

   Jetzt feste Spaltenzahl je Breite, und die senkrechten Trenner nur dort,
   wo tatsächlich eine Spalte an eine andere grenzt.
   -------------------------------------------------------------------------- */
.objekte__liste {
  grid-template-columns: 1fr;
}
.objekte__liste b {
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
}
@media (min-width: 40rem) {
  .objekte__liste { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 52rem) {
  .objekte__liste { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Die alte Regel setzte den Trenner an jedes Folgeelement */
  .objekte__liste li + li {
    border-left: none;
    padding-left: 0;
  }
  .objekte__liste li:not(:nth-child(3n + 1)) {
    border-left: 1px solid rgba(255, 255, 255, 0.35);
    padding-left: var(--s-5);
  }
}
@media (min-width: 40rem) and (max-width: 51.99rem) {
  .objekte__liste li:nth-child(2n) {
    border-left: 1px solid rgba(255, 255, 255, 0.35);
    padding-left: var(--s-5);
  }
}
