/* =========================================================
   Susanbau Service — Stylesheet
   Farbwelt „Putz & Schwarz": das Weiß der frisch verputzten
   Fassade als Grundfläche, Schwarz hinter den Bildern und in
   den dunklen Abschnitten, Terrakotta nur noch als Akzent.
   Die Fotos und Filme tragen die Seite — das Design hält sich
   bewusst zurück.
   ========================================================= */

/* ---------------------------------------------------------
   Schriften — bewusst LOKAL eingebunden (nicht über das
   Google-Fonts-CDN). So wird beim Seitenaufruf keine IP-
   Adresse der Besucher an Google übertragen (DSGVO, vgl.
   LG München I, 20.01.2022 – 3 O 17493/20).
   Archivo & Inter stehen unter der SIL Open Font License 1.1.
   --------------------------------------------------------- */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 100%;
  font-display: swap;
  src: url("../fonts/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Flächen.
     Die Werte sind von den Fotos abgenommen: --paper ist der Ton des
     frischen Putzes an der Fassade, --ink das Anthrazit der gestrichenen
     Dachuntersicht. Beides kühl — sonst beißt sich die Seite mit dem
     blauen Himmel und dem grauen Gerüst auf den Bildern. */
  --paper:   #f4f3f0;   /* Putzweiß, Grundfläche */
  --paper-2: #e8e7e3;   /* zweite Abschnittsfläche */
  --white:   #ffffff;
  --ink:     #17181b;   /* Text und dunkle Abschnitte */
  --ink-2:   #202226;
  --ink-3:   #2b2e33;
  --schwarz: #0d0e10;   /* hinter Video — dunkler als --ink, damit das
                           Bild und nicht die Fläche die Aufmerksamkeit hat */

  /* Akzent. Terrakotta trägt jetzt nur noch den Hauptbutton, ein Wort in
     der Überschrift und das Logo. Alles andere überlassen wir den Bildern.
     --clay ist die Markenfarbe; für weiße Schrift darauf ist sie eine Spur
     zu hell (4,2:1), dafür gibt es --clay-cta mit 5,4:1. */
  --clay:      #c85a2b;
  --clay-cta:  #b34a20;
  --clay-dark: #a8461f;   /* Hover + Textlinks auf hellem Grund (5,2:1) */
  --clay-soft: #f1e2da;   /* getönte Fläche, z. B. Icon-Kacheln */
  --clay-lite: #e8875c;   /* Akzentschrift auf Anthrazit (6,2:1) */

  --line:      #dedcd7;
  --line-2:    #cfccc6;
  --line-dark: rgba(255, 255, 255, .14);
  --muted:     #5c5e63;   /* auf --paper 5,8:1 */
  --muted-dark:#a9acb2;   /* auf --ink 7,8:1 */

  --wa:      #1f9d55;
  --wa-cta:  #157f43;     /* dunkler, damit weiße Schrift 5,1:1 erreicht */

  --font-head: "Archivo", "Segoe UI", Arial, sans-serif;
  --font-body: "Inter", "Segoe UI", Arial, sans-serif;

  /* Größer und enger als vorher. Die Seite lebt von wenigen großen
     Aussagen über ganzflächigen Bildern, nicht von viel Text. */
  --h1:   clamp(2.6rem, 1.1rem + 5.2vw, 5.2rem);
  --h2:   clamp(1.9rem, 1.2rem + 2.4vw, 3.1rem);
  --h3:   clamp(1.12rem, 1rem + .45vw, 1.35rem);
  --lead: clamp(1.05rem, .95rem + .4vw, 1.25rem);

  --shell: 1200px;
  --pad-x: clamp(1.1rem, .5rem + 2.4vw, 2.75rem);
  --sec-y: clamp(3.5rem, 2rem + 5.5vw, 6.5rem);
  --r:     10px;
  --r-sm:  6px;

  --shadow-s: 0 1px 2px rgba(13, 14, 16, .05), 0 4px 14px rgba(13, 14, 16, .05);
  --shadow-m: 0 2px 6px rgba(13, 14, 16, .06), 0 18px 40px rgba(13, 14, 16, .10);
  --shadow-l: 0 30px 70px rgba(13, 14, 16, .18);

  /* Die Putzkörnung im Hintergrund ist weg. Sie war der Ersatz für echte
     Struktur, solange es keine Fotos gab — jetzt liefert die Wand selbst
     die Struktur, und zwei Körnungen übereinander sehen schmutzig aus. */
  --grain: none;

  /* Auf den schwarzen Flächen bleibt ein Hauch Rauschen, aber nicht als
     Deko: Große dunkle Verläufe über dem Video zeigen sonst sichtbare
     Streifen, weil 8 Bit pro Kanal dafür zu grob sind. Das Rauschen bricht
     sie auf. feColorMatrix nimmt ihm die Farbe, sonst schimmert es bunt. */
  --grain-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background-color: var(--paper);
  background-image: var(--grain);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; height: auto; }
a   { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -.022em;
  margin: 0 0 .55em;
  text-wrap: balance;
}
h1 { font-size: var(--h1); }
h2 { font-size: var(--h2); }
h3 { font-size: var(--h3); font-weight: 700; letter-spacing: -.01em; line-height: 1.28; }
p  { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

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

:focus-visible {
  outline: 3px solid var(--clay);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--ink);
  color: #fff;
  padding: .8rem 1.2rem;
  font-weight: 600;
}
.skip-link:focus { left: 0; }

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

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}
.shell--narrow { max-width: 860px; }

.ico { width: 1.25em; height: 1.25em; fill: currentColor; flex: none; }

/* ---------------------------------------------------------
   Buttons — kantig gerundet, nie Pillenform
   --------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .78rem 1.35rem;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: .96rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .16s ease, color .16s ease, border-color .16s ease, transform .16s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: none; }

.btn--clay { background: var(--clay-cta); color: #fff; }
.btn--clay:hover { background: var(--clay-dark); }

.btn--ink { background: var(--ink); color: #fff; }
.btn--ink:hover { background: var(--ink-2); }

.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn--ghost:hover { background: var(--white); border-color: var(--ink); }

.btn--wa { background: var(--wa-cta); color: #fff; }
.btn--wa:hover { background: #106635; }

.btn--light { background: var(--white); color: var(--ink); }
.btn--light:hover { background: var(--paper-2); }

.btn--outline-light { background: transparent; color: #fff; border-color: var(--line-dark); }
.btn--outline-light:hover { background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .4); }

.btn--lg { padding: 1rem 1.7rem; font-size: 1.02rem; }
.btn--block { width: 100%; }

/* ---------------------------------------------------------
   Kopfbereich
   --------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, box-shadow .2s ease;
}
/* Hintergrund und Unschärfe liegen auf einer eigenen Ebene statt auf der
   Kopfleiste selbst: backdrop-filter macht ein Element zum Bezugsrahmen für
   position: fixed. Das Handy-Menü hing sonst an der Kopfleiste statt am
   Bildschirm, deckte Logo und Schließen-X zu und ließ sich nicht mehr
   schließen (Bilal, 14.09.2026). */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(244, 243, 240, .92);
  backdrop-filter: saturate(1.4) blur(10px);
}
.site-header.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: var(--shadow-s);
}
.site-header__in {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 74px;
}

.brand { display: inline-flex; align-items: center; text-decoration: none; }
.brand__mark { height: 44px; width: auto; display: block; }

.nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: clamp(.5rem, 1.4vw, 1.4rem);
}
.nav a {
  position: relative;
  text-decoration: none;
  font-weight: 600;
  font-size: .95rem;
  padding: .4rem .1rem;
  color: var(--ink);
}
.nav a:not(.nav__cta)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: .05rem;
  height: 2px;
  background: var(--clay);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .18s ease;
}
.nav a:not(.nav__cta):hover::after,
.nav a.is-active::after { transform: scaleX(1); }
.nav a.is-active { color: var(--clay-dark); }
/* Bewusst .nav a.nav__cta und nicht nur .nav__cta: .nav a (Element + Klasse)
   wiegt schwerer als .btn und gab dem Knopf sonst Innenabstand, Gewicht und
   Größe der Textlinks — links und rechts 1,6 px, die Schrift stieß an den
   Rand. Feste Höhe mit line-height 1, damit er auf ganzen Pixeln sitzt.
   Die Farbe steht aus demselben Grund hier: In der hellen Kopfleiste nach
   dem Scrollen bekam er sonst die dunkle Linkfarbe, schwarz auf Terrakotta. */
.nav a.nav__cta {
  color: #fff;
  margin-left: .5rem;
  min-height: 42px;
  padding: 0 1.15rem;
  font-weight: 700;
  font-size: .92rem;
  line-height: 1;
}

.burger {
  display: none;
  margin-left: auto;
  width: 46px;
  height: 46px;
  background: transparent;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  padding: 0;
}
.burger span {
  display: block;
  width: 22px;
  height: 2px;
  margin: 4px auto;
  background: var(--ink);
  transition: transform .2s ease, opacity .2s ease;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 940px) {
  .burger { display: block; }
  .nav {
    position: fixed;
    inset: 0 0 auto 0;
    margin: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    /* Beginnt unter der Kopfleiste; main.js misst beim Öffnen, wo sie endet. */
    padding: calc(var(--kopf-unten, 4.7rem) + .8rem) var(--pad-x) 2rem;
    height: 100dvh;
    overflow-y: auto;
    transform: translateY(-101%);
    /* visibility wird BEWUSST nicht mitanimiert. Hinge der geschlossene
       Zustand allein am Transform, würde das Menü die ganze Seite bedecken,
       sobald die Transition nicht durchläuft (gedrosselter Hintergrund-Tab,
       unterbrochenes Rendern). Außerdem nimmt visibility:hidden die Links
       aus der Tab-Reihenfolge — sonst tabbt man am Handy durch ein
       unsichtbares Menü. */
    visibility: hidden;
    transition: transform .25s ease;
    z-index: 55;
  }
  .nav.is-open { transform: none; visibility: visible; }
  /* Logo und Schließen-X liegen über dem Menü — sonst deckt das Menü sie zu
     und nichts lässt sich mehr antippen. */
  .brand,
  .burger { position: relative; z-index: 56; }
  .nav a {
    font-family: var(--font-head);
    font-size: 1.35rem;
    font-weight: 700;
    padding: .95rem 0;
    border-bottom: 1px solid var(--line);
  }
  .nav a::after { display: none; }
  /* Rahmen ringsum durchsichtig statt unten weg — sonst ist der Knopf oben
     einen Pixel dicker als unten und die Schrift sitzt schief. */
  .nav a.nav__cta {
    margin: 1.4rem 0 0;
    min-height: 58px;
    padding: 0 1.35rem;
    font-size: 1.35rem;
    border-bottom: 1px solid transparent;
    justify-content: center;
  }
  body.nav-open { overflow: hidden; }
}

/* ---------------------------------------------------------
   Hero — randloses Video

   Das Video liegt ganzflächig hinter dem Text. Damit es bis unter die
   Kopfleiste durchläuft, zieht sich der Hero um deren Höhe nach oben und
   schiebt seinen Inhalt um denselben Betrag wieder herunter. --kopf-h
   misst main.js nach dem Laden; der Wert hier ist nur die Schätzung für
   den Fall, dass kein JavaScript läuft — dann sitzt der Text ein paar
   Pixel anders, mehr passiert nicht.

   Die Klasse .hat-hero steht nur auf der Startseite am <body>. Impressum
   und Datenschutz haben kein Video und behalten ihre helle Kopfleiste.
   --------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: 100vh;
  /* svh statt vh: Auf dem iPhone wächst und schrumpft vh, sobald die
     Adressleiste ein- oder ausfährt. Der Hero würde bei jedem Scrollen
     um 60 Pixel springen. */
  min-height: 100svh;
  margin-top: calc(-1 * var(--kopf-h, 75px));
  padding-top: calc(var(--kopf-h, 75px) + 2rem);
  padding-bottom: clamp(2.5rem, 1rem + 5vw, 5.5rem);
  background: var(--schwarz);
  color: #fff;
  overflow: hidden;
}

.hero__buehne {
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--schwarz);
}
.hero__standbild,
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Das Video liegt über dem Standbild und wird eingeblendet, sobald es
   wirklich läuft. Sein erstes Bild ist dasselbe Bild, deshalb sieht man
   keinen Wechsel — nur, dass sich plötzlich etwas bewegt. Lädt es nie,
   bleibt das Standbild stehen und niemand merkt etwas. */
.hero__video { opacity: 0; transition: opacity .9s ease; }
.hero__video.is-da { opacity: 1; }

/* Zwei Verläufe übereinander machen die Schrift lesbar, ohne das Bild
   zuzudecken:

   - von unten nach oben, damit Überschrift und Knöpfe stehen, und oben
     noch einmal etwas, sonst verschwindet die Kopfleiste im hellen Himmel;
   - von links nach rechts, weil der Text links steht. Ohne diesen zweiten
     Verlauf müsste der erste viel kräftiger sein, und dann wäre auch die
     rechte Bildhälfte grau — genau die, die das Haus zeigt.

   Das Rauschen darüber verhindert die Streifen, die große dunkle Verläufe
   auf 8-Bit-Bildschirmen sonst zeigen. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    var(--grain-dark),
    linear-gradient(to right,
      rgba(13, 14, 16, .62) 0%,
      rgba(13, 14, 16, .34) 34%,
      rgba(13, 14, 16, 0) 64%),
    linear-gradient(to top,
      rgba(13, 14, 16, .92) 0%,
      rgba(13, 14, 16, .70) 24%,
      rgba(13, 14, 16, .34) 52%,
      rgba(13, 14, 16, .16) 74%,
      rgba(13, 14, 16, .50) 100%);
}

.hero__in { position: relative; width: 100%; }
.hero__text { max-width: 42rem; }
.hero h1 { color: #fff; margin-bottom: .38em; }
.hero h1 .hl { color: var(--clay-lite); }
.hero .lead {
  color: rgba(255, 255, 255, .85);
  font-size: var(--lead);
  max-width: 34em;
}
.hero .eyebrow { color: #fff; }

.eyebrow {
  font-family: var(--font-head);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--clay-dark);
  margin: 0 0 .9rem;
}

.cta-row { display: flex; flex-wrap: wrap; gap: .7rem; margin: 1.7rem 0 0; }

/* Schmaler Streifen direkt unter dem Video. */
.versprechen {
  padding-block: clamp(1.8rem, 1.2rem + 1.8vw, 2.8rem);
  border-bottom: 1px solid var(--line);
}
.trust {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.1rem, 2.5vw, 2.4rem);
}
.trust li { display: flex; flex-direction: column; gap: .1rem; }
.trust strong { font-family: var(--font-head); font-size: 1.02rem; letter-spacing: -.01em; }
.trust span { color: var(--muted); font-size: .88rem; line-height: 1.45; }

/* Kopfleiste über dem Video: durchsichtig, bis gescrollt wird. Nur solange
   das Handy-Menü zu ist (:not(.nav-open)) — das Menü hat einen hellen Grund,
   mit diesen Regeln standen Menüpunkte, Logo und Schließen-X sonst weiß auf
   hell. Die oberste Zeile mit Ort und Telefon gibt es seit 14.09.2026 nicht
   mehr (sie stand nur auf der Startseite). */
.hat-hero:not(.nav-open) .site-header:not(.is-stuck) { color: #fff; }
.hat-hero:not(.nav-open) .site-header:not(.is-stuck)::before {
  background: transparent;
  backdrop-filter: none;
}
.hat-hero:not(.nav-open) .site-header:not(.is-stuck) .nav > a { color: #fff; }
/* Das gesperrte SERVICE unter der Wortmarke steht sonst in Terrakotta auf
   grauem Putz — bei der Größe nicht mehr lesbar. Über dem Video deshalb der
   hellere Ton, auf der weißen Leiste bleibt es beim Markenfarbton. */
.hat-hero:not(.nav-open) .site-header:not(.is-stuck) .brand__sub { fill: var(--clay-lite); }
.hat-hero:not(.nav-open) .site-header:not(.is-stuck) .burger span { background: #fff; }
.hat-hero:not(.nav-open) .site-header:not(.is-stuck) .burger { border-color: rgba(255, 255, 255, .35); }

/* Hinweis zum Weiterscrollen. Nur am großen Bildschirm — am Handy sitzt
   unten schon die Anrufleiste, und zwei Dinge am selben Rand sind einer
   zu viel. */
.hero__cue {
  position: absolute;
  right: var(--pad-x);
  bottom: clamp(1.2rem, 2vw, 2rem);
  display: none;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  font-size: .76rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .62);
}
.hero__cue::after {
  content: "";
  width: 1px;
  height: 44px;
  background: linear-gradient(rgba(255, 255, 255, .55), transparent);
  animation: cue 2.4s ease-in-out infinite;
  transform-origin: top;
}
@keyframes cue {
  0%, 100% { transform: scaleY(.4); opacity: .4; }
  50%      { transform: scaleY(1);  opacity: 1; }
}
@media (min-width: 900px) { .hero__cue { display: flex; } }

@media (max-width: 760px) {
  /* Die feste Anrufleiste deckt unten rund 62 Pixel ab. Ohne diesen
     Zuschlag läge der Anfrage-Knopf darunter. */
  .hero { padding-bottom: 5.5rem; }

  /* Am Handy nur Kategoriezeile, Überschrift und der Telefon-Knopf. Mit
     Absatz und zweitem Knopf deckte der Text fast das ganze Video zu — frei
     blieben rund 100 Pixel (Bilal, 13.09.2026). „Anfragen" steht ohnehin in
     der Anrufleiste, der Absatz sinngemäß in den Leistungen darunter. */
  .hero .lead,
  .hero .cta-row .btn--outline-light { display: none; }
  .hero .cta-row { margin-top: 1.2rem; }
}
@media (max-width: 560px) {
  .trust { grid-template-columns: 1fr; gap: .75rem; }
  .cta-row .btn { width: 100%; }
}

/* ---------------------------------------------------------
   Bildrahmen + Platzhalter
   Solange in assets/img/ noch kein Foto liegt, entfernt das
   Skript im <head> das kaputte Bild und der Kasten zeigt
   stattdessen den Text aus data-label.
   --------------------------------------------------------- */
.media {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--paper-2);
  border: 1px solid var(--line);
  aspect-ratio: 4 / 3;
}
/* <picture> bekommt display:contents, damit der Rahmen direkt auf das Bild
   wirkt. Ohne das läge zwischen beiden noch ein Inline-Element, das unten
   eine Lücke von ein paar Pixeln erzeugt. */
.media picture,
.card__bild picture { display: contents; }
.media img { width: 100%; height: 100%; object-fit: cover; }
.media--tall { aspect-ratio: 3 / 4; }
.media--wide { aspect-ratio: 3 / 2; }

.media.is-empty::before {
  content: attr(data-label);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.5rem;
  color: var(--muted);
  font-size: .9rem;
  line-height: 1.5;
}
.media.is-empty::after {
  content: "";
  position: absolute;
  inset: .6rem;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-sm);
  pointer-events: none;
}

/* ---------------------------------------------------------
   Abschnitte
   --------------------------------------------------------- */
.section { padding-block: var(--sec-y); }
.section--paper2 { background-color: var(--paper-2); background-image: var(--grain); }
.section--ink {
  /* Dasselbe Schwarz wie hinter dem Video. Die dunklen Abschnitte lesen
     sich dadurch als Fortsetzung des Hero und nicht als eigene Farbe. */
  background-color: var(--schwarz);
  background-image: var(--grain-dark);
  color: #fff;
}
.section--ink .eyebrow { color: var(--clay-lite); }
.section--ink .sec-head__lead { color: var(--muted-dark); }

.sec-head { max-width: 46rem; margin-bottom: clamp(2rem, 1rem + 2.5vw, 3.25rem); }
.sec-head h2 { margin-bottom: .4em; }
.sec-head__lead { color: var(--muted); font-size: var(--lead); }
.sec-head--center { margin-inline: auto; text-align: center; }

/* ---------------------------------------------------------
   Leistungen
   --------------------------------------------------------- */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 2vw, 1.6rem);
}
.card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r);
  /* Das Bild sitzt bündig in der Karte und soll ihre Rundung mitnehmen. */
  overflow: hidden;
  box-shadow: var(--shadow-s);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-m);
  border-color: var(--line-2);
}

/* Die Symbole von früher sind weg. Sie waren der Ersatz dafür, dass es
   nichts zu zeigen gab — neben einem echten Foto wären sie nur Beiwerk. */
.card__bild {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--paper-2);
}
.card__bild img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .7s cubic-bezier(.2, .7, .3, 1);
}
.card:hover .card__bild img { transform: scale(1.045); }

/* Kennzeichnung eines fremden Fotos. Ein Symbolbild darf nicht wie eine
   eigene Arbeit wirken (§ 5 UWG) — klein genug, dass es nicht stört. */
.card__hinweis {
  position: absolute;
  left: .7rem;
  bottom: .7rem;
  padding: .22rem .5rem;
  border-radius: 4px;
  background: rgba(13, 14, 16, .62);
  color: #fff;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .02em;
  pointer-events: none;
}

.card__in {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: clamp(1.3rem, 1rem + 1vw, 1.9rem);
}
.card h3 { margin-bottom: .5em; }
.card__in > p { color: var(--muted); font-size: .95rem; }

.ticks { list-style: none; margin: 1.1rem 0 0; padding: 0; display: grid; gap: .5rem; }
.ticks li {
  position: relative;
  padding-left: 1.6rem;
  font-size: .93rem;
  line-height: 1.5;
}
.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .5em;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  background: var(--clay);
}

@media (max-width: 940px) { .cards { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) {
  .cards { grid-template-columns: 1fr; }
  /* Untereinander wäre ein Hochformat rund 500 Pixel hoch. Man müsste dann
     an drei bildschirmfüllenden Fotos vorbeiwischen, um die drei Leistungen
     zu lesen. Quer bleibt jede Karte mit einem Blick erfassbar. */
  .card__bild { aspect-ratio: 16 / 10; }
}

/* ---------------------------------------------------------
   Leistungen als Karussell

   Nachbau der React-Vorlage „feature-carousel" (shadcn/21st.dev) ohne
   React — die Seite hat keinen Build-Schritt und bekommt auch keinen.
   main.js setzt .is-an und schreibt an jede Karte data-pos: 0 ist die
   Mitte, -1 und 1 sind die Nachbarn. Ohne JavaScript fehlt .is-an, und die
   drei Karten stehen nebeneinander wie oben.

   Karte: oben drei Fünftel Foto, unten zwei Fünftel Text mit den sechs
   Stichpunkten in zwei Spalten. Am Handy reicht die Breite dafür nicht —
   dort einspaltig, und der Textteil darf höher werden.
   --------------------------------------------------------- */
.section--karussell {
  /* Die Nachbarkarten ragen seitlich über den Rand hinaus. */
  overflow-x: hidden;
  overflow-x: clip;
}
/* 580 breit, nachgemessen: Bei 560 brachen die langen Stichpunkte
   zweizeilig um. Noch breiter schöbe die Nebenfotos unter die Pfeile.
   Das Foto ist drei Fünftel von 640 hoch (384 px); der Textteil wächst mit
   seinem Inhalt, beim Fassadenbau auf höchstens 245 px. */
.karussell {
  --karte-b: 580px;
  --karte-h: 640px;
  --bild-h: calc(var(--karte-h) * .6);
  position: relative;
}
.karussell__steuerung { display: none; }

.karussell.is-an .cards {
  grid-template-columns: 1fr;
  justify-items: center;
  /* Senkrecht scrollt der Browser, waagerechtes Wischen kommt bei main.js an. */
  touch-action: pan-y;
}
.karussell.is-an .card {
  --pos: 0;
  --groesse: 1;
  --deckkraft: 1;
  grid-area: 1 / 1;
  /* Jede Karte ist so hoch wie ihr Text und hängt oben. Bis 14.09.2026 waren
     alle gleich hoch, und unter kürzeren Texten blieb leeres Weiß stehen —
     am Handy 75 px beim Trockenbau. */
  align-self: start;
  width: min(var(--karte-b), 100%);
  z-index: 3;
  opacity: var(--deckkraft);
  box-shadow: var(--shadow-m);
  /* Verkleinert wird um die Fotomitte: So stehen die Nebenfotos mittig
     neben dem Hauptfoto statt versetzt darüber oder darunter. */
  transform-origin: 50% calc(var(--bild-h) / 2);
  transform: translateX(calc(var(--pos) * 45%)) scale(var(--groesse));
  transition: transform .5s ease, opacity .5s ease, background-color .3s ease, border-color .3s ease, box-shadow .5s ease;
}
/* Von den Nachbarn bleibt nur das unscharfe Foto. Bis 14.09.2026 war die
   ganze Karte unscharf und durchsichtig: Überschrift und Stichpunkte wurden
   zu grauen Schlieren in einem milchigen Kasten, am Handy genau am Bildrand.
   Bilal fand das Karussell „unclean". */
.karussell.is-an .card[data-pos="-1"],
.karussell.is-an .card[data-pos="1"] {
  --groesse: .85;
  --deckkraft: .6;
  z-index: 2;
  background-color: transparent;
  border-color: transparent;
  box-shadow: none;
  /* Anklickbar ist nur das Foto, nicht der unsichtbare Text darunter. */
  pointer-events: none;
}
.karussell.is-an .card[data-pos="-1"] .card__bild,
.karussell.is-an .card[data-pos="1"] .card__bild {
  border-radius: var(--r);
  pointer-events: auto;
  cursor: pointer;
}
/* Leicht vergrößert, sonst zieht die Unschärfe am Rand einen hellen Saum. */
.karussell.is-an .card[data-pos="-1"] .card__bild img,
.karussell.is-an .card[data-pos="1"] .card__bild img {
  filter: blur(3px);
  transform: scale(1.08);
}
/* Beim Weiterdrehen verschwindet der alte Text schnell, der neue kommt erst,
   wenn seine Karte fast in der Mitte ist. So liegen nie zwei Texte
   übereinander (an Zwischenbildern bei 80, 200 und 350 ms geprüft). */
.karussell.is-an .card[data-pos="-1"] .card__in,
.karussell.is-an .card[data-pos="1"] .card__in,
.karussell.is-an .card[data-pos="-1"] .card__hinweis,
.karussell.is-an .card[data-pos="1"] .card__hinweis {
  opacity: 0;
  transition: opacity .12s ease;
}
.karussell.is-an .card[data-pos="-1"] { --pos: -1; }
.karussell.is-an .card[data-pos="1"]  { --pos: 1; }
/* Erst ab vier Karten nötig: Alles weiter außen wird ausgeblendet. */
.karussell.is-an .card[data-pos="-2"],
.karussell.is-an .card[data-pos="2"] {
  --groesse: .7;
  --deckkraft: 0;
  z-index: 1;
  visibility: hidden;
}
.karussell.is-an .card[data-pos="-2"] { --pos: -2; }
.karussell.is-an .card[data-pos="2"]  { --pos: 2; }

.karussell.is-an .card__bild {
  aspect-ratio: auto;
  height: var(--bild-h);
  transition: border-radius .5s ease;
}
.karussell.is-an .card__bild img { transition: transform .7s cubic-bezier(.2, .7, .3, 1), filter .5s ease; }
.karussell.is-an .card__in,
.karussell.is-an .card__hinweis { transition: opacity .3s ease .2s; }
.karussell.is-an .card__in { padding: 1.2rem 1.6rem 1.3rem; }
.karussell.is-an .card h3 { margin-bottom: .25em; }
/* „pretty" hält das letzte Wort nicht allein in der Zeile („abgezogen."). */
.karussell.is-an .card__in > p { margin: 0; text-wrap: pretty; }
.karussell.is-an .ticks {
  grid-template-columns: 1fr 1fr;
  column-gap: 1.4rem;
  row-gap: .3rem;
  margin-top: .8rem;
}
.karussell.is-an .ticks li { font-size: .88rem; line-height: 1.4; text-wrap: pretty; }

.karussell.is-an .karussell__steuerung {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 1.3rem;
}
.karussell__pfeil {
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 50%;
  background: rgba(255, 255, 255, .72);
  backdrop-filter: blur(6px);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease;
}
.karussell__pfeil:hover { background: var(--white); border-color: var(--ink); }
/* Die Pfeile sind lucide „chevron-left" und „chevron-right" (ISC-Lizenz),
   als Pfad eingebettet statt als Paket. */
.karussell__pfeil svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.karussell__stand {
  margin: 0;
  min-width: 3.5em;
  text-align: center;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: .95rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* Am großen Bildschirm sitzen die Pfeile wie in der Vorlage links und
   rechts, auf Höhe der Fotomitte; die Zählung braucht es dort nicht. */
@media (min-width: 941px) {
  .karussell.is-an .karussell__steuerung {
    position: absolute;
    /* Etwas nach außen, damit die Nebenfotos nicht unter die Pfeile ragen. */
    left: -1.5rem;
    right: -1.5rem;
    top: calc(var(--bild-h) / 2);
    transform: translateY(-50%);
    justify-content: space-between;
    margin: 0;
    pointer-events: none;
  }
  .karussell.is-an .karussell__pfeil { pointer-events: auto; }
  .karussell.is-an .karussell__stand { display: none; }
}

/* Bis 700 statt 640: Darunter ist die Karte schmaler als 580, und die
   Stichpunkte passen nicht mehr zweispaltig. */
@media (max-width: 700px) {
  /* 80 % breit: So ragen links und rechts die unscharfen Nebenfotos ins
     Bild wie am PC (Bilal, 13.09.2026). Vorher war die Karte voll breit und
     die Nachbarn ausgeblendet. */
  .karussell.is-an .card { width: min(var(--karte-b), 80cqw); }
  .karussell.is-an .card__in { padding: 1rem 1.15rem 1.1rem; }
  .karussell.is-an .card__in > p { font-size: .9rem; }
  .karussell.is-an .ticks { grid-template-columns: 1fr; row-gap: .15rem; margin-top: .6rem; }
  .karussell.is-an .ticks li { font-size: .86rem; }

  /* Foto 16:9 statt 4:3: Mit 4:3 war die Karte am iPhone höher als der
     sichtbare Bereich, Pfeile und Zählung lagen unter der Anrufleiste
     (Bilal, 13.09.2026). Die Höhe wird aus der Kartenbreite gerechnet
     (cqw = Breite des Karussells).

     Pfeile und Zählung liegen am Handy als kleine Leiste unten rechts im
     Bild statt unter der Karte — so passt die Karte samt Bedienung auf den
     Bildschirm. */
  .karussell {
    container-type: inline-size;
    --bild-h: calc(min(var(--karte-b), 80cqw) * 9 / 16);
  }
  .karussell.is-an .karussell__steuerung {
    position: absolute;
    z-index: 5;
    top: calc(var(--bild-h) - 44px - .6rem);
    right: calc((100cqw - min(var(--karte-b), 80cqw)) / 2 + .6rem);
    margin: 0;
    gap: 0;
    padding: 0 .15rem;
    border-radius: 999px;
    background: rgba(13, 14, 16, .55);
    backdrop-filter: blur(6px);
  }
  .karussell.is-an .karussell__pfeil {
    width: 44px;
    height: 44px;
    border: 0;
    background: transparent;
    backdrop-filter: none;
    color: #fff;
  }
  .karussell.is-an .karussell__pfeil:hover { background: rgba(255, 255, 255, .12); }
  .karussell.is-an .karussell__stand { min-width: 2.6em; font-size: .85rem; color: #fff; }
}

/* Die Einleitung der Leistungen steht unter dem Karussell statt im Kopf:
   gleiche Schrift wie die übrigen Einleitungen, aber mittig. */
.leistungen__schluss {
  max-width: 46rem;
  margin: clamp(2.6rem, 1.6rem + 3vw, 4.25rem) auto 0;
  text-align: center;
  /* Verteilt die Wörter gleichmäßig — sonst stand am Desktop „Sanierung."
     allein in der letzten Zeile. Ältere Browser brechen einfach normal um. */
  text-wrap: balance;
  color: var(--muted);
  font-size: var(--lead);
}

/* ---------------------------------------------------------
   Ablauf
   --------------------------------------------------------- */
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 2vw, 1.8rem);
  counter-reset: step;
}
.step { position: relative; padding-top: 2.6rem; }
.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  position: absolute;
  top: 0;
  left: 0;
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--clay-lite);
  letter-spacing: .06em;
}
.step::after {
  content: "";
  position: absolute;
  top: 1.75rem;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--line-dark);
}
.step h3 { color: #fff; margin-bottom: .45em; }
.step p { color: var(--muted-dark); font-size: .95rem; }

@media (max-width: 900px) { .steps { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .steps { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------
   Aktuelle Baustelle

   Es ist ein einziges Projekt, und genau so wird es gezeigt: ein Film
   über die volle Breite, darunter drei Aufnahmen davon. Sechs Kacheln
   so zu beschriften, als wären es sechs Aufträge, wäre gelogen.
   --------------------------------------------------------- */
/* Kleine Galerie der aktuellen Baustelle: vier quadratische Kacheln mit
   runden Ecken, am PC in einer Reihe, am Handy zwei mal zwei. Vorher standen
   hier ein großer Film und drei hohe Fotos — Bilal: „zu groß alles". */
.kacheln {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(.6rem, 1.2vw, 1rem);
}
.kachel {
  position: relative;
  margin: 0;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 18px;
  background: var(--schwarz);
}
.kachel picture { display: contents; }
.kachel img,
.kachel video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.kachel video { opacity: 0; transition: opacity .9s ease; }
.kachel video.is-da { opacity: 1; }
@media (max-width: 640px) {
  .kacheln { grid-template-columns: 1fr 1fr; }
  .kachel { border-radius: 14px; }
}


/* Harte Fakten zum Projekt. Steht bewusst unter den Bildern und nicht
   darüber: Erst sieht man die Arbeit, dann liest man die Eckdaten. */
.fakten {
  margin: clamp(1.6rem, 1rem + 1.5vw, 2.4rem) 0 0;
  padding: 1.4rem 0 0;
  border-top: 1px solid var(--line-2);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.2rem;
}
.fakten > div { display: flex; flex-direction: column; gap: .15rem; }
.fakten dt {
  font-family: var(--font-head);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.fakten dd { margin: 0; font-weight: 600; font-size: .95rem; }

@media (max-width: 640px) { .fakten { grid-template-columns: 1fr 1fr; } }
.hint {
  margin-top: 1.6rem;
  padding: .9rem 1.1rem;
  border-left: 3px solid var(--clay);
  background: var(--white);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--muted);
  font-size: .92rem;
}
.section--paper2 .hint { background: rgba(255, 255, 255, .6); }

/* ---------------------------------------------------------
   Über uns
   --------------------------------------------------------- */
.about {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
}
.about p { color: var(--muted); }
.about p.about__lead { color: var(--ink); font-size: var(--lead); }

.towns { margin-top: 2rem; }
.towns h3 { font-size: 1rem; margin-bottom: .8em; }
.towns ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
}
.towns li {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: .3rem .8rem;
  font-size: .87rem;
  color: var(--muted);
}

@media (max-width: 860px) { .about { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------
   Fragen
   --------------------------------------------------------- */
.faq { max-width: 52rem; }
.faq details {
  border-bottom: 1px solid var(--line);
  padding: .35rem 0;
}
.faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.05rem 0;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.35;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  flex: none;
  margin-left: auto;
  margin-top: .38em;
  width: 11px;
  height: 11px;
  border-right: 2px solid var(--clay);
  border-bottom: 2px solid var(--clay);
  transform: rotate(45deg);
  transition: transform .2s ease;
}
.faq details[open] summary::after { transform: rotate(-135deg); margin-top: .6em; }
.faq details p {
  color: var(--muted);
  font-size: .96rem;
  padding-bottom: 1.1rem;
  max-width: 46rem;
}

/* ---------------------------------------------------------
   Kontakt
   --------------------------------------------------------- */
.contact {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}

.form { display: grid; gap: .9rem; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }
.form label {
  display: block;
  font-size: .87rem;
  font-weight: 600;
  margin-bottom: .35rem;
  color: var(--muted-dark);
}
.form input,
.form select,
.form textarea {
  width: 100%;
  font: inherit;
  /* Exakt 16px und keinen Deut kleiner: iOS Safari zoomt die ganze Seite
     hinein, sobald ein Eingabefeld mit kleinerer Schrift den Fokus bekommt.
     Der Besucher landet dann verschoben im Formular und muss erst wieder
     herauszoomen — auf dem Handy der schnellste Weg, eine Anfrage zu verlieren. */
  font-size: 16px;
  color: #fff;
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--line-dark);
  border-radius: var(--r-sm);
  padding: .72rem .85rem;
  transition: border-color .16s ease, background-color .16s ease;
}
.form textarea { min-height: 130px; resize: vertical; }
.form input::placeholder,
.form textarea::placeholder { color: rgba(255, 255, 255, .4); }
.form input:hover,
.form select:hover,
.form textarea:hover { border-color: rgba(255, 255, 255, .3); }
.form input:focus,
.form select:focus,
.form textarea:focus {
  outline: none;
  border-color: var(--clay-lite);
  background: rgba(255, 255, 255, .1);
}
.form .is-invalid { border-color: #ff8a75; background: rgba(255, 138, 117, .1); }

/* Das Auswahlfeld erbt auf Windows sonst weiße Systemfarben für die Liste. */
.form select option { color: var(--ink); background: #fff; }

.form__check {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  font-size: .88rem;
  color: var(--muted-dark);
  line-height: 1.5;
}
.form__check input {
  /* 18px war mit dem Daumen kaum zu treffen — und wer den Haken nicht
     setzt, kommt am Formular nicht vorbei. */
  width: 1.5rem;
  height: 1.5rem;
  margin: .05rem 0 0;
  flex: none;
  accent-color: var(--clay);
}
.form__check a { color: #fff; text-underline-offset: 3px; }

.form__actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: .3rem; }
.form__note { font-size: .9rem; margin: 0; min-height: 1.4em; color: var(--muted-dark); }
.form__note.is-error { color: #ff9d8a; }
.form__note.is-ok { color: #7ee2a8; }

/* Spam-Falle: für Menschen unsichtbar, für einfache Bots verlockend. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.contact-card {
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  padding: clamp(1.4rem, 1rem + 1vw, 2rem);
}
.contact-card h3 { color: #fff; }
.contact-list { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: 1.05rem; }
.contact-list li { display: flex; gap: .85rem; align-items: flex-start; }
.contact-list .ico { width: 20px; height: 20px; margin-top: .25rem; color: var(--clay-lite); }
.contact-list b {
  display: block;
  font-family: var(--font-head);
  font-size: .78rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted-dark);
  font-weight: 700;
  margin-bottom: .1rem;
}
.contact-list a {
  display: inline-flex;
  align-items: center;
  /* Telefon, WhatsApp und E-Mail sind die drei wichtigsten Ziele der
     ganzen Seite. Als 20px hohe Textzeile waren sie zu knapp zum Tippen. */
  min-height: 44px;
  color: #fff;
  text-decoration: none;
  font-weight: 600;
}
.contact-list a:hover { color: var(--clay-lite); }
.contact-card__note {
  font-size: .87rem;
  color: var(--muted-dark);
  border-top: 1px solid var(--line-dark);
  padding-top: 1.1rem;
  margin-top: 1.4rem;
}

@media (max-width: 900px) { .contact { grid-template-columns: 1fr; } }
@media (max-width: 520px) {
  .form__row { grid-template-columns: 1fr; }
  .form__actions .btn { width: 100%; }
}

/* ---------------------------------------------------------
   Fußzeile
   --------------------------------------------------------- */
.footer {
  background-color: #17191b;
  background-image: var(--grain-dark);
  color: var(--muted-dark);
  padding: clamp(2.5rem, 1.5rem + 3vw, 4rem) 0 2rem;
  font-size: .92rem;
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  gap: clamp(1.6rem, 3vw, 3rem);
  padding-bottom: 2.2rem;
  border-bottom: 1px solid var(--line-dark);
}
.footer__mark { height: 52px; width: auto; margin-bottom: 1rem; }
.footer h4 {
  color: #fff;
  font-size: .8rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-bottom: 1rem;
}
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.footer a { text-decoration: none; }
.footer a:hover { color: #fff; }
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.4rem;
  align-items: center;
  padding-top: 1.5rem;
  font-size: .86rem;
}
.footer__bottom nav { display: flex; gap: 1.2rem; margin-left: auto; }

@media (max-width: 760px) {
  .footer__grid { grid-template-columns: 1fr; }
  .footer__bottom nav { margin-left: 0; }
  /* Am Handy bekommt jeder Fußzeilen-Link ein volles Tippziel. Das macht
     die Fußzeile länger — beim Scrollen stört das niemanden, danebentippen
     dagegen schon. */
  .footer ul { gap: 0; }
  .footer ul a,
  .footer__bottom nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ---------------------------------------------------------
   Feste Anruf-Leiste am Handy.
   Bei Handwerksbetrieben kommt der Großteil der Anfragen über
   genau diesen Knopf — deshalb liegt sie immer im Blick.
   --------------------------------------------------------- */
.callbar { display: none; }

@media (max-width: 760px) {
  .callbar {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 70;
    background: var(--ink);
    border-top: 1px solid var(--line-dark);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .callbar a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .18rem;
    padding: .62rem .3rem;
    color: #fff;
    text-decoration: none;
    font-size: .76rem;
    font-weight: 600;
    /* 48 px Mindesthöhe: kleiner lässt sich mit dem Daumen nicht sicher treffen. */
    min-height: 52px;
  }
  .callbar a + a { border-left: 1px solid var(--line-dark); }
  .callbar .ico { width: 20px; height: 20px; }
  .callbar__wa { color: #6ee7a4; }
  .callbar__cta { color: var(--clay-lite); }
  /* Platz schaffen, damit die Leiste die Fußzeile nicht überdeckt. */
  .footer { padding-bottom: calc(2rem + 64px); }
}

/* ---------------------------------------------------------
   Einblenden beim Scrollen.
   Das Verstecken hängt an .reveal-on, das ERST von main.js
   gesetzt wird — so kann eine fehlende oder kaputte JS-Datei
   die Inhalte niemals dauerhaft unsichtbar machen.
   --------------------------------------------------------- */
.reveal-on .reveal {
  opacity: 0;
  transform: translateY(18px);
}
.reveal-on .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .55s ease, transform .55s cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal-on .reveal { opacity: 1; transform: none; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------------------------------------------------------
   Unterseiten (Impressum / Datenschutz)
   --------------------------------------------------------- */
.page-head {
  background-color: var(--ink);
  background-image: var(--grain-dark),
    radial-gradient(ellipse 55% 60% at 88% 0%, rgba(200, 90, 43, .22), transparent 60%);
  color: #fff;
  padding: clamp(2.6rem, 2rem + 3vw, 4.5rem) 0 clamp(2.6rem, 2rem + 3vw, 4rem);
}
.page-head h1 { margin-bottom: .3rem; }
.page-head p { color: var(--muted-dark); margin: 0; }

.legal { padding: clamp(2.5rem, 2rem + 3vw, 4.5rem) 0; }
.legal h2 {
  font-size: clamp(1.25rem, 1.1rem + .6vw, 1.6rem);
  margin: 2.2rem 0 .7rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line);
}
.legal h2:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
.legal h3 { margin: 1.5rem 0 .5rem; font-size: 1.02rem; }
.legal p, .legal li { color: var(--muted); }
.legal ul { padding-left: 1.2rem; }
.legal li { margin-bottom: .4rem; }
.legal a { color: var(--clay-dark); }
.legal address {
  font-style: normal;
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 4px solid var(--clay);
  border-radius: var(--r-sm);
  padding: 1.2rem 1.4rem;
  margin: 1.2rem 0;
  color: var(--ink);
}
/* Noch offene Angaben sichtbar markieren, statt sie stillschweigend
   wegzulassen — eine Lücke im Impressum darf niemand übersehen. */
.legal .offen {
  background: #fdf3d6;
  border: 1px dashed #d9a441;
  border-radius: var(--r-sm);
  padding: .1rem .4rem;
  color: #6b4c05;
  font-size: .93em;
}
.back-link {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  margin-top: 2.5rem;
  font-weight: 600;
  color: var(--clay-dark);
  text-decoration: none;
}
.back-link:hover { text-decoration: underline; }

/* ---------------------------------------------------------
   Druck — alles auf Schwarz-Weiß herunterbrechen, damit ein
   ausgedrucktes Angebot lesbar bleibt und kein Toner draufgeht.
   --------------------------------------------------------- */
@media print {
  .topbar, .site-header, .callbar, .burger, .cta-row, .form__actions, .hint { display: none !important; }
  body { background: #fff !important; color: #000; font-size: 11pt; }
  .section, .section--ink, .section--paper2, .footer {
    background: #fff !important;
    color: #000 !important;
    padding-block: 1.2rem;
  }
  .section--ink h3, .step h3, .contact-card h3, .footer h4, .contact-list a { color: #000 !important; }
  .step p, .sec-head__lead, .leistungen__schluss, .contact-list b, .footer, .form label { color: #333 !important; }
  .card, .contact-card, .media { border: 1px solid #999; box-shadow: none; }
  .reveal { opacity: 1 !important; transform: none !important; }
  /* Auf Papier dreht sich nichts: die drei Leistungen nebeneinander. */
  .karussell.is-an .cards { grid-template-columns: repeat(3, 1fr); }
  .karussell.is-an .card[data-pos] {
    grid-area: auto;
    width: auto;
    transform: none;
    opacity: 1;
    visibility: visible;
    background-color: #fff;
  }
  .karussell.is-an .card[data-pos] .card__bild { height: auto; aspect-ratio: 4 / 3; }
  .karussell.is-an .card[data-pos] .card__bild img { filter: none; transform: none; }
  .karussell.is-an .card[data-pos] .card__in,
  .karussell.is-an .card[data-pos] .card__hinweis { opacity: 1; }
  .karussell__steuerung { display: none !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
