/* ============================================================
   VitaMel's Fensterreinigung - Stylesheet
   ------------------------------------------------------------
   Aufbau dieser Datei
   1. Farben, Masse, Schriftgroessen (Tokens)
   2. Grundlagen
   3. Bausteine (Knoepfe, Karten, Symbole)
   4. Abschnitte der Startseite, in der Reihenfolge der Seite
   5. Rechtsseiten
   6. Kleine Bildschirme
   ============================================================ */

/* ============================================================
   1. Tokens
   ------------------------------------------------------------
   Farbgedanke: kuehle, klare Toene, die an Glas und Wasser erinnern,
   dazu ein warmer Akzent, damit die Seite nicht klinisch wirkt.

   Der warme Ton --licht erreicht auf hellem Grund nur 3,6:1. Er wird
   deshalb nie fuer Fliesstext benutzt, sondern nur grafisch: Linien,
   Flaechen, Symbole. Wo der warme Ton als Text erscheint, steht
   --licht-text mit 6,4:1.
   ============================================================ */
:root {
  /* Grundflaechen */
  --papier:        #FFFFFF;
  --grund:         #FBFCFC;
  --grund-kuehl:   #F2F7F8;

  /* Tiefe Toene: die dunkle Kante einer Glasscheibe */
  --tinte:         #0B2B33;   /* 14,5:1 auf --grund */
  --text:          #17323A;   /* 13,2:1 auf --grund */
  /* Gedaempfter Text. Vorher #4E6B73 mit 5,3:1 auf den Bahnen, fuer
     eine Zielgruppe von 45 bis 70 zu schwach, zumal rund 70 Prozent
     aller Saetze in dieser Farbe stehen. Gleicher Farbeindruck,
     dunkler abgemischt. */
  --leise:         #3A555C;   /*  7,4:1 auf --grund */

  /* Wasser: der kuehle Leitton */
  --wasser:        #0E6E86;   /*  5,7:1 auf --grund */
  --wasser-tief:   #0A5A6E;
  --wasser-blass:  #E4F1F4;
  --wasser-hauch:  #F3F9FA;

  /* Licht: der warme Gegenpol, Sonne durch eine saubere Scheibe */
  --licht:         #C2711C;   /* nur grafisch */
  /* Warmer Text fuer Kicker, Marken und Pillen. Vorher #8A4E10 mit
     6,4:1, nach dem Audit auf ueber 7:1 gezogen. */
  --licht-text:    #6F3E0C;   /*  8,6:1 auf --grund, 7,9:1 auf --licht-blass */
  --licht-blass:   #FBF1E3;
  --licht-hauch:   #FDF8F1;

  /* Toene auf dunklem Grund. Der Hero laeuft seit dem dreizehnten
     Umbau auf --tinte, dort tragen die hellen Toene der Palette
     nicht. Beide sind gegen --tinte gemessen. */
  --tief-ocker:    #F0C58A;   /*  8,6:1 auf --tinte */
  --tief-leise:    #B4CBD1;   /*  8,2:1 auf --tinte */
  /* Heller als --tief-leise, fuer Text auf dem dunklen Hero, der
     nicht leise sein soll. */
  --tief-hell:     #E1EEF1;

  /* Linien */
  --linie:         #DDE7E9;
  --linie-stark:   #C3D5D9;

  /* Masse. Vierer-Raster. */
  --s1: 4px;   --s2: 8px;   --s3: 12px;  --s4: 16px;
  --s5: 24px;  --s6: 32px;  --s7: 48px;  --s8: 64px;
  --s9: 80px;  --s10: 128px;

  /* Schriftgroessen.
     Die Zielgruppe ist ueberwiegend zwischen 45 und 70. Der Grundtext
     startet deshalb bei 17px statt der ueblichen 16 und waechst auf
     dem Rechner auf 18. */
  --t-grund:  17px;
  --t-klein:  15px;
  --t-mini:   13px;
  --t-lead:   clamp(1.06rem, 1rem + 0.35vw, 1.28rem);
  --t-h1:     clamp(2.05rem, 1.35rem + 3.1vw, 3.85rem);
  /* Untergrenze von 1,62 auf 1,875 rem, also von 25,9 auf 30 px.
     Die H2 laeuft seit dem dreizehnten Umbau in einer Displayschrift
     mit hohem Strichkontrast.

     Die Vermutung war, dass die duennen Striche bei 25,9 px zu duenn
     werden. Die Messung mit _pruefung/strichstaerke.py sagt das
     nicht: der Haarstrich liegt bei 25,9 px und bei 30 px gleich
     hoch, bei 2,00 px, und das Verhaeltnis von Haar- zu Grundstrich
     ist auf Handy und Rechner identisch bei 0,067 des Schriftgrads.

     Die groessere Untergrenze bleibt trotzdem, aber aus dem
     schlichteren Grund: 30 px sind fuer eine Zielgruppe zwischen 45
     und 70 besser zu lesen als 25,9. Es ist eine Groessen-, keine
     Strichstaerkenfrage. */
  --t-h2:     clamp(1.875rem, 1.25rem + 1.7vw, 2.5rem);
  --t-h3:     clamp(1.17rem, 1.08rem + 0.42vw, 1.42rem);

  /* Breiten.
     Der Inhalt lief bei 1200 px, auf einem 1440er Bildschirm blieben
     links und rechts je 120 px ungenutzt und die Seite wirkte leer.
     Karten, Bilder und das Preisraster nutzen jetzt 1360 px.
     Fliesstext bleibt bei --lesebreite, weil lange Zeilen sonst
     schwer zu verfolgen sind. */
  --breit:      1360px;
  --schmal:     72ch;
  --lesebreite: 720px;
  /* Seitenrand der Bahnen. Waechst mit dem Fenster, faellt aber nie
     unter 20 px und steigt nie ueber 40 px. Ohne Untergrenze stiesse
     der Inhalt auf einem 1265 px breiten Fenster fast an die Kante,
     seit die Inhaltsbreite auf 1360 px steht. */
  --rand:       clamp(20px, 3vw, 40px);

  /* Luft oben und unten in einer Abschnittsbahn. Eigene Tokens statt
     der Groessenskala, weil --s8 und --s9 auch anderswo hangen.
     Vorher 80 px, dadurch trafen zwischen zwei Abschnitten bis zu
     160 px Leerraum aufeinander. */
  --bahn-luft:     48px;
  --bahn-luft-eng: 40px;
  /* Der Hero braucht oben weniger, sonst steht unter der Kopfzeile
     eine leere Flaeche. Zwischen Bahnkante und H1 liegt noch der
     Kicker, deshalb sind es hier nur 20 px. */
  --hero-oben:     20px;

  /* Rundungen und Schatten */
  --r-klein:  6px;
  --r:        12px;
  --r-gross:  20px;
  /* Bis zum siebenunddreissigsten Umbau lagen beide bei 5 bis 10
     Prozent Deckkraft. Gemessen aendert ein Schatten mit 5 Prozent
     die Helligkeit des Untergrundes um weniger als ein Zehntel;
     das sieht auf einem hellen Bildschirm im Tageslicht niemand.
     Jetzt 8 bis 22 Prozent. */
  --schatten:       0 8px 24px rgba(20,30,35,.12), 0 2px 6px rgba(20,30,35,.08);
  --schatten-stark: 0 16px 40px rgba(20,30,35,.22), 0 4px 10px rgba(20,30,35,.12);
  --schatten-hoch:  0 20px 48px rgba(20,30,35,.20), 0 6px 14px rgba(20,30,35,.12);
  --schatten-knopf: 0 6px 16px rgba(20,30,35,.18);

  /* Ein Takt fuer alle Uebergaenge an Knoepfen, Karten und Feldern.
     Vorher 180 ms, jetzt 200: ruhiger, und nah genug an der Schwelle,
     ab der eine Bewegung als Reaktion gelesen wird und nicht als
     Verzoegerung. */
  --takt: 200ms cubic-bezier(.22,.61,.36,1);
  /* Die Fragen fahren langsamer auf als ein Knopf reagiert, und die
     Kurve laeuft am Ende sanft aus statt gleichmaessig zu stoppen. */
  --takt-frage: 300ms cubic-bezier(.22,.61,.36,1);
}

/* ============================================================
   2. Grundlagen
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--grund);
  color: var(--text);
  font-family: 'Grotesk', 'Grotesk Ersatz', system-ui, sans-serif;
  font-size: var(--t-grund);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
@media (min-width: 900px) { body { font-size: 18px; } }

h1, h2, h3, h4 {
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  color: var(--tinte);
  line-height: 1.14;
  letter-spacing: -.018em;
  margin: 0 0 var(--s4);
  font-weight: 600;
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); line-height: 1.06; letter-spacing: -.028em; }
/* Die H2 traegt die Stimme der Marke, deshalb dieselbe Schrift wie
   die Ueberschrift im Hero. Die H3 und H4 bleiben bei der
   Lesetextserife beziehungsweise der Grotesk: dort geht es um
   Groessen zwischen 17 und 23 px, und eine Displayschrift traegt
   dort nicht mehr.

   Instrument Serif hat nur einen Schnitt, deshalb Gewicht 400 statt
   der 600 der uebrigen Ueberschriften. */
h2 {
  font-family: 'Display', 'Serife', 'Serife Ersatz', Georgia, serif;
  font-weight: 400;
  font-size: var(--t-h2);
  letter-spacing: -.018em;
}
h3 { font-size: var(--t-h3); line-height: 1.25; }

p { margin: 0 0 var(--s4); }
p:last-child { margin-bottom: 0; }

/* Textlinks in --wasser-tief statt --wasser: 7,6:1 statt 5,7:1 auf
   dem Seitengrund. Der hellere Ton bleibt fuer Symbole und Linien. */
a { color: var(--wasser-tief); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--tinte); }

img { max-width: 100%; height: auto; display: block; }

/* Die Kopfzeile klebt oben. Ohne diesen Abstand landet ein Sprung
   ueber das Menue genau hinter der Kopfzeile und die Ueberschrift
   des Ziels ist verdeckt. */
/* Sprungziele muessen unter der klebenden Kopfzeile landen, nicht
   dahinter. Die Kopfzeile ist 71 px hoch auf dem Rechner und 73 px auf
   dem Handy, dazu rund 16 px Luft. main[id] gehoert dazu, sonst landet
   die Sprungmarke "Zum Inhalt" hinter der Kopfzeile. */
:target, section[id], main[id], #oben { scroll-margin-top: 89px; }

/* Die Anfrage-Knoepfe zeigen seit dem fuenfzehnten Umbau auf das
   Formular selbst, nicht mehr auf den Abschnitt darueber. Vorher
   landete man ueber dem Vorspann und den drei Kontaktkarten und
   musste erst noch scrollen, um ein Eingabefeld zu sehen. Das
   Formular ist ein <form> und faellt nicht unter section[id]. */
#anfrage { scroll-margin-top: 89px; }

:focus-visible {
  outline: 3px solid var(--wasser);
  outline-offset: 3px;
  border-radius: var(--r-klein);
}

.zum-inhalt {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--tinte); color: #fff; padding: var(--s3) var(--s5);
  border-radius: 0 0 var(--r) 0; font-weight: 600; text-decoration: none;
}
.zum-inhalt:focus { left: 0; }

.nur-vorlesen {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Aeussere Bahn und innerer Inhalt */
.bahn { padding: var(--bahn-luft) var(--rand); }
.bahn-eng { padding: var(--bahn-luft-eng) var(--rand); }
.mitte { max-width: var(--breit); margin: 0 auto; }
.mitte-schmal { max-width: var(--schmal); margin: 0 auto; }

.bahn-kuehl { background: var(--grund-kuehl); }
.bahn-blass { background: var(--wasser-hauch); }
.bahn-warm  { background: var(--licht-hauch); }
/* Kraeftiger als --bahn-warm. Die Karten darin stehen auf --papier und
   heben sich dadurch ab; ihre Kante wird warm mitgezogen, sonst wirkt
   sie auf dem warmen Grund grau. */
.bahn-licht { background: var(--licht-blass); }
.bahn-licht .faktor,
.bahn-licht .preis-schluss { background: var(--papier); border-color: #EFDFC6; }

/* Der gedaempfte Textton --leise ist gegen den warmen Grund auf
   7,07:1 gefallen, gemessen an den Glyphen mit
   _pruefung/feldkontrast.py. Das haelt die Hausmarke von 7:1, aber
   ohne jede Reserve: eine spaetere Aenderung am Grundton wuerde sie
   reissen, ohne dass jemand es merkt.

   Text, der direkt auf dem warmen Grund liegt, laeuft deshalb im
   normalen Textton statt im gedaempften. Damit stehen 12,0:1 statt
   7,07:1. Auf den weissen Karten bleibt --leise, dort sind es 7,97:1.
   Dieselbe Ueberlegung wie bei der dunklen Bahn, die eigene Toene
   fuer ihren Grund hat. */
.bahn-licht > .mitte > .kopf-block .lead,
.bahn-licht .festpreis p { color: var(--text); }
.bahn-tief  { background: var(--tinte); color: #DCE8EB; }
.bahn-tief h2, .bahn-tief h3 { color: #FFFFFF; }

/* Kleine Ueberschrift ueber der Ueberschrift */
.kicker {
  /* Die Groesse steht hier mit !important. In zwei Abschnitten setzt
     eine eigene p-Regel 16,5 px, und die gewann bisher gegen diese
     Regel: die Auszeichnung ueber "Ueber mich" und ueber "Der
     Unterschied" war dadurch ein Viertel groesser als die neun
     anderen. Gefunden mit _pruefung/bestand.py. */
  font-size: var(--t-mini) !important;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--licht-text);
  margin: 0 0 var(--s3);
  /* Bewusst kein Flex-Container. Als Flex wuerde jedes Textstueck neben
     einem span zu einem eigenen Element und bekaeme den Abstand der
     Luecke zusaetzlich zum Wortzwischenraum. Der Strich laeuft deshalb
     als Inline-Element im Text mit und bricht sauber um. */
  display: block;
  line-height: 1.5;
  text-wrap: balance;
}
.kicker::before {
  content: "";
  display: inline-block; vertical-align: middle;
  width: 26px; height: 2px; background: var(--licht);
  margin: -2px 12px 0 0;
}
.bahn-tief .kicker { color: #F0C58A; }
.bahn-tief .kicker::before { background: #F0C58A; }

/* Haelt eine Wortgruppe zusammen, damit Zeilen nicht mit einem
   einzelnen Wort enden. */
.zusammen { white-space: nowrap; }

.lead { font-size: var(--t-lead); color: var(--leise); line-height: 1.6; }
.bahn-tief .lead { color: #B4CBD1; }

/* Abstand vom Abschnittskopf zum Inhalt. Lag bei 48 px und war
   damit die groesste Luecke im Seitenfluss. */
.kopf-block { max-width: 60ch; margin-bottom: 36px; }
.kopf-block-mitte { max-width: 62ch; margin: 0 auto 36px; text-align: center; }
.kopf-block-mitte .kicker { text-align: center; }

/* ============================================================
   3. Bausteine
   ============================================================ */
.knopf {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font-family: inherit; font-size: 1rem; font-weight: 650;
  padding: 15px var(--s6);
  border-radius: var(--r);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--takt), color var(--takt), border-color var(--takt),
              transform var(--takt), box-shadow var(--takt);
  min-height: 54px;
  line-height: 1.2;
  text-align: center;
}
.knopf svg { width: 19px; height: 19px; flex: none; }

.knopf-voll {
  background: var(--wasser-tief); color: #FFFFFF;   /* 7,0:1 */
  /* Ein eigener, kleinerer Wert: ein Knopf soll wie ein Ding wirken,
     das man druecken kann, nicht wie eine schwebende Karte. */
  box-shadow: var(--schatten-knopf);
}
.knopf-voll:hover { background: var(--tinte); color: #fff; transform: translateY(-1px); box-shadow: var(--schatten-hoch); }

.knopf-rand {
  background: var(--papier); color: var(--tinte); border-color: var(--linie-stark);
}
.knopf-rand:hover { border-color: var(--wasser); color: var(--wasser-tief); background: var(--wasser-hauch); }

.bahn-tief .knopf-rand { background: transparent; color: #FFFFFF; border-color: rgba(255,255,255,.4); }
.bahn-tief .knopf-rand:hover { background: rgba(255,255,255,.1); color: #FFFFFF; border-color: #FFFFFF; }

/* Warmer Knopf: fuer den WhatsApp-Weg, damit er sich vom Hauptknopf
   unterscheidet, ohne mit ihm zu konkurrieren. */
.knopf-warm {
  background: var(--licht-blass); color: var(--licht-text);   /* 5,9:1 */
  border-color: #EBD5B4;
}
.knopf-warm:hover { background: #F6E6CE; color: #5A320A; border-color: #DFC299; }

.knopf-reihe { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }

.karte {
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--r-gross);
  padding: var(--s6);
  /* Neu seit dem siebenunddreissigsten Umbau. Vorher stand hier kein
     box-shadow: die Karte lag flach auf dem Grund und hob sich nur
     ueber ihren Rand ab. Der Schatten kam erst beim Ueberfahren mit
     der Maus, also nie auf einem Handy. */
  box-shadow: var(--schatten);
  transition: border-color var(--takt), box-shadow var(--takt), transform var(--takt);
}

/* Die Hauptleistungskarte ist die hervorgehobene. Sie steht als
   einzige ueber die volle Breite, sie traegt die Leistung, mit der
   der Betrieb sein Geld verdient, und sie soll sichtbar ueber den
   vier Bildkarten darunter liegen. */
.leistung-gross { box-shadow: var(--schatten-stark); }

/* Nur mit einer Maus. Auf einem Tastschirm bleibt ein :hover nach dem
   Antippen haengen, und die Karte steht dann dauerhaft angehoben da,
   ohne dass jemand versteht warum. */
@media (hover: hover) and (pointer: fine) {
  .karte-hebt:hover {
    border-color: var(--linie-stark);
    box-shadow: var(--schatten-hoch);
    transform: translateY(-2px);
  }
  .leistung-gross.karte-hebt:hover { box-shadow: var(--schatten-hoch); }
}

/* Bei reduzierter Bewegung bleibt der Schatten, der Versatz faellt
   weg. Der Block weiter oben setzt nur die Dauer auf null; die Karte
   spraenge dann ohne Uebergang zwei Pixel hoch, und genau das ist
   die Bewegung, die hier stoert. */
@media (prefers-reduced-motion: reduce) {
  .karte-hebt:hover { transform: none; }
}

.raster { display: grid; gap: var(--s5); }
.raster-3 { grid-template-columns: repeat(3, 1fr); }
.raster-2 { grid-template-columns: repeat(2, 1fr); }
.raster-4 { grid-template-columns: repeat(4, 1fr); }

/* Symbolflaeche */
.symbol {
  width: 54px; height: 54px; border-radius: 15px;
  display: grid; place-items: center;
  background: var(--wasser-blass);
  color: var(--wasser-tief);
  margin-bottom: var(--s5);
  flex: none;
}
.symbol svg { width: 28px; height: 28px; }
.symbol-warm { background: var(--licht-blass); color: var(--licht-text); }

/* ============================================================
   4. Abschnitte der Startseite
   ============================================================ */

/* ---------- Kopfzeile ---------- */
.kopfzeile {
  position: sticky; top: 0; z-index: 60;
  background: rgba(251,252,252,.9);
  backdrop-filter: saturate(1.4) blur(12px);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--takt), box-shadow var(--takt);
}
.kopfzeile.geschoben { border-bottom-color: var(--linie); box-shadow: 0 1px 12px rgba(11,43,51,.05); }
.kopfzeile-innen {
  /* Der Innenabstand liegt hier auf demselben Element wie die
     Hoechstbreite, beim Hauptinhalt dagegen auf der Bahn darum herum.
     Mit blossem max-width:--breit war der Inhalt der Kopfzeile
     gemessen 1280 px breit, der Hauptinhalt 1360, Marke und Menue
     standen also beidseitig 40 px weiter innen als alles darunter. */
  max-width: calc(var(--breit) + var(--rand) * 2); margin: 0 auto;
  padding: var(--s3) var(--rand);
  display: flex; align-items: center; gap: var(--s5);
}

.marke { display: flex; align-items: center; gap: var(--s3); text-decoration: none; color: var(--tinte); flex: none; }
/* Bis zum dreissigsten Umbau stand hier ein SVG, dessen Striche
   ueber color eingefaerbt wurden: var(--wasser-tief) in der
   Kopfzeile, #7FB6C4 in der Fusszeile. Jetzt ist es ein Bild und
   bringt seinen eigenen dunklen Grund mit. Die Rundung steckt in
   der Datei, nicht in dieser Regel: so bleibt sie auch dann,
   wenn das Bild einmal ohne Stilvorlage geladen wird. */
.marke-zeichen { width: 30px; height: 30px; flex: none; display: block; }
.marke-text { display: flex; flex-direction: column; line-height: 1.08; }
.marke-text strong {
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.24rem; font-weight: 600; letter-spacing: -.02em;
}
.marke-text span { font-size: 11.5px; letter-spacing: .17em; text-transform: uppercase; color: var(--leise); font-weight: 600; }
.marke-hell { color: #FFFFFF; }
/* Die naechste Zeile faerbte die Striche des alten SVG fuer den
   dunklen Grund um. Seit dem dreissigsten Umbau ist die Marke ein
   Bild, color greift dort nicht. Die Zeile bleibt stehen, sie schadet
   nichts und waere beim Zurueckdrehen wieder noetig. */
.marke-hell .marke-zeichen { color: #7FB6C4; }
.marke-hell .marke-text span { color: #9FBCC3; }

.hauptmenue { margin-left: auto; display: flex; align-items: center; gap: var(--s6); }
.hauptmenue a { color: var(--text); text-decoration: none; font-weight: 550; font-size: 16px; }
.hauptmenue a:hover { color: var(--wasser-tief); text-decoration: underline; text-underline-offset: 5px; }
/* Der Anrufknopf ist ein Knopf, kein Menuepunkt. Ohne diese Zeile
   gewinnt die Regel darueber nach Spezifitaet und der Knopf haette
   dunklen Text auf dunklem Grund, gemessen 1,74:1. */
.hauptmenue a.knopf-voll { color: #FFFFFF; }
.hauptmenue a.knopf-voll:hover { color: #FFFFFF; text-decoration: none; }
/* Beide Namen, mit Absicht. Auf der Startseite traegt der Knopf seit
   dem zwanzigsten Umbau die Anfrage, auf Impressum und Datenschutz
   weiter die Telefonnummer: dort gibt es kein Formular, auf das er
   springen koennte. Beim Umbenennen war .kopf-anruf zuerst ohne jede
   Regel geblieben, der Knopf der beiden Rechtsseiten fiel damit auf
   die Grundwerte von .knopf zurueck und war gemessen 54 statt 46 px
   hoch. */
.hauptmenue a.kopf-anfrage,
.kopf-anfrage, .kopf-anruf { font-size: 15px; padding: 11px var(--s5); min-height: 46px; }
.kopf-anfrage:hover, .kopf-anruf:hover { text-decoration: none; color: #fff; }

/* Der Anrufweg, schlicht. Kein zweiter gefuellter Knopf: zwei gleich
   laute Knoepfe nebeneinander lassen den Leser waehlen, statt ihn zu
   fuehren. Die Trefferflaeche bleibt trotzdem 46 px hoch.

   Der Selektor nennt .hauptmenue, weil der Link darin steht: .hauptmenue a
   hat zwei Klassen plus Typ und schlaegt ein blosses .kopf-telefon.
   Ohne diese Schaerfe blieben Farbe und Schriftschnitt wirkungslos, und
   die Nummer sah aus wie ein gewoehnlicher Menuepunkt. Gemessen: gleiche
   Farbe rgb(23,50,58), gleiche Staerke 550 wie die Punkte daneben. */
.hauptmenue a.kopf-telefon, .kopf-telefon {
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: 46px; padding: 11px 0;
  color: var(--wasser-tief); font-weight: 600; font-size: 15px;
  text-decoration: none; white-space: nowrap;
}
.kopf-telefon svg { width: 17px; height: 17px; flex: none; }
.hauptmenue a.kopf-telefon:hover, .kopf-telefon:hover { color: var(--tinte); text-decoration: underline; text-underline-offset: 5px; }

.menue-knopf {
  display: none; margin-left: auto;
  width: 48px; height: 48px; border-radius: var(--r);
  background: var(--papier); border: 1px solid var(--linie-stark);
  color: var(--tinte); cursor: pointer;
}
.menue-knopf svg { width: 24px; height: 24px; margin: 0 auto; }

/* ---------- Hero ----------
   Dunkles Feld seit dem dreizehnten Umbau. Der Hero hat kein Foto und
   brauchte etwas, das die Flaeche traegt. Ein Verlauf war es nicht:
   drei Anlaeufe wurden gemessen, der sichtbarste kam auf dem Handy auf
   6,86:1 und riss die Hausmarke. Die Flaeche selbst traegt.

   Aufbau: links Auszeichnung, Ueberschrift, Unterzeile, Knoepfe.
   Rechts die vier Merkmale als 2x2. Auf dem Handy stapelt beides.

   Der weisse Knopf steht mit 14,9:1 gegen den Grund und ist damit das
   auffaelligste Element der Bahn, gemessen als Flaeche mal Kontrast
   gegen die naehere Umgebung. Auf hellem Grund kam kein Knopf ueber
   7,6:1. */
.hero {
  position: relative;
  overflow: hidden;
  background: var(--tinte);
  padding: var(--s8) 0;
}

/* Eine sehr weite, sehr schwache Aufhellung von oben links. Gibt der
   Flaeche Tiefe, ohne als Verlauf erkennbar zu werden. Sie lag bei
   0,16 und hob den Grund genau dort, wo die Auszeichnung steht: der
   Ocker fiel damit auf 6,86:1. Bei 0,11 steht er bei 7,9:1. */
.hero::before {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(90% 120% at 6% -20%,
              rgba(120,190,210,.11) 0%, rgba(11,43,51,0) 62%);
}

.hero-innen {
  position: relative; z-index: 1;
  max-width: var(--breit);
  margin: 0 auto;
  padding: 0 var(--rand);
  display: grid;
  grid-template-columns: minmax(0, 1fr) 420px;
  gap: clamp(40px, 4.5vw, 64px);
  align-items: center;
}

.hero .kicker { color: var(--tief-ocker); margin-bottom: var(--s5); }
.hero .kicker::before { background: var(--tief-ocker); }

/* Die Displayschrift laeuft nur hier und in keiner Zeile unter 40 px.
   Bei kleineren Graden traegt der hohe Strichkontrast nicht mehr, und
   die Zielgruppe ist ueberwiegend zwischen 45 und 70. */
.hero h1 {
  font-family: 'Display', 'Serife', Georgia, serif;
  font-weight: 400;
  font-size: clamp(2.3rem, 1.15rem + 3.6vw, 5.875rem);
  line-height: .98;
  letter-spacing: -.012em;
  color: #FFFFFF;
  margin: 0 0 var(--s6);
  text-wrap: initial;
}
.hero h1 em { font-style: italic; color: var(--tief-ocker); }

/* Die drei Zeilen sind gesetzt, nicht gefallen: "Klare Sicht." allein,
   dann die beiden Haelften des zweiten Satzes. Unter 700 px ist die
   Spalte zu schmal dafuer, dort laeuft der Umbruch wieder frei.

   Vor jedem <br> steht im Quelltext ein Leerzeichen. Solange der
   Umbruch gilt, faellt es weg; sobald er auf display:none steht,
   trennt es die Woerter. Ohne das Leerzeichen las sich die
   Ueberschrift auf dem Handy als "Sicht.Ohne" und "selbstauf". */
.hero h1 br { display: inline; }

.hero-lead {
  color: var(--tief-leise);
  margin: 0 0 var(--s6);
  max-width: 34em;
}
.hero-knoepfe { gap: var(--s3); }
.wa-kurz { display: none; }

/* Auf dem dunklen Grund tauschen die Knoepfe die Rollen: der
   Hauptknopf wird zur hellen Flaeche, der zweite zur Kontur. */
.hero .knopf-voll {
  background: #FFFFFF; color: var(--tinte);
  box-shadow: 0 10px 30px rgba(0,0,0,.28);
}
.hero .knopf-voll:hover {
  background: var(--licht-blass); color: var(--tinte);
  box-shadow: 0 14px 34px rgba(0,0,0,.34);
}
.hero .knopf-rand {
  background: transparent; color: #FFFFFF;
  border-color: rgba(255,255,255,.45);
}
.hero .knopf-rand:hover {
  background: rgba(255,255,255,.1); color: #FFFFFF; border-color: #FFFFFF;
}

/* Die Regeln der rechten Spalte stehen weiter unten unter
   "Rechte Hero-Spalte". Hier standen bis zum achtzehnten Umbau die
   vier Kacheln. */

/* ---------- Rechte Hero-Spalte ----------
   Aufbau von oben nach unten: Bewertungszeile, die vier Merkmale, drei
   Kundenstimmen.

   Bis zum achtzehnten Umbau standen die Merkmale als vier Kacheln zu
   204 x 112 px da: 248 px Hoehe fuer acht Zeilen Text, also fast nur
   Rahmen. Jetzt eine schlichte Liste ohne Rahmen und ohne Flaeche. */

/* Die rechte Spalte als ein Rasterkind.

   align-items bleibt auf stretch. Mit flex-start schrumpfen die Kinder
   auf ihre Inhaltsbreite: die Merkmalliste war dann nicht 420 px breit,
   sondern so schmal wie moeglich, und lief auf 542 px Hoehe auf. Nur
   die Bewertungszeile soll sich auf ihren Inhalt begrenzen. */
.hero-rechts { display: flex; flex-direction: column; }
.bewertungszeile { align-self: flex-start; }

/* 1  Bewertungszeile. Schmale Zeile, kein Kasten. */
.bewertungszeile {
  display: inline-flex; align-items: center; gap: var(--s3);
  /* Der Auftrag nennt etwa 40 px. Es sind 44, weil die Zeile ein Link
     ist und jede Klickflaeche auf dem Handy seit dem ersten Auftrag
     mindestens 44 px hoch sein muss. Sichtbar sind davon rund 22 px
     Inhalt, der Rest ist Greifflaeche. */
  min-height: 44px;
  text-decoration: none;
}
.bewertungszeile:hover .bewertungswert { color: var(--tief-ocker); }
.g-zeichen {
  width: 22px; height: 22px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%; background: #FFFFFF;
  color: var(--tinte); font-weight: 800; font-size: 14px; line-height: 1;
}
.sterne { display: inline-flex; gap: 2px; flex: none; }
.sterne svg { width: 15px; height: 15px; fill: #F0B429; }
.sterne-klein svg { width: 13px; height: 13px; }
.bewertungswert {
  font-size: var(--t-klein); font-weight: 650; color: #FFFFFF;
  line-height: 1.3; transition: color var(--takt);
}
.bewertungsquelle { font-weight: 400; color: var(--tief-leise); }

/* 2  Die vier Merkmale, einspaltig.

      Beide Fassungen sind gebaut und gemessen worden, Vergleich in
      _pruefung/tafel-18-merkmale.jpg:

        einspaltig    117 px, jedes Merkmal auf einer Zeile
        zweispaltig    93 px, jedes Merkmal auf zwei Zeilen

      Zweispaltig ist also kuerzer, aber bei 202 px Spaltenbreite
      bricht jeder der vier Texte um. Vier zweizeilige Eintraege mit
      unterschiedlich langen zweiten Zeilen lesen sich unruhiger als
      vier einzeilige. Beide liegen unter der Grenze von 120 px,
      deshalb entscheidet das Bild und nicht die Zahl. */
/* Groesser und luftiger seit dem dreiundzwanzigsten Umbau. Ohne die
   drei Platzhalter-Stimmen traegt die rechte Spalte nur noch 185 px
   in einer 480 px hohen Zeile; die vier Merkmale sind jetzt das, was
   sie fuellt, und duerfen nicht mehr wie Kleingedrucktes aussehen.
   Auf dem Handy bleibt es eng, dort zaehlt jeder Pixel bis zur
   Anrufleiste. */
.hero-punkte {
  list-style: none; margin: var(--s6) 0 0; padding: 0;
  display: grid; grid-template-columns: 1fr;
  gap: var(--s4);
}
/* Nur fuer den Vergleich, per Klasse zugeschaltet. */
.hero-punkte.zweispaltig {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s3) var(--s4);
}
.hero-punkte li {
  display: flex; align-items: flex-start; gap: var(--s3);
  font-size: 16px; font-weight: 550; color: #FFFFFF; line-height: 1.4;
}

/* Ohne feste Masse waechst ein SVG ohne width-Attribut auf die Breite
   seines Elternteils und wird quadratisch: das Haekchen war 271 x 271
   und trieb die Liste auf 1118 px. Die Regel stand im Block, den der
   achtzehnte Umbau ersetzt hat. */
.haken-zeichen {
  width: 18px; height: 18px; flex: none;
  color: var(--tief-ocker);
  margin-top: 1px;
}

/* Die Zusage ueber den Hero-Knoepfen. Bis zum dreiundzwanzigsten
   Umbau stand sie darunter, in 14,5 px und var(--tief-leise), also
   rgb(180, 203, 209). Sie war damit die leiseste Zeile des Hero und
   stand hinter drei grossen Knoepfen: gemessen 9,35:1, aber Kontrast
   ist nicht Auffaelligkeit.

   Jetzt in Fliesstextgroesse und in var(--tief-hell). Sie ist kein
   Kleingedrucktes mehr, sondern der letzte Satz vor der
   Entscheidung. */
.hero-zusage {
  margin: 0 0 var(--s4);
  font-size: 16px; line-height: 1.5;
  color: var(--tief-hell); font-weight: 500;
}

/* 3  Drei Kundenstimmen. Keine Kaesten, nur Haarlinien dazwischen. */
.hero-stimmen { margin-top: var(--s5); }
.hero-stimmen ul { list-style: none; margin: 0; padding: 0; }
/* Als Block gerechnet blieb je Stimme ein Rest von 17 px uebrig, den
   keine Regel erklaerte: die Zeilenschachtelung zwischen Liste,
   Blockzitat und Absatz. Als Flexspalte gibt es diesen Rest nicht,
   und die Abstaende stehen genau dort, wo sie gesetzt sind. */
.hero-stimme {
  padding: var(--s2) 0;
  display: flex; flex-direction: column; gap: 5px;
}
.hero-stimme blockquote { margin: 0; }
.hero-stimme-wer { margin: 0; }
.hero-stimme + .hero-stimme { border-top: 1px solid rgba(255,255,255,.15); }

.hero-stimme blockquote p {
  margin: 0; font-size: var(--t-klein); line-height: 1.5;
  color: var(--tief-leise);
}
.hero-stimme-wer { font-size: var(--t-mini);
  color: var(--tief-leise); opacity: .85;
}

/* Der Hinweis auf der Bewertungszeile. Nur dort sichtbar, wo die Zeile
   auch etwas oeffnet, also auf dem Handy. */
.bewertungs-hinweis {
  display: none; align-items: center; gap: 3px;
  font-size: var(--t-mini); font-weight: 600; color: var(--tief-ocker);
}
.bewertungs-hinweis svg { width: 13px; height: 13px; }
/* Solange die Stimmen ausgeblendet sind, fuehrt der Hinweis
   "ansehen" ins Leere. Die Klasse setzt js/seite.js. */
.ohne-stimmen .bewertungs-hinweis { display: none !important; }

/* ---------- Ebene mit den Kundenstimmen ----------
   Nur auf dem Handy im Einsatz. Sie faehrt von unten ein und legt sich
   ueber die Seite; dahinter wird abgedunkelt und die Seite haelt an.

   <dialog> statt eines eigenen Kastens: Escape, die Abdunklung und die
   Fokusfalle kommen damit vom Browser und nicht aus einer Nachbildung,
   die man pflegen muss. */
.stimmen-ebene {
  border: 0; padding: 0; margin: 0 0 auto;
  position: fixed; inset: auto 0 0 0;
  width: 100%; max-width: 100%; max-height: 82vh;
  background: var(--tinte);
  border-radius: var(--r-gross) var(--r-gross) 0 0;
  color: #FFFFFF;
  overflow: auto;
  transform: translateY(100%);
  transition: transform 300ms cubic-bezier(.22,.61,.36,1);
}
.stimmen-ebene[open] { transform: translateY(0); }
.stimmen-ebene::backdrop { background: rgba(4,18,22,.62); }

.stimmen-ebene-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4);
  padding: var(--s5) var(--s5) 0;
}
.stimmen-ebene-titel {
  margin: 0; font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.15rem; color: #FFFFFF; line-height: 1.3;
}
.stimmen-schliessen {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  background: rgba(255,255,255,.1); color: #FFFFFF;
  border: 1px solid rgba(255,255,255,.22);
  border-radius: 50%; cursor: pointer;
  transition: background var(--takt), border-color var(--takt);
}
.stimmen-schliessen:hover { background: rgba(255,255,255,.2); border-color: #FFFFFF; }
.stimmen-schliessen svg { width: 19px; height: 19px; }
#stimmen-ziel { padding: 0 var(--s5) var(--s6); }
#stimmen-ziel .hero-stimmen { margin-top: 0; }

@media (max-width: 960px) {
  .bewertungs-hinweis { display: inline-flex; }
}
@media (prefers-reduced-motion: reduce) {
  .stimmen-ebene { transition: none; transform: none; }
}

/* ---------- Einsatzgebiet in der Fusszeile ----------
   Kraeftiger als der umgebende Text: er nimmt einen Zweifel, der genau
   hier entsteht, wenn eine Dattelner Adresse sichtbar wird. */
.fuss-gebiet {
  color: #FFFFFF; font-weight: 600;
  margin: 0 0 var(--s4);
  padding-left: var(--s4);
  border-left: 3px solid var(--tief-ocker);
}

/* ---------- Klappbloecke ----------
   Benutzt von den drei Bloecken der Hauptleistung und vom Vorspann des
   Kontaktabschnitts. Steht bewusst nicht im Leistungsblock: beim
   Neuschreiben dieses Blocks im fuenfzehnten Umbau sind diese Regeln
   einmal mit entfernt worden, und danach nahmen die Anrisse auf dem
   Rechner Klicks an.

   Im Anriss steht der erste Satz, im Rumpf der Rest. Auf dem Rechner
   laeuft beides als ein Absatz weiter: Anriss und Rumpf stehen dort
   inline, die Luecke zwischen ihnen ist das Leerzeichen aus dem
   Quelltext. Der Block bleibt dort immer offen und nimmt keine Klicks
   an.

   Ohne JavaScript sind alle Bloecke offen. Der Inhalt ist dann
   vollstaendig da, die Seite nur laenger. Zuklappen geht trotzdem,
   das kann <details> von sich aus. */
.block-klapp > summary {
  list-style: none;
  color: var(--leise); font-size: 15.5px; line-height: 1.55;
}
.block-klapp > summary::-webkit-details-marker { display: none; }

@media (min-width: 961px) {
  .block-klapp > summary,
  .block-klapp > p { display: inline; }
  .block-klapp > summary { pointer-events: none; }
}

@media (max-width: 960px) {
  .block-klapp > summary {
    cursor: pointer;
    position: relative;
    padding-right: 34px;
    min-height: 44px;
    display: flex; align-items: center;
  }
  /* Derselbe Pfeil wie bei den Fragen, damit auf der Seite nur ein
     Zeichen fuer "hier steckt mehr dahinter" vorkommt. */
  .block-klapp > summary::after {
    content: ""; position: absolute; right: 8px; top: 50%;
    width: 10px; height: 10px; margin-top: -7px;
    border-right: 2.2px solid var(--wasser);
    border-bottom: 2.2px solid var(--wasser);
    transform: rotate(45deg); transition: transform var(--takt-frage);
  }
  .block-klapp[open] > summary::after { transform: rotate(-135deg); margin-top: -2px; }
  .block-klapp[open].schliesst > summary::after { transform: rotate(45deg); margin-top: -7px; }
  .block-klapp > p { margin-top: var(--s3); overflow: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .block-klapp > summary::after { transition: none; }
}

/* Der Vorspann des Kontaktabschnitts benutzt dieselbe Mechanik,
   braucht darin aber seine eigene Schriftgroesse. */
.klapp-lead > .block-klapp > summary,
.klapp-lead > .block-klapp > p {
  font-size: var(--t-lead); line-height: 1.6; color: var(--leise);
}
.klapp-lead > .block-klapp > p { margin: 0; }

/* ---------- Leistungen ----------
   Alle fuenf Karten sind seit dem neunzehnten Umbau dieselbe Karte.
   Die Hauptleistung spannt zwei Spalten und darf ein Bild haben, aber
   sie benutzt .karte wie die anderen: dieselbe Rundung, derselbe
   Rahmen, derselbe Innenabstand, dieselbe Typografie, dasselbe
   Anheben beim Ueberfahren.

   Der Grund, warum sie vorher nicht dazugehoerte, war nicht die
   Breite, sondern die Textmenge: 966 Zeichen gegen 165 in den kleinen
   Karten, also das Sechsfache. */
/* Drei Spalten, nicht vier. Bei vier Spalten belegen fuenf Karten,
   von denen eine zwei Spalten spannt, sechs von acht Zellen: unten
   rechts blieben 475 px tote Flaeche. Bei drei Spalten gehen genau
   zwei Reihen auf, ohne Rest. */
#leistungen > .mitte {
  display: grid;
  /* Vier Spalten seit dem dreiundzwanzigsten Umbau. Bei drei Spalten
     musste die Hauptleistung zwei davon spannen, und daneben stand
     eine einzelne Bildkarte, die sie auf 480 px zog. Nahm man ihr das
     weg, blieben 206 px Loch unter ihr. Bei vier Spalten liegt sie
     als eigene Zeile oben, die vier Bildkarten bilden eine Zeile,
     Schaufenster schliesst ab: drei volle Zeilen, kein Loch. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s5);
  /* Bleibt stretch, und das ist seit der Umstellung auf vier Spalten
     wieder richtig: In keiner Zeile steht mehr eine Textkarte neben
     einer Bildkarte. Die Hauptleistung und Schaufenster haben ihre
     Zeile fuer sich und damit ihre eigene Hoehe, die vier Bildkarten
     teilen sich eine Zeile und sollen dort gleich hoch sein.

     Mit align-items: start standen sie 427 bis 451 px hoch
     nebeneinander, also unten ausgefranst. */
  align-items: stretch;
}
#leistungen .kopf-block { grid-column: 1 / -1; margin-bottom: 0; }
/* Die Huelle der vier kleinen Karten reicht ihre Kinder an das Raster
   durch, damit alle fuenf in derselben Zeilenrechnung liegen. */
.leistung-klein { display: contents; }
.leistung-gross { grid-column: 1 / -1; }
/* Innen zweispaltig: links der Text, rechts die vier Haekchen und der
   Satz zu den Ladenlokalen. Untereinander kam die Karte auf 531 px,
   nebeneinander auf 289. Die Grenze im Auftrag liegt bei 340, und
   gestrichen werden sollte nichts weiter. */
.leistung-gross {
  display: grid;
  /* 1,1 zu 0,9 ist gemessen die beste Aufteilung: bei 1,3 zu 0,7
     bricht "Auf Wunsch Insektengitter und Fensterlaeden" rechts auf
     drei Zeilen und die Karte waechst von 416 auf 512 px. */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: var(--s6);
  padding: var(--s6);
  /* Hier stand align-content: center. Es verteilte die 206 px, die
     die Nachbarkarte der Hauptleistung aufzwang, auf oben und unten.
     Seit das Raster align-items: start hat, gibt es die 206 px nicht
     mehr und die Zeile ist gegenstandslos. */
}
.leistung-gross .karte-inhalt { padding: 0; }
.leistung-gross .karte-inhalt p + p { margin-top: var(--s3); }
.leistung-gross-neben { display: flex; flex-direction: column; justify-content: center; }
.leistung-gross-neben .haken { margin-top: 0; }
/* Der Satz zu den Ladenlokalen spannt beide Spalten. In der schmalen
   rechten Spalte lief er auf vier Zeilen. */
/* Hier stand die Regel fuer den Ladenlokal-Satz in der Hauptleistung.
   Der Satz ist entfernt, die Karte hat keine dritte Zeile mehr. Damit
   ist auch align-content: space-between oben wirkungslos geworden, es
   verteilt jetzt nur noch eine Zeile. */

@media (max-width: 960px) {
  .leistung-gross { grid-template-columns: 1fr; gap: var(--s5); }
}

/* Die Nutzenzeile unter jeder Ueberschrift. Kleiner als die
   Ueberschrift, groesser als der Fliesstext, in der warmen
   Akzentfarbe: sie sagt, warum die Leistung jemanden angeht, die
   Beschreibung darunter sagt, was sie ist. */
/* Die fuenfte Karte spannt alle drei Spalten. Damit geht die
   Rechnung des Rasters wieder auf: zwei Zellen fuer die
   Hauptleistung, vier fuer die kleinen Karten, drei fuer diese, also
   genau neun von neun. Mit einer sechsten Karte in einer Spalte
   blieben zwei Zellen leer. */
/* Wie karte-bild: der Rand kommt aus .karte-inhalt, nicht aus der
   Karte selbst. Ohne padding:0 addieren sich beide, und die
   Ueberschrift stand 57 px vom Rand statt 25 wie in den vier
   Karten darueber. */
.leistung-breit { grid-column: 1 / -1; padding: 0; }
/* Ueber die volle Breite laesst ein einspaltiger Text rechts 496 px
   leer stehen, gemessen. Deshalb steht die Ueberschrift mit ihrer
   Nutzenzeile links, der Satz daneben. Dieselbe Aufteilung wie in der
   Hauptleistung, nur ohne Haekchen. */
.leistung-breit .karte-inhalt {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  column-gap: var(--s7);
  align-items: start;
}
.leistung-breit .karte-inhalt h3 { grid-column: 1; grid-row: 1; }
.leistung-breit .karte-inhalt .karte-nutzen { grid-column: 1; grid-row: 2; margin-bottom: 0 !important; }
/* Zeile fuer Zeile in der rechten Spalte. Mit dem festen
   grid-row: 1 / span 2, das hier bis zum sechsundzwanzigsten Umbau
   stand, landeten die zwei Absaetze von "Warum von Hand" beide in
   derselben Zelle und lagen uebereinander. Ohne Zeilenangabe sucht
   sich jeder Absatz die naechste freie Zelle in Spalte zwei. */
.leistung-breit .karte-inhalt > p:not(.karte-nutzen) {
  grid-column: 2; margin-top: 0 !important;
}
.leistung-breit .karte-inhalt > p:not(.karte-nutzen) ~ p { margin-top: var(--s3) !important; }
@media (max-width: 700px) {
  .leistung-breit .karte-inhalt { display: block; }
  .leistung-breit .karte-inhalt .karte-nutzen { margin-bottom: var(--s3) !important; }
}

/* Die Zwischenzeile in der Hauptleistung. Kein h4: die Karte traegt
   schon ein h3, und eine vierte Ebene fuer zwei Absaetze waere eine
   Gliederung, die es nicht gibt. Sie sieht aus wie eine Ueberschrift
   und ist keine. */
.karte-zwischen {
  margin: var(--s4) 0 var(--s2) !important;
  font-family: var(--serife);
  font-size: 17px; font-weight: 600;
  color: var(--tinte) !important;
}

.karte-nutzen {
  margin: 0 0 var(--s3) !important;
  font-size: 15.5px;
  font-weight: 600;
  color: var(--licht-text) !important;
  line-height: 1.4;
}

@media (max-width: 960px) {
  #leistungen > .mitte { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .leistung-gross { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
  #leistungen > .mitte { gap: var(--s3); }
}

.haken { list-style: none; margin: var(--s5) 0 0; padding: 0; display: grid; gap: var(--s2); }
/* Bis zum neunzehnten Umbau zeichnete ein ::before-Kaestchen das
   Haekchen aus zwei Rahmenlinien. Seit die Punkte dasselbe SVG tragen
   wie die Merkmale im Hero, standen zwei Haekchen nebeneinander:
   ein grosses aus CSS und ein kleines aus dem SVG. Das CSS-Haekchen
   faellt weg, das SVG bleibt. */
.haken li {
  display: flex; align-items: flex-start; gap: var(--s2);
  font-size: 16px; color: var(--text); font-weight: 500;
}
.haken .haken-zeichen { color: var(--licht); }

.karte-bild { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.karte-bild img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.karte-inhalt { padding: var(--s5); flex: 1; }
.karte-inhalt h3 { font-size: 1.18rem; margin-bottom: var(--s2); }
.karte-inhalt p { color: var(--leise); font-size: 15.5px; line-height: 1.55; margin: 0; }

/* ---------- Ablauf ---------- */
.schritte {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s5);
}
.schritte li { position: relative; padding-top: 74px; }
.schritte li::after {
  content: ""; position: absolute; left: 60px; top: 27px; right: calc(var(--s5) * -1);
  height: 1px; background: #EBD9BE;
}
.schritte li:last-child::after { display: none; }
.schritt-zahl {
  position: absolute; top: 0; left: 0; z-index: 1;
  display: grid; place-items: center;
  width: 54px; height: 54px; border-radius: 50%;
  background: var(--papier); border: 1.5px solid #E3CBA6;
  color: var(--licht-text);
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.5rem; font-weight: 600;
}
.schritte h3 { margin: 0 0 var(--s2); font-size: 1.15rem; }
.schritte p { color: var(--leise); font-size: 15.5px; line-height: 1.55; margin: 0; }
/* Seit Schritt 1 zwei Absaetze hat: ohne Abstand lief der Satz zum
   Vorbeikommen ohne Absetzen an den Satz zu Formular und Foto an
   und las sich als dessen Fortsetzung. */
.schritte p + p { margin-top: var(--s3); }

/* ---------- Preise ---------- */
.preis-feld {
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--r-gross);
  overflow: hidden;
}
.preis-karten { gap: 0; }
.preis-karte { padding: var(--s7); }
/* Vier Karten in zwei Reihen. Die Trennlinien folgen dem Raster:
   rechte Karten bekommen eine linke Linie, untere eine obere. */
.preis-karte:nth-child(2n) { border-left: 1px solid var(--linie); }
.preis-karte:nth-child(n+3) { border-top: 1px solid var(--linie); }
.preis-fall {
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--leise); margin-bottom: var(--s3);
}
.preis-karte h3 { font-size: 1.5rem; margin-bottom: var(--s2); }
.preis-menge { color: var(--leise); font-size: 16px; margin-bottom: var(--s5); }
.preis-zahl {
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.7rem);
  font-weight: 600; color: var(--wasser-tief); letter-spacing: -.02em;
  line-height: 1.1; margin: 0;
}

.preis-hinweis { background: var(--licht-hauch); border-top: 1px solid #F0E2CC; padding: var(--s6) var(--s7); }
.preis-marke {
  display: inline-block; margin-bottom: var(--s3);
  background: var(--licht-blass); color: var(--licht-text);
  border: 1px solid #EBD5B4; border-radius: 999px;
  padding: 5px 14px; font-size: var(--t-mini); font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
}
.preis-hinweis p { color: var(--text); font-size: 16.5px; max-width: var(--lesebreite); }
.preis-klein { color: var(--leise); font-size: var(--t-klein); margin-top: var(--s4); }

/* ---------- Warum eine Person ---------- */
.person-innen {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .72fr);
  gap: clamp(32px, 5vw, 72px); align-items: stretch;
}
.person-text p { color: #C6DADF; font-size: 16.5px; max-width: var(--lesebreite); }
.person-text .lead { color: #DCE8EB; }
/* Das Bild fuellt die Hoehe der Textspalte. Zentriert blieben unten
   66 px tote Flaeche stehen, gemessen mit _pruefung/luecken.py. */
.person-bild { display: flex; }
.person-bild img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%;
  /* Der Schatten war ein Einzelwert (0 18px 44px, 30 Prozent
     Schwarz) und der einzige auf der Seite, der nicht aus den Tokens
     kam. Auf dunklem Grund braucht er mehr Tiefe als --schatten-hoch,
     deshalb dieselbe Form, nur dunkler. */
  border-radius: var(--r-gross);
  box-shadow: 0 2px 6px rgba(0,0,0,.22), 0 14px 38px rgba(0,0,0,.34);
}

/* Ersetzt die frueher hier stehende Stichpunktliste. Die las sich wie
   ein Datenblatt. Als Absatz mit warmer Kante bleibt der Block visuell
   ein eigener Halt, spricht aber in ganzen Saetzen. */
.gegenrede {
  margin: var(--s6) 0 0;
  padding: var(--s4) 0 var(--s4) var(--s5);
  border-left: 3px solid #F0C58A;
  font-size: 1.06rem;
  line-height: 1.6;
  color: #DCE8EB;
  max-width: var(--lesebreite);
}
.person-text .gegenrede { color: #DCE8EB; }

/* ---------- Handlungsstreifen ----------
   Bewusst keine eigene Bahn mit eigener Farbe: die Seite hat schon ein
   dunkles und ein warmes Feld, ein drittes waere zu viel. Zwei
   Haarlinien auf dem Seitengrund und eine Zeile Text.

   Auf dem Rechner stehen Text und Knoepfe nebeneinander, auf dem Handy
   untereinander. Zielhoehe unter 220 px. */
.handlungsstreifen {
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
  background: var(--grund);
  padding: var(--s6) var(--rand);
}
.streifen-innen {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--s5);
}
.streifen-text { max-width: 52ch; }
.streifen-text h2 {
  font-size: clamp(1.32rem, 1.1rem + .9vw, 1.7rem);
  margin: 0 0 var(--s2);
}
.streifen-text p { margin: 0; color: var(--leise); font-size: 16.5px; }
.streifen-knoepfe { flex: none; }

@media (max-width: 700px) {
  .handlungsstreifen { padding: var(--s5) var(--rand); }
  .streifen-innen { gap: var(--s4); }
  .streifen-text h2 { margin-bottom: var(--s1); }
  .streifen-knoepfe { width: 100%; flex-wrap: nowrap; }
  /* Die allgemeine Regel unter 520 px stellt Knoepfe auf volle Breite
     und damit uebereinander. Hier nicht: die beiden Beschriftungen
     brauchen zusammen rund 300 px und passen nebeneinander. Gestapelt
     waere der Streifen 269 statt 213 px hoch. */
  .streifen-knoepfe .knopf { width: auto; flex: 1 1 auto; padding-inline: var(--s4); }
}

/* ---------- Einzugsgebiet ----------
   Ohne Bild seit dem elften Umbau, dadurch eine Spalte ueber die
   volle Breite. Die Ortsliste gewinnt dabei am meisten: bei 1360 px
   passen elf Orte in eine Reihe statt vier. */
.gebiet-innen { display: block; }/* Die Unterzeile lief mit 133 Zeichen ueber die volle Breite. Der
   Absatz zur Anfahrt darunter haelt sich an die Lesebreite, die
   Unterzeile darueber nicht. */
#gebiet .gebiet-text > .lead { max-width: var(--lesebreite); }


.orte { margin-top: var(--s6); }
.orte-titel {
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--leise); margin-bottom: var(--s3);
}
.orte-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--s2); }
.orte-liste li {
  background: var(--papier); border: 1px solid var(--linie);
  border-radius: 999px; padding: 5px 14px; font-size: var(--t-klein); color: var(--text);
}
/* Der weitere Umkreis klappt auf dem Handy zu. Ausgeschrieben sind
   38 Ortspillen dort ueber zwoelf Zeilen, und wer seinen Ort in der
   ersten Gruppe findet, braucht die zweite nicht. */
.orte-klapp > summary { list-style: none; cursor: pointer; }
.orte-klapp > summary::-webkit-details-marker { display: none; }
.orte-schluss {
  margin: var(--s5) 0 0; color: var(--leise); font-size: 16.5px;
  max-width: var(--lesebreite);
}
/* Der Satz zu den Ladenlokalen schliesst den Abschnitt ab, deshalb
   die Haarlinie darueber: erst die Privatkunden, dann als Nachsatz die
   Laeden. Hier stand zuerst zusaetzlich grid-column: 1 / -1. Das war
   ein Pflaster auf ein fehlendes </div> im Gebietsabschnitt, nicht die
   Behebung. Das Tag ist jetzt gesetzt, die Zeile deshalb weg. */
.orte-gewerbe {
  margin-top: var(--s4);
  padding-top: var(--s4);
  border-top: 1px solid var(--linie);
}

@media (min-width: 961px) { .orte-klapp > summary { pointer-events: none; } }

@media (max-width: 960px) {
  .orte-klapp > summary {
    position: relative; padding-right: 34px; min-height: 44px;
    display: flex; align-items: center;
  }
  .orte-klapp > summary::after {
    content: ""; position: absolute; right: 8px; top: 50%;
    width: 10px; height: 10px; margin-top: -7px;
    border-right: 2.2px solid var(--wasser);
    border-bottom: 2.2px solid var(--wasser);
    transform: rotate(45deg); transition: transform var(--takt-frage);
  }
  .orte-klapp[open] > summary::after { transform: rotate(-135deg); margin-top: -2px; }
  .orte-klapp[open].schliesst > summary::after { transform: rotate(45deg); margin-top: -7px; }
}

.orte-nah li { background: var(--wasser-blass); border-color: #C5DFE6; color: var(--tinte); font-weight: 600; }

/* Die beiden Gruppen stehen nebeneinander. Untereinander ueber die
   volle Breite lag "Senden" als einziger Ort allein auf der letzten
   Zeile, und der Abschnitt war 41 px hoeher. Nebeneinander bekommt
   jede Gruppe zwei bis drei volle Reihen und eine eigene Spalte.
   Fotos in _screenshots/gebiet-*. */
.orte-paar {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s7); align-items: start;
}
.orte-paar .orte { margin-top: var(--s6); }

/* ---------- Ueber mich ---------- */
.ueber { text-align: center; }
.ueber .kicker { text-align: center; }
.ueber-gross { font-size: var(--t-lead); color: var(--text); line-height: 1.55; margin-bottom: var(--s4); }
.ueber p:last-child { color: var(--leise); font-size: 16.5px; }

/* ---------- Haeufige Fragen ---------- */
.fragen { border-top: 1px solid var(--linie-stark); }
.fragen details { border-bottom: 1px solid var(--linie-stark); }
.fragen summary {
  list-style: none; cursor: pointer;
  padding: var(--s5) 44px var(--s5) 0;
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.12rem; font-weight: 600; color: var(--tinte);
  position: relative; line-height: 1.35;
}
.fragen summary::-webkit-details-marker { display: none; }
.fragen summary::after {
  content: ""; position: absolute; right: 10px; top: 50%;
  width: 12px; height: 12px; margin-top: -8px;
  border-right: 2.2px solid var(--wasser); border-bottom: 2.2px solid var(--wasser);
  transform: rotate(45deg); transition: transform var(--takt-frage);
}
.fragen details[open] summary::after { transform: rotate(-135deg); margin-top: -2px; }
/* Beim Zuklappen bleibt das Element bis zum Ende der Bewegung offen,
   sonst faellt der Inhalt sofort weg. Der Pfeil soll trotzdem gleich
   zurueckdrehen, deshalb diese Klasse. */
.fragen details[open].schliesst summary::after { transform: rotate(45deg); margin-top: -8px; }

@media (prefers-reduced-motion: reduce) {
  .fragen summary::after { transition: none; }
}
.fragen summary:hover { color: var(--wasser-tief); }
/* Die Hoehe wird von js/seite.js bewegt. Der Wert kommt aus einer
   Messung des Inhalts, nicht aus einem geschaetzten max-height: bei
   langen Antworten laeuft ein zu grosser Schaetzwert erst schnell
   durch die Leere und bremst dann, das ruckelt sichtbar. */
.frage-inhalt { padding: 0 var(--s6) var(--s5) 0; overflow: hidden; }
/* Antworten haben seit dem fuenften Umbau meist zwei Absaetze: die
   Antwort im ersten, die Begruendung im zweiten. Ohne Abstand
   klebten sie aneinander. */
.frage-inhalt p { color: var(--leise); font-size: 16.5px; margin: 0; }
.frage-inhalt p + p { margin-top: var(--s3); }

/* ---------- Kontakt ---------- */
.kontakt-innen {
  display: grid; grid-template-columns: minmax(0, .86fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px); align-items: start;
}
/* Die drei Kontaktwege als Karten. Vorher stand die Nummer als
   20 px hoher Text ohne Linkfarbe da, auf dem Handy war nicht zu
   erkennen, dass sie antippbar ist. Jetzt wie der Anrufknopf in
   der Mobilnavigation: Rahmen, Akzentfarbe, Pfeil, volle Breite. */
.kontakt-wege { list-style: none; margin: var(--s6) 0 0; padding: 0; display: grid; gap: var(--s3); }
.kontakt-karte {
  display: flex; align-items: center; gap: var(--s4);
  min-height: 62px; padding: 8px var(--s4) 8px 8px;
  background: var(--papier);
  border: 1.5px solid var(--linie-stark); border-radius: var(--r);
  text-decoration: none; color: var(--wasser-tief);
  box-shadow: var(--schatten);
  transition: border-color var(--takt), box-shadow var(--takt), transform var(--takt);
}
@media (hover: hover) and (pointer: fine) {
  .kontakt-karte:hover {
    border-color: var(--wasser);
    box-shadow: var(--schatten-hoch);
    transform: translateY(-2px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .kontakt-karte:hover { transform: none; }
}
.kontakt-symbol {
  width: 46px; height: 46px; border-radius: 12px; flex: none;
  background: var(--wasser-blass); color: var(--wasser-tief);
  display: grid; place-items: center;
}
.kontakt-symbol svg { width: 22px; height: 22px; }
.kontakt-karte-text { display: flex; flex-direction: column; flex: 1; min-width: 0; line-height: 1.3; }
.kontakt-karte-text strong {
  font-size: var(--t-mini); letter-spacing: .1em;
  text-transform: uppercase; color: var(--leise); font-weight: 700;
}
.kontakt-karte-text span {
  font-size: 1.06rem; font-weight: 650; color: var(--wasser-tief);   /* 7,8:1 auf Weiss */
  text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 3px;
  overflow-wrap: anywhere;
}
.kontakt-pfeil { width: 22px; height: 22px; flex: none; color: var(--wasser-tief); }

.formular {
  background: var(--papier); border: 1px solid var(--linie);
  border-radius: var(--r-gross); padding: var(--s7);
  box-shadow: var(--schatten);
}
.formular-titel {
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.3rem; font-weight: 600; color: var(--tinte); margin-bottom: var(--s5);
}
.feld { margin-bottom: var(--s4); }
.feld-paar { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }
.feld label, .feld-haken label { display: block; font-size: var(--t-klein); font-weight: 650; color: var(--text); margin-bottom: 6px; }
.feld input, .feld select, .feld textarea {
  width: 100%; font-family: inherit; font-size: 16px; color: var(--text);
  background: var(--grund); border: 1.5px solid var(--linie-stark);
  border-radius: var(--r); padding: 12px 14px; min-height: 48px;
  transition: border-color var(--takt), box-shadow var(--takt);
}
.feld textarea { min-height: 110px; resize: vertical; line-height: 1.55; }
.feld input:focus, .feld select:focus, .feld textarea:focus {
  outline: none; border-color: var(--wasser); box-shadow: 0 0 0 3px rgba(14,110,134,.18);
}
.feld input[type="file"] { padding: 9px 12px; background: var(--wasser-hauch); }
.feld-hilfe { font-size: 14px; color: var(--leise); margin: 6px 0 0; }

.feld-haken { display: flex; gap: var(--s3); align-items: flex-start; margin: var(--s5) 0; }

/* Leistungsauswahl im Formular. Ein fieldset, damit die sechs Kaesten
   als eine Gruppe angesagt werden und nicht als sechs einzelne Fragen. */
.feld-gruppe { border: 0; margin: 0 0 var(--s4); padding: 0; }
.feld-gruppe legend {
  padding: 0; margin-bottom: var(--s3);
  font-size: var(--t-klein); font-weight: 650; color: var(--text);
}
.feld-zusatz { font-weight: 400; color: var(--leise); }
.haken-gitter { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s4); }
/* Das Kaestchen ist 44 px breit, sichtbar davon sind 24 px in der
   Mitte. Der Abstand aus .feld-haken kommt also zu 10 px
   unsichtbarem Rand hinzu, und Kaestchen und Beschriftung standen
   im Zweispalter sichtbar 22 px auseinander. */
.haken-gitter .feld-haken { margin: 0; min-height: 44px; align-items: center; gap: 0; }
.haken-gitter .feld-haken label { font-size: 14.5px; }
/* Auf dem Handy bleiben es zwei Spalten. Einspaltig standen sechs
   Kaesten untereinander und brauchten 456 px, also mehr als ein
   halber Bildschirm fuer eine Auswahl, die kein Pflichtfeld ist. Die
   Beschriftungen sind dafuer gekuerzt, damit bei halber Breite nichts
   umbricht. Die Klickflaeche bleibt bei 44 px. */
@media (max-width: 520px) {
  .haken-gitter { gap: 0 var(--s2); }
  .haken-gitter .feld-haken label { font-size: 14px; }
}
.feld-haken input { width: 20px; height: 20px; margin-top: 2px; flex: none; accent-color: var(--wasser-tief); }
.feld-haken label { font-size: 14.5px; font-weight: 400; color: var(--leise); line-height: 1.5; margin: 0; }

.formular-knopf { width: 100%; }
.formular-meldung {
  margin: var(--s4) 0 0; padding: var(--s4) var(--s5);
  background: var(--wasser-blass); border: 1px solid #A9CEd8;
  border-radius: var(--r); color: var(--tinte); font-size: 16px; font-weight: 550;
}
.formular-fuss { font-size: 14px; color: var(--leise); margin: var(--s4) 0 0; text-align: center; }

/* ---------- Fusszeile ---------- */
.fusszeile { background: var(--tinte); color: #B4CBD1; padding: var(--s8) var(--rand) var(--s6); }
.fusszeile-innen {
  display: grid; grid-template-columns: 1.6fr 1fr 1fr;
  gap: var(--s7); padding-bottom: var(--s7);
  border-bottom: 1px solid rgba(255,255,255,.13);
  max-width: var(--breit); margin: 0 auto;
}
.fusszeile p { font-size: var(--t-klein); line-height: 1.75; }
.fuss-satz { margin-top: var(--s4); max-width: 34ch; color: #9FBCC3; }
.fuss-titel {
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: #FFFFFF; margin-bottom: var(--s3);
}
.fusszeile a { color: #DCE8EB; text-decoration: none; }
.fusszeile a:hover { color: #FFFFFF; text-decoration: underline; text-underline-offset: 4px; }
.fuss-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); font-size: var(--t-klein); }
.fuss-unten {
  padding-top: var(--s5); max-width: var(--breit); margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s6); justify-content: space-between;
}
.fuss-unten p { margin: 0; font-size: 14px; color: #9FBCC3; }
.fuss-vorschau { color: #F0C58A; }

/* ---------- Feste Anrufleiste, nur Handy ---------- */
.anrufleiste { display: none; }

/* ============================================================
   5. Rechtsseiten
   ============================================================ */
.rechtsseite { padding: var(--s8) var(--rand) var(--s9); }
.rechtsseite-innen { max-width: 70ch; margin: 0 auto; }
.brotkrume { font-size: var(--t-klein); color: var(--leise); margin-bottom: var(--s6); }
.brotkrume a { color: var(--text); }
.rechtsseite h1 { font-size: clamp(1.9rem, 1.5rem + 2vw, 2.8rem); margin-bottom: var(--s3); }
.rechtsseite .stand { color: var(--leise); font-size: var(--t-klein); margin-bottom: var(--s7); }
.rechtsseite h2 {
  font-size: 1.42rem; margin: var(--s7) 0 var(--s4);
  padding-top: var(--s6); border-top: 1px solid var(--linie);
}
.rechtsseite h2:first-of-type { border-top: none; padding-top: 0; margin-top: var(--s6); }
.rechtsseite h3 { font-size: 1.12rem; margin: var(--s5) 0 var(--s3); }
.rechtsseite p, .rechtsseite li { font-size: 16.5px; color: var(--text); line-height: 1.72; }
.rechtsseite ul { padding-left: 20px; }
.rechtsseite li { margin-bottom: var(--s2); }
.rechtsseite .anschrift {
  background: var(--wasser-hauch); border: 1px solid var(--linie);
  border-radius: var(--r); padding: var(--s5); margin-bottom: var(--s4);
}
.rechtsseite .anschrift p { margin: 0; }
.platzhalter {
  background: var(--licht-blass); border: 1px solid #EBD5B4;
  border-left: 4px solid var(--licht);
  border-radius: var(--r-klein); padding: var(--s4) var(--s5); margin: var(--s4) 0;
}
.platzhalter p { margin: 0; font-size: 15.5px; color: var(--licht-text); }
.platzhalter strong { color: #6F3E0C; }

/* ============================================================
   6. Kleine Bildschirme
   ------------------------------------------------------------
   Mobil zuerst gedacht, hier nur die Abweichungen nach unten.
   Diese Zielgruppe sucht sowohl am Handy als auch am Rechner,
   die Handyfassung ist deshalb keine Sparfassung.
   ============================================================ */

@media (max-width: 1100px) {
  .raster-4 { grid-template-columns: repeat(2, 1fr); }
  .fusszeile-innen { grid-template-columns: 1fr 1fr; }
  .fuss-marke { grid-column: 1 / -1; }
}

@media (max-width: 960px) {
  :root { --bahn-luft-mobil: 32px; }

  .bahn, .bahn-eng { padding: var(--bahn-luft-mobil) var(--rand); }

  /* Der Hero stapelt: erst Text und Knoepfe, dann die Merkmale. */
  .hero { padding: var(--s7) 0; }
  .hero-innen { grid-template-columns: 1fr; gap: var(--s6); }
  .hero-lead { max-width: 46ch; }

  /* Achtung bei Aenderungen: unter 700 px steht weiter unten noch ein
     eigener Block fuer den Hero. Er muss HINTER diesem stehen, sonst
     gewinnt dieser hier. Genau das ist einmal passiert: die Regel lag
     600 Zeilen weiter oben und blieb wirkungslos. */

  /* Grosse Leistungskarte stapelt in der Quelltextreihenfolge:
     Kopf, die drei Bloecke, dann die Haekchen. Die Umsortierung ueber
     order ist damit ueberfluessig geworden. */
  .leistung-gross {
    grid-template-columns: 1fr;
    grid-template-areas: "kopf" "text" "marke";
    grid-template-rows: auto;
    gap: var(--s6);
    padding: var(--s6);
  }

  .person-innen, .kontakt-innen { grid-template-columns: 1fr; }
  /* Zwei Spalten Ortspillen waeren auf 390 px je 155 px breit.
     "Oer-Erkenschwick" braucht allein 150 px. */
  .orte-paar { grid-template-columns: 1fr; gap: 0; }
  .person-bild { order: -1; }
  .person-bild img { max-height: 300px; height: auto; object-fit: cover; }

  .schritte { grid-template-columns: repeat(2, 1fr); gap: var(--s6) var(--s5); }
  .schritte li:nth-child(2)::after { display: none; }

  .preis-karte:nth-child(2n) { border-left: none; }
  .preis-karte + .preis-karte { border-top: 1px solid var(--linie); }
  .preis-karten { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  /* Der Hero muss auf 390 x 844 ueber der Anrufleiste bleiben, die bei
     771 px beginnt. Jede Zeile hier ist einmal nachgemessen worden:

       48 px Luft                      Hero endete bei 777
       24 px Luft                                     745
       + Bewertungszeile                              839

     Die Bewertungszeile steht laut Auftrag unter den Kacheln und soll
     sichtbar sein. Statt sie hochzuziehen, sind hier sieben kleine
     Abstaende enger gesetzt. Gemessen mit _pruefung/erster_schirm.py. */
  .hero { padding: var(--s3) 0; }
  .hero-innen { gap: var(--s3); }
  .hero-punkte { gap: var(--s2); }
  .hero .kicker { margin-bottom: var(--s4); }
  .hero h1 { margin-bottom: var(--s5); }
  .hero-lead { margin-bottom: var(--s5); }
  /* Ohne feste Mindesthoehe. Seit das Haekchen neben dem Text steht
     statt darueber, ist die natuerliche Hoehe einer Kachel rund 62 px;
     die alten 92 px waren reine Luft. */
  /* Kein eigener oberer Abstand mehr: gestapelt liefert das Raster
     des Hero bereits 12 px zwischen den beiden Spalten. Zusammen
     standen 24 px zwischen der Zusage und der Bewertungszeile,
     waehrend alles andere im Hero mit 8 bis 16 auskommt. */
  .bewertungszeile { margin-top: 0; }
}

/* Bis zum zwanzigsten Umbau klappte das Menue erst ab 860 px zusammen.
   Seit die Kopfzeile sechs statt fuenf Eintraege traegt, reicht der
   Platz frueher nicht mehr: gemessen passt sie ab 968 px auf eine
   Zeile, darunter wird sie 87 statt 72 px hoch und die Punkte laufen
   auf vier Reihen. Deshalb dieser eigene Block bei 990 px. Die feste
   Anrufleiste unten und die Kartenraster bleiben bei 860, sie haben
   mit dem Platz in der Kopfzeile nichts zu tun.

   Wer diesen Wert aendert, muss js/seite.js mitziehen: dort steht
   dieselbe Grenze, damit ein offenes Menue beim Aufziehen des
   Fensters wieder schliesst. */
@media (max-width: 990px) {
  /* Menue klappt auf */
  .menue-knopf { display: grid; place-items: center; }
  /* Das offene Menue fuellt den ganzen Bildschirm unter der Kopfzeile.
     Vorher endete es mitten im Bild, die Seite scrollte dahinter weiter
     und die Anrufleiste schaute halbiert darunter hervor. Die Hoehe der
     Kopfzeile misst das Skript beim Oeffnen und legt sie in --kopf-hoehe. */
  .hauptmenue {
    position: fixed; left: 0; right: 0;
    top: var(--kopf-hoehe, 72px); bottom: 0;
    margin: 0; overflow-y: auto;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--papier);
    padding: var(--s3) var(--rand) var(--s7);
    display: none;
  }
  .hauptmenue.offen { display: flex; }
  .hauptmenue a { padding: 14px 0; font-size: 17px; border-bottom: 1px solid var(--linie); }
  .hauptmenue a:last-child { border-bottom: none; }
  .kopf-anfrage { margin-top: var(--s4); justify-content: center; font-size: 16px; }
  .kopf-telefon { justify-content: center; font-size: 17px; padding: 14px 0;
                  border-bottom: 1px solid var(--linie); }
}

@media (max-width: 860px) {
  /* Feste Anrufleiste unten */
  .anrufleiste {
    display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--s2);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    background: rgba(251,252,252,.96);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    border-top: 1px solid var(--linie-stark);
    /* Nach oben, nicht nach unten: unter der Leiste ist nichts mehr.
       Sie soll sich sichtbar vom Inhalt abheben, ueber den sie
       geschoben wird. */
    box-shadow: 0 -4px 16px rgba(20,30,35,.15);
    padding: var(--s2) var(--s3) calc(var(--s2) + env(safe-area-inset-bottom));
  }
  .anrufleiste-knopf {
    display: flex; align-items: center; justify-content: center; gap: var(--s2);
    min-height: 56px; border-radius: var(--r);
    font-size: 16px; font-weight: 650; text-decoration: none;
  }
  .anrufleiste-knopf svg { width: 19px; height: 19px; }
  .anrufleiste-haupt { background: var(--wasser-tief); color: #FFFFFF; }
  .anrufleiste-zweit {
    background: var(--licht-blass); color: var(--licht-text);
    box-shadow: inset 0 0 0 1.5px #EBD5B4;
  }
  /* Platz, damit die Leiste die Fusszeile nicht verdeckt */
  body { padding-bottom: 76px; }
}

@media (max-width: 700px) {
  :root { --s9: 64px; --s8: 48px; --bahn-luft-mobil: 32px; }

  /* Die vier Zusatzleistungen stehen auf dem Handy zweispaltig.
     Untereinander waren sie 1566 px hoch, also fast zwei Bildschirme
     fuer vier Karten mit je zwei Saetzen. Zweispaltig sind es 702 px.
     Die Schriftgroesse bleibt, nur die Innenabstaende ruecken zusammen.
     Vergleich in _pruefung/tafel-14-karten.jpg */
  .leistung-klein.raster-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s3);
  }
  .leistung-klein .karte { padding: 0 0 var(--s4); }
  .leistung-klein .karte-inhalt { padding: 0 var(--s4); }
  .leistung-klein .karte h3 { font-size: 1.05rem; }
  /* Dieselben Werte fuer die fuenfte Karte, damit die Ueberschriften
     auf dem Handy auf einer Linie stehen: sonst 25 px gegen 17. */
  .leistung-breit .karte-inhalt { padding: var(--s4); }
  .leistung-breit h3 { font-size: 1.05rem; }

  /* Hier ist die entscheidende Stelle des dreizehnten Umbaus an dieser
     Karte. Ohne zweite Spalte trennt ein Absatzabstand die drei
     Bloecke nicht sichtbar genug: sie lesen sich als eine Textwand.
     Jeder Block bekommt deshalb eine eigene Flaeche mit Rundung und
     Innenabstand und ist damit als Einheit erkennbar. Die Haarlinie
     zwischen ihnen entfaellt, sie waere dann doppelt gemoppelt. */
  .leistung-block {
    background: var(--wasser-hauch);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    /* Enger als vorher: seit die Bloecke zugeklappt starten, steht in
       zweien von dreien nur eine Zwischenueberschrift und ein Satz.
       24 px ringsum waren dafuer viel Rahmen um wenig Inhalt. */
    padding: var(--s4) var(--s5);
  }
  .leistung-block + .leistung-block {
    margin-top: var(--s3);
    padding-top: var(--s4);
    border-top: 0;
  }
  .leistung-block h4 { margin-bottom: var(--s2); }
  .leistung-gross { padding: var(--s5); }
  .raster-3, .raster-4 { grid-template-columns: 1fr; }
  .fusszeile-innen { grid-template-columns: 1fr 1fr; gap: var(--s6); }
  .kopf-block { margin-bottom: var(--s6); }
  /* Enger auf dem Handy. Die Feldabstaende bleiben, nur der Rahmen
     um das Formular und der Abstand zwischen den Feldern ruecken
     zusammen. Die Felder selbst behalten ihre 48 px Mindesthoehe. */
  .formular { padding: var(--s4); }
  .formular .feld { margin-bottom: var(--s3); }
  .formular .feld-haken { margin: var(--s4) 0; }
  .schritte { grid-template-columns: 1fr; gap: var(--s5); }
  .schritte li { padding-top: 0; padding-left: 70px; min-height: 54px; }
  .schritte li::after { display: none; }
  .schritte h3 { margin-top: 4px; }
  .preis-karte, .preis-hinweis { padding: var(--s5); }
  /* Die Richtwert-Marke bricht auf schmalen Bildschirmen in zwei Zeilen.
     Als voll gerundete Pille wirkt sie dann aufgeblasen, als Schild nicht. */
  .preis-marke { border-radius: 10px; }
  .frage-inhalt { padding-right: 0; }
  .fragen summary { font-size: 1.06rem; padding-right: 36px; }
}

@media (max-width: 520px) {
  .feld-paar { grid-template-columns: 1fr; gap: 0; }
  .knopf { width: 100%; }
  .knopf-reihe { gap: var(--s2); }
  /* Drei Knoepfe ueber die volle Breite untereinander waren 178 px
     Flaeche, alle drei gleich laut. Jetzt traegt der Hauptweg die
     volle Breite, die beiden Nebenwege teilen sich die Zeile
     darunter: 118 px, und die Rangfolge ist zu sehen statt nur zu
     lesen. Der Hero bekommt damit 62 px Luft ueber der Anrufleiste
     statt 2. */
  .hero-knoepfe {
    display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  }
  .hero-knoepfe .knopf { width: 100%; padding-inline: var(--s2); }
  .hero-knoepfe .knopf-voll { grid-column: 1 / -1; }
  .hero-knoepfe .knopf-wa .wa-lang { display: none; }
  .hero-knoepfe .knopf-wa .wa-kurz { display: inline; }
  .marke-text strong { font-size: 1.12rem; }
  .marke-text span { font-size: 10.5px; letter-spacing: .14em; }
  /* Die Fusszeile bleibt zweispaltig. Einspaltig wurde sie mit den
     44 px hohen Linkzeilen zu einem Turm von ueber 1100 px. */
  .fusszeile-innen { grid-template-columns: 1fr 1fr; gap: var(--s5) var(--s4); }
  /* Die Kacheln bleiben zweispaltig, nur enger. Einspaltig waere
     der Hero auf dem Handy ueber einen Bildschirm hinausgelaufen.

     Der obere Abstand ist seit der Zusage unter den Knoepfen kleiner:
     die Zusage kostet 50 px, und der Hero endete damit 12 px unter der
     festen Anrufleiste. Die letzte Kachel stand halb dahinter. */
  .hero-punkte { gap: var(--s2); margin-top: var(--s4); }
  .hero-punkte li { font-size: 13.5px; }
  /* Die Zusage bleibt auch auf dem Handy bei 16 px. Sie stand
     vorher unter den Knoepfen und war dort auf 13,5 px die
     kleinste Schrift des Hero. Ueber den Knoepfen ist sie der
     letzte Satz vor der Entscheidung und wird gelesen. */
  .hero-zusage { font-size: 16px; margin-bottom: var(--s3); }
}

/* Druckfassung: Kopfzeile, Leiste und Formular fallen weg */
@media print {
  .kopfzeile, .anrufleiste, .formular, .zum-inhalt { display: none !important; }
  body { font-size: 11pt; }
  .bahn, .bahn-eng { padding: 12pt 0; }
  a { color: #000; text-decoration: underline; }
}

@media (max-width: 700px) {
  /* Auf schmalen Bildschirmen wird der Kicker zweizeilig. Kleiner
     gesetzt und enger gesperrt passt er meist doch in eine Zeile. */
  /* Kleiner gesetzt, damit der Kicker in eine Zeile passt. Zweizeilig
     schoebe er die Ueberschrift unter die 48-px-Grenze zur Kopfzeile. */
  .kicker { font-size: 13px; letter-spacing: .07em; line-height: 1.4; }
  .kicker::before { margin: -2px 10px 0 0; width: 20px; }
}

/* Kleiner Merkzettel in der Kontaktspalte. Fuellt nicht nur die
   Flaeche, sondern nimmt die Frage vorweg, was ich ueberhaupt
   brauche, um einen Preis nennen zu koennen. */
.merkzettel {
  margin-top: var(--s7);
  background: var(--wasser-hauch);
  border: 1px solid #D3E6EB;
  border-radius: var(--r-gross);
  padding: var(--s5) var(--s6) var(--s6);
}
.merkzettel h3 { font-size: 1.12rem; margin-bottom: var(--s3); }
/* Der erste Absatz traegt seit dem zweiundzwanzigsten Umbau den
   Inhalt, der vorher in der Liste stand. Er hat deshalb die Groesse
   des Fliesstextes, waehrend der zweite als Nachsatz leiser bleibt.
   Ohne diese Regel waeren beide 15 px und grau, und der Merkzettel
   haette keine Aussage mehr, nur noch zwei Fussnoten. */
.merkzettel-haupt {
  font-size: 16px !important; color: var(--text) !important;
  margin-bottom: var(--s3) !important;
}
.merkzettel ul { list-style: none; margin: 0 0 var(--s4); padding: 0; display: grid; gap: var(--s2); }
.merkzettel li { position: relative; padding-left: 26px; font-size: 16px; }
.merkzettel li::before {
  content: ""; position: absolute; left: 0; top: .4em;
  width: 14px; height: 7px;
  border-left: 2.2px solid var(--wasser); border-bottom: 2.2px solid var(--wasser);
  transform: rotate(-45deg);
}
.merkzettel p { font-size: var(--t-klein); color: var(--leise); margin: 0; }

/* Rechtsseiten haben kein Klappmenue. Der Anrufknopf steht dort
   direkt in der Kopfzeile und darf nicht in die Regeln des
   Hauptmenues fallen, sonst waere er auf dem Handy unsichtbar. */
.kopf-rechts { margin-left: auto; }

/* ============================================================
   7. Nachtrag: Vertrauen, Person, Steuer
   ------------------------------------------------------------
   Ergaenzt nach der Messung, dass die Seite leer und unpersoenlich
   wirkte: kein Wort zur Absicherung, kein Gesicht, das staerkste
   Preisargument versteckt in einer Rechtsbox.
   ============================================================ */

/* ---------- Vertrauensbalken ----------
   Vier Fakten, kein Fliesstext. Bewusst schmal und ruhig gesetzt,
   damit er wie ein Siegelstreifen wirkt und nicht wie Werbung. */
.siegel {
  background: var(--grund-kuehl);
  border-top: 1px solid var(--linie);
  padding: var(--s5) var(--rand);
}
.siegel-innen {
  max-width: var(--breit); margin: 0 auto;
  list-style: none; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.siegel-innen li {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: var(--s3) var(--s4);
  font-size: var(--t-klein); font-weight: 600; color: var(--tinte);
  text-align: left; line-height: 1.35;
}
.siegel-innen li + li { border-left: 1px solid var(--linie-stark); }
.siegel-innen svg { width: 20px; height: 20px; flex: none; color: var(--wasser-tief); }

/* ---------- Ueber mich, zweispaltig ----------
   Vorher stand hier zentrierter Text ohne Bild. Das war die
   unpersoenlichste Stelle der Seite, obwohl sie die persoenlichste
   sein sollte. */
/* Das Portrait war 475 x 480 px und damit ein Drittel der Inhalts-
   breite. Es dominierte den Abschnitt, obwohl der Text die Arbeit
   leisten soll. Jetzt 200 px rund, links neben dem Text. */
.ueber-innen {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: clamp(28px, 3.5vw, 48px);
  align-items: center;
}
.ueber-bild img {
  width: 240px; height: 240px;
  object-fit: cover;
  object-position: 50% 14%;
  /* Weich abgerundet wie die uebrigen Bilder, nicht rund. Runde
     Portraits lesen als Profilbild aus einem sozialen Netzwerk,
     nicht als Handwerker. */
  border-radius: var(--r-gross);
  box-shadow: var(--schatten-hoch);
}
.ueber-text { max-width: var(--lesebreite); }
.ueber-text .ueber-gross { font-size: var(--t-lead); color: var(--text); line-height: 1.55; margin-bottom: var(--s4); }
/* Die Auszeichnung ist auch ein p und wurde von dieser Regel
   miterfasst: grau statt ocker, als einzige der elf. */
.ueber-text > p:not(.ueber-gross):not(.ueber-hinweis):not(.kicker) { color: var(--leise); font-size: 16.5px; }


/* ---------- Steuerargument im Preisabschnitt ----------
   Stand vorher als letzter Satz in der Rechtsbox, also dort, wo
   niemand ein Verkaufsargument sucht. Jetzt eigener Block direkt
   unter den Zahlen. Die Rechtsbox darunter bleibt unveraendert. */
.steuer {
  padding: var(--s6) var(--s7);
  border-top: 1px solid var(--linie);
  background: var(--papier);
}
.steuer h3 {
  font-size: 1.28rem;
  margin-bottom: var(--s3);
  display: flex; align-items: baseline; gap: var(--s3);
}
.steuer h3::before {
  content: "§ 19";
  flex: none;
  font-family: 'Grotesk', 'Grotesk Ersatz', system-ui, sans-serif;
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .04em;
  color: var(--wasser-tief); background: var(--wasser-blass);
  border-radius: 6px; padding: 4px 9px;
  transform: translateY(-2px);
}
.steuer p { color: var(--text); font-size: 16.5px; max-width: var(--lesebreite); margin: 0; }

/* ---------- Kleine Bildschirme ---------- */
@media (max-width: 960px) {
  /* Auf dem Handy steht das Bild ueber dem Text und mittig. 200 px
     nehmen dort ein knappes Fuenftel der Bildschirmhoehe ein, das
     traegt ohne zu dominieren. */
  .ueber-innen { grid-template-columns: 1fr; gap: var(--s5); justify-items: center; }
  .ueber-bild { order: -1; }
  /* Bild, Kicker und Ueberschrift mittig, die Absaetze aber linksbuendig:
     vier zentrierte Fliesstextzeilen sind deutlich schwerer zu lesen als
     linksbuendige. */
  .ueber-text { text-align: left; }
  .ueber-text .kicker, .ueber-text h2 { text-align: center; }
  .ueber-hinweis { margin-left: auto; margin-right: auto; }
  .steuer { padding: var(--s5); }
}

@media (max-width: 860px) {
  .siegel-innen { grid-template-columns: repeat(2, 1fr); }
  /* Bei zwei Spalten trennt die Linie nur noch senkrecht in der
     Mitte, die waagerechte Trennung uebernimmt der Zeilenabstand. */
  .siegel-innen li + li { border-left: none; }
  .siegel-innen li:nth-child(even) { border-left: 1px solid var(--linie-stark); }
  .siegel-innen li:nth-child(n+3) { border-top: 1px solid var(--linie-stark); }
  .siegel-innen li { justify-content: flex-start; }
}

@media (max-width: 520px) {
  .siegel-innen { grid-template-columns: 1fr; }
  .siegel-innen li:nth-child(even) { border-left: none; }
  .siegel-innen li + li { border-top: 1px solid var(--linie-stark); }
}

/* ============================================================
   8. Nachtrag: Audit und Nutzertest
   ------------------------------------------------------------
   Preisanker in allen Leistungen, die Preiszeile im Hero, die
   Kontaktwege als Karten, der umgeleitete Formularhinweis, das
   deutsche Datei-Feld und das Klappmenue mit Abdunklung.
   ============================================================ */

/* Die Regeln fuer .hero-preis sind mit der Zeile selbst im zwoelften
   Umbau entfallen. */

/* ---------- Was die Spanne bestimmt ---------- */
.preis-spanne {
  margin: var(--s3) 0 0;
  font-size: 14.5px; line-height: 1.5;
  color: var(--leise);
}

/* ---------- Preisanker in den Leistungskarten ---------- */
.karte-preis {
  margin: var(--s3) 0 0 !important;
  padding-top: var(--s3);
  border-top: 1px dashed var(--linie-stark);
  font-size: 14.5px !important; line-height: 1.45 !important;
  color: var(--tinte) !important; font-weight: 600;
}
.karte-preis span {
  display: inline-block; margin-right: 6px;
  font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--licht-text); background: var(--licht-blass);
  border-radius: 5px; padding: 2px 7px; vertical-align: 1px;
}
.leistung-richtwert {
  margin: var(--s5) 0 0;
  font-size: var(--t-klein); color: var(--leise);
  max-width: var(--lesebreite);
}

/* ---------- Gewerbe-Satz in der Hauptleistung ----------
   Vorher stand der einzige Satz zu Ladenlokalen zugeklappt in der
   achten Frage. Jetzt sichtbar, mit warmer Kante wie die Gegenrede. */
/* Hier stand .gewerbe-satz, der Kasten mit der Ockerlinie links.
   Die Klasse kommt in keiner Datei mehr vor. */

/* ---------- Anfahrt im Einzugsgebiet ---------- */
.anfahrt { color: var(--text); font-size: 16.5px; max-width: var(--lesebreite); }

/* ---------- Formularhinweis, der zum Anruf leitet ----------
   Ersetzt den Satz "Das Formular versendet noch nichts", der laut
   Nutzertest alle Formularanfragen kostete. Bleibt stehen, solange
   nichts versendet wird, leitet aber weiter statt abzubrechen. */
.formular-hinweis {
  margin-top: var(--s5);
  padding: var(--s5);
  background: var(--licht-hauch);
  border: 1px solid #EBD5B4; border-left: 4px solid var(--licht);
  border-radius: var(--r);
}
.formular-hinweis p { font-size: 16px; color: var(--text); margin: 0 0 var(--s4); }
.formular-hinweis .knopf-reihe .knopf { flex: 1 1 200px; }

/* ---------- Fehlermeldung im Formular ---------- */
.feld-fehler {
  margin: -6px 0 var(--s4); padding: 10px 14px;
  background: #FBEAEA; border: 1px solid #E5B4B4; border-radius: var(--r-klein);
  color: #8B1E1E;   /* 7,6:1 auf dem hellen Rot */
  font-size: 14.5px; font-weight: 600; line-height: 1.45;
}
.feld input[aria-invalid="true"] { border-color: #B33A3A; }

/* ---------- Datei-Feld auf Deutsch ----------
   Das native Feld zeigte in Chrome "Choose Files / No file chosen".
   Das Eingabefeld bleibt fuer Tastatur und Vorleser da, ist aber
   unsichtbar; sichtbar sind Knopf und Stand daneben. */
.datei-feld {
  position: relative;
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s3);
  min-height: 48px; padding: 8px 12px;
  background: var(--wasser-hauch);
  border: 1.5px dashed var(--linie-stark); border-radius: var(--r);
  transition: border-color var(--takt), box-shadow var(--takt);
}
.datei-feld:focus-within { border-color: var(--wasser); box-shadow: 0 0 0 3px rgba(14,110,134,.18); }
.datei-feld input[type="file"] {
  position: absolute; width: 1px; height: 1px; min-height: 0;
  opacity: 0; overflow: hidden; padding: 0; margin: 0; border: 0;
}
.feld .datei-knopf {
  display: inline-flex; align-items: center;
  min-height: 34px; margin: 0; padding: 5px 14px;
  background: var(--papier); border: 1.5px solid var(--linie-stark); border-radius: 8px;
  font-size: 15px; font-weight: 650; color: var(--wasser-tief);
  cursor: pointer;
}
.feld .datei-knopf:hover { border-color: var(--wasser); }
.datei-stand { font-size: 14.5px; color: var(--leise); overflow-wrap: anywhere; }

/* ---------- Klappmenue: Abdunklung und Sperre ---------- */
.menue-schleier {
  position: fixed; inset: 0; z-index: 55;
  background: rgba(11,43,51,.5);
}
.menue-schleier[hidden] { display: none; }
body.menue-offen { overflow: hidden; }
/* Die feste Anrufleiste liegt sonst ueber dem offenen Menue. */
body.menue-offen .anrufleiste { display: none; }
/* backdrop-filter macht die Kopfzeile zum Bezugsrahmen fuer fixierte
   Nachfahren. Das Menue mass dann seine Hoehe an der 73 px hohen
   Kopfzeile statt am Fenster und endete bei 133 px. Solange es offen
   ist, faellt der Filter weg; die Flaeche ist ohnehin fast deckend. */
body.menue-offen .kopfzeile { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--grund); }

/* ---------- Sechs Menuepunkte auf dem Rechner ---------- */
@media (min-width: 861px) and (max-width: 1200px) {
  .hauptmenue { gap: var(--s5); }
  .hauptmenue a { font-size: 15px; }
}

/* ---------- Kleine Bildschirme ---------- */
@media (max-width: 520px) {
  .formular-hinweis .knopf-reihe .knopf { flex-basis: 100%; }
  .kontakt-karte { min-height: 60px; }
}

/* ============================================================
   9. Nachtrag: Reihenfolge, Belege, Klickflaechen
   ------------------------------------------------------------
   Der Ueber-mich-Abschnitt steht jetzt vor den Preisen, der
   Wiederholungsabschnitt unter dem Hero ist weg, dazu ein
   Belegblock und groessere Klickflaechen auf dem Handy.
   ============================================================ */

/* Der Hero laeuft seit dem dreizehnten Umbau auf dunklem Grund.
   Diese Regel stand hier seit dem sechsten Umbau und hat die
   Farbe des Hero-Blocks ueberschrieben: der Absatz stand damit
   mit 1,87:1 dunkel auf dunkel. */
.hero-lead { color: var(--tief-leise); }

/* ---------- Belegblock ----------
   Die Platzhalter sollen nicht wie unfertige graue Kaesten wirken.
   Deshalb dieselbe Kartenform wie im Rest der Seite, nur mit
   gestrichelter Kante und ohne Schatten: erkennbar vorbereitet,
   nicht kaputt. */
.belege { align-items: stretch; }
.beleg {
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--r-gross);
  padding: var(--s6);
}
.beleg-leer {
  background: transparent;
  border: 1.5px dashed var(--linie-stark);
  display: flex; flex-direction: column; gap: var(--s3);
}
.beleg-art {
  font-size: var(--t-mini); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--licht-text);
  margin: 0;
  display: flex; align-items: center; gap: 10px;
}
.beleg-art::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--licht-blass); box-shadow: inset 0 0 0 2px var(--licht);
}
.beleg-text { font-size: 16px; color: var(--leise); line-height: 1.55; margin: 0; }

.beleg-hinweis {
  margin: var(--s5) 0 0;
  font-size: var(--t-klein); color: var(--leise);
  display: flex; align-items: center; gap: var(--s3);
}
.beleg-hinweis::before {
  content: ""; width: 26px; height: 2px; background: var(--linie-stark); flex: none;
}

/* Fuer die spaeter befuellten Karten, damit das Einsetzen ohne
   weitere Stilarbeit geht. */
.beleg-stimme blockquote { margin: 0 0 var(--s5); }
.beleg-stimme blockquote p {
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.15rem; line-height: 1.45; color: var(--tinte); margin: 0;
}
.beleg-stimme blockquote p::before { content: "\201E"; }
.beleg-stimme blockquote p::after { content: "\201C"; }
.beleg figcaption { display: flex; flex-direction: column; gap: 2px; }
.beleg-wer { font-weight: 700; color: var(--tinte); font-size: var(--t-klein); }
.beleg-wo, .beleg-anlass { font-size: 14px; color: var(--leise); }
.beleg-bild { padding: 0; overflow: hidden; }
.beleg-paar { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.beleg-paar img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.beleg-bild figcaption { padding: var(--s5); }

/* ---------- Erreichbarkeit ----------
   Zwei Testpersonen ueber 70 wollten anrufen und wussten nicht, ob
   sie stoeren. Steht direkt unter den Kontaktkarten. */
.erreichbar {
  margin: var(--s4) 0 0;
  padding: var(--s3) var(--s4);
  background: var(--wasser-hauch);
  border-radius: var(--r);
  font-size: var(--t-klein);
  color: var(--text);
  display: flex; align-items: flex-start; gap: 10px;
}
.erreichbar::before {
  content: ""; flex: none; width: 18px; height: 18px; margin-top: 2px;
  background: var(--wasser-tief);
  -webkit-mask: no-repeat center / contain;
  mask: no-repeat center / contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5.2l3.2 2'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5.2l3.2 2'/%3E%3C/svg%3E");
}

/* ---------- Anrufkarte hervorheben ----------
   Die Telefonnummer war eine Textzeile. Jetzt ist sie der Knopf,
   der sie sein sollte. */
.kontakt-karte-haupt {
  background: var(--wasser-tief);
  border-color: var(--wasser-tief);
}
.kontakt-karte-haupt:hover { background: var(--tinte); border-color: var(--tinte); }
.kontakt-karte-haupt .kontakt-symbol { background: rgba(255,255,255,.16); color: #FFFFFF; }
/* Auch die kleine Beschriftung in Weiss: jeder abgesetzte Ton auf
   diesem Grund bleibt unter 7:1, gemessen kam #BBD6DD auf 5,1:1.
   Die Hierarchie traegt hier die Groesse und die Sperrung, nicht
   die Farbe. */
.kontakt-karte-haupt .kontakt-karte-text strong { color: #FFFFFF; }        /* 7,8:1 */
.kontakt-karte-haupt .kontakt-karte-text span { color: #FFFFFF; }          /* 7,8:1 */
.kontakt-karte-haupt .kontakt-pfeil { color: #FFFFFF; }

/* ---------- Portrait im Kontaktbereich ----------
   Fuellt die frueher leere linke Spalte auf dem Rechner und zeigt
   das Gesicht noch einmal dort, wo entschieden wird. */
.kontakt-person {
  margin-top: var(--s6);
  display: flex; align-items: center; gap: var(--s5);
}
.kontakt-person img {
  width: 96px; height: 96px; flex: none;
  border-radius: var(--r); object-fit: cover; object-position: 50% 18%;
  box-shadow: var(--schatten);
}
.kontakt-person p {
  margin: 0; font-size: var(--t-klein); color: var(--leise); line-height: 1.55;
}
.kontakt-person strong {
  display: block;
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.12rem; font-weight: 600; color: var(--tinte);
  margin-bottom: 2px;
}

/* ============================================================
   Klickflaechen auf dem Handy
   ------------------------------------------------------------
   Gemessen waren 22 Ziele unter 44 px, das kleinste 18 px hoch.
   Fliesstextlinks bekommen ihre Flaeche ueber padding-block: bei
   einem Inline-Element vergroessert das die Trefferflaeche, ohne
   die Zeilenhoehe zu veraendern, der Umbruch bleibt also gleich.
   ============================================================ */
@media (max-width: 860px) {
  /* Wortmarke in Kopf- und Fusszeile */
  .marke { min-height: 44px; }

  /* Listenlinks in der Fusszeile */
  .fuss-liste { gap: 0; }
  .fuss-liste a {
    display: inline-flex; align-items: center;
    min-height: 44px;
  }
  .fuss-unten a { display: inline-flex; align-items: center; min-height: 44px; }

  /* Links mitten im Fliesstext */
  .leistung-richtwert a,
  .feld-haken label a,
  .rechtsseite p a,
  .rechtsseite li a,
  .brotkrume a {
    padding-block: 13px;
    margin-block: -13px;
  }

  /* Beschriftungen im Formular. Der zusaetzliche Platz liegt oben,
     also zwischen zwei Feldern, wo er ohnehin gut tut. Dafuer
     ruecken die Felder selbst enger zusammen. */
  .feld { margin-bottom: 6px; }
  .feld label { padding: 13px 0 6px; margin-bottom: 0; min-height: 44px; }
  .feld .datei-knopf { min-height: 44px; padding: 8px 16px; }

  /* Enger: 13 zugeklappte Fragen mit je 24 px Luft oben und unten
     ergaben 923 px, fast eineinhalb Bildschirme fuer 13 Zeilen. Mit
     16 px bleibt die Klickflaeche bei 55 px und damit ueber den
     geforderten 44. */
  .fragen summary { padding-block: var(--s4); }
}

/* Das Haekchen wird selbst gezeichnet: als natives Kaestchen ist es
   20 px gross und laesst sich nicht vergroessern, ohne die Grafik zu
   verzerren. So bleibt das sichtbare Kaestchen bei 24 px, die
   Trefferflaeche wird 44 px. */
.feld-haken input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 44px; height: 44px; flex: none;
  margin: -10px 0 0 -10px; padding: 0; border: 0; background: none;
  display: grid; place-items: center; cursor: pointer;
}
.feld-haken input[type="checkbox"]::before {
  content: ""; grid-area: 1 / 1; box-sizing: border-box;
  width: 24px; height: 24px; border-radius: 6px;
  border: 2px solid var(--linie-stark); background: var(--papier);
  transition: background var(--takt), border-color var(--takt);
}
.feld-haken input[type="checkbox"]:checked::before {
  background: var(--wasser-tief); border-color: var(--wasser-tief);
}
.feld-haken input[type="checkbox"]::after {
  content: ""; grid-area: 1 / 1;
  width: 12px; height: 7px; margin-top: -3px;
  border-left: 2.5px solid #FFFFFF; border-bottom: 2.5px solid #FFFFFF;
  transform: rotate(-45deg) scale(0);
  transition: transform var(--takt);
}
.feld-haken input[type="checkbox"]:checked::after { transform: rotate(-45deg) scale(1); }
.feld-haken input[type="checkbox"]:focus-visible { outline-offset: -8px; }

/* ---------- Kleine Bildschirme ---------- */
@media (max-width: 960px) {
  .kontakt-person { margin-top: var(--s5); }
}

@media (max-width: 900px) {
  .belege.raster-3 { grid-template-columns: 1fr; }
}

/* Das zweite Portrait im Kontaktbereich fuellt eine Luecke, die nur
   auf dem Rechner entsteht: dort ist die Formularspalte hoeher als die
   Textspalte daneben. Auf dem Handy steht ohnehin alles untereinander,
   es gaebe keine Luecke, und das Gesicht kam sechs Bildschirme vorher
   schon einmal. */
@media (max-width: 960px) {
  .kontakt-person { display: none; }

  /* Die vier kleinen Leistungsbilder zeigen alle liegende Motive:
     Dachrinne, Fassade, Balkongang, Wintergarten. Auf dem Handy ist
     16:9 dort der passendere Zuschnitt als 3:2, und die vier Karten
     werden zusammen 144 px kuerzer. */
  .karte-bild img { aspect-ratio: 16 / 9; }
}

/* ============================================================
   10. Nachtrag: Formularversand
   ============================================================ */

/* Die Falle fuer Bots. Nicht display:none: manche Bots erkennen das
   und lassen das Feld dann in Ruhe. Weit aus dem Sichtfeld geschoben
   wirkt es fuer sie wie ein normales Feld. */
.falle {
  position: absolute;
  left: -9999px; top: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Rueckmeldung nach dem Absenden */
.formular-meldung-gut {
  background: #E8F3EC; border-color: #A8CDB6; color: #1C5233;   /* 7,6:1 */
}
.formular-meldung-schlecht {
  background: #FBEAEA; border-color: #E5B4B4; color: #8B1E1E;   /* 7,8:1 */
}
.formular-knopf[disabled] { opacity: .7; cursor: progress; }

/* Fussnote unter der Steuerantwort */
.frage-fussnote {
  margin-top: var(--s3) !important;
  padding-top: var(--s3);
  border-top: 1px solid var(--linie);
  font-size: var(--t-klein) !important;
}

/* Der Satz zum Aufwand des Kunden, unter den vier Ablaufschritten */
.ablauf-hinweis {
  margin: var(--s6) 0 0;
  padding: var(--s4) var(--s5);
  background: var(--papier);
  border: 1px solid #EBD5B4;
  border-left: 3px solid var(--licht);
  border-radius: var(--r);
  font-size: 16.5px;
  color: var(--text);
  max-width: var(--lesebreite);
}

/* ---------- Vorher und nachher am Falz ----------
   Steht noch als Kommentar in der Hauptleistungskarte. Die Stile sind
   fertig, damit das Bild nur noch eingesetzt werden muss. Zwei
   Aufnahmen nebeneinander, mit einer Fuge dazwischen statt einer
   Linie: der Unterschied soll aus den Bildern kommen, nicht aus der
   Gestaltung. */
.falz-beleg {
  margin: var(--s5) 0 0;
  max-width: var(--lesebreite);
}
.falz-paar {
  display: grid; grid-template-columns: 1fr 1fr; gap: 3px;
  border-radius: var(--r); overflow: hidden;
}
.falz-paar img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.falz-beleg figcaption {
  margin-top: var(--s3);
  font-size: var(--t-klein); color: var(--leise);
}

/* ============================================================
   11. Nachtrag: ohne Preise, mit Haltung
   ============================================================ */

/* ---------- Woran der Preis haengt ----------
   Fuenf Faktoren statt vier Preisfaellen. Karten wie sonst, aber mit
   Ziffer, damit die Reihenfolge (zuerst die Anzahl) sichtbar bleibt. */
.faktoren {
  list-style: none; margin: 0; padding: 0;
  /* Vier Karten in zwei vollen Reihen. Bei drei Spalten stuende die
     vierte allein in der zweiten Zeile, bei vier nebeneinander bliebe
     neben der Ziffer zu wenig Textbreite. */
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5);
  counter-reset: faktor;
}
.faktor {
  counter-increment: faktor;
  position: relative;
  background: var(--papier); border: 1px solid var(--linie);
  border-radius: var(--r-gross); padding: var(--s6) var(--s6) var(--s6) 78px;
  /* Die vier Preisfaktoren sehen aus wie Karten, tragen aber nicht die
     Klasse .karte, weil sie aus einer nummerierten Liste kommen. Beim
     siebenunddreissigsten Umbau waren sie deshalb zunaechst die
     einzigen Karten ohne Schatten. Auf dem hellen Ocker des
     Preisabschnitts faellt das besonders auf. */
  box-shadow: var(--schatten);
}
.faktor::before {
  content: counter(faktor);
  position: absolute; left: var(--s6); top: var(--s6);
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--licht-blass); color: var(--licht-text);
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.1rem; font-weight: 600;
}
.faktor h3 { font-size: 1.15rem; margin-bottom: var(--s2); }
.faktor p { color: var(--leise); font-size: 16px; line-height: 1.55; margin: 0; }

.preis-schluss {
  margin-top: var(--s6);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s5) var(--s7);
  padding: var(--s5) var(--s6);
  background: var(--wasser-hauch); border: 1px solid #D3E6EB; border-radius: var(--r-gross);
}
.preis-schluss p { flex: 1 1 420px; margin: 0; color: var(--text); font-size: 16.5px; }
/* Der Fotosatz spannt die ganze Breite des Kastens, gemessen 157
   Zeichen. Er steht allein in seiner Zeile, deshalb greift das
   flex-basis der Regel darueber bei ihm nicht. */
.preis-fotohinweis { max-width: var(--lesebreite); }
.preis-schluss .knopf { flex: none; }


/* Die Zusage ueber dem Formular und die unter dem Absendeknopf.
   Beide auf hellem Grund, beide kleiner als der Fliesstext. */
.kontakt-zusage {
  margin: var(--s3) 0 var(--s4);
  font-size: 15.5px; line-height: 1.5;
  color: var(--licht-text); font-weight: 600;
}
.formular-zusage {
  margin: var(--s3) 0 0;
  font-size: var(--t-klein); line-height: 1.5;
  color: var(--leise);
}

/* ---------- Die Stadtabschnitte der Landingpages ----------
   Diese Klassen kommen auf der Hauptseite nicht vor. Sie stehen
   trotzdem hier, weil alle einunddreissig Seiten dasselbe Stylesheet
   laden und eine zweite Datei nur Anfragen kostet. */
.stadt-text {
  margin: 0 0 var(--s4);
  max-width: var(--lesebreite);
  color: var(--text); font-size: 17px; line-height: 1.65;
}
.stadt-text:last-child { margin-bottom: 0; }

/* Text links, die drei Merkmale rechts. Dieselbe Aufteilung wie in der
   Hauptleistungskarte, damit die Seite eine Formensprache behaelt. */
.stadt-spalten {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: var(--s7);
  align-items: start;
}
.stadt-neben .haken { margin-top: 0; }
@media (max-width: 860px) {
  .stadt-spalten { grid-template-columns: 1fr; gap: var(--s5); }
}

/* ---------- Haltung ---------- */
/* Die Haltungspunkte standen bis zum vierzehnten Umbau in einem
   eigenen Abschnitt mit eigener Ueberschrift. Der stand direkt hinter
   "Wer bei Ihnen klingelt" und handelte von derselben Sache: wer der
   Anbieter ist und wie er arbeitet. Zusammen waren das 2,6
   Bildschirme auf dem Handy.

   Jetzt sind sie der zweite Teil desselben Abschnitts. Die zweispaltige
   Anordnung mit klebender Ueberschrift ist damit hinfaellig, der
   Abschnittskopf steht oben beim Portraet. */
.haltung-teil { margin-top: var(--s7); }
.haltung-teil .haltung-schluss { max-width: var(--lesebreite); }

.haltung-liste {
  list-style: none; margin: 0; padding: 0;
  /* Einspaltig seit dem dreizehnten Umbau. Die vier Punkte lesen
     sich als Folge, nicht als vier gleichrangige Kacheln. Die
     ockerfarbene Kante vor jedem Punkt war schon da und bleibt. */
  display: grid; grid-template-columns: 1fr; gap: var(--s5);
}
.haltung-liste li {
  padding: var(--s5) 0 var(--s5) var(--s6);
  border-left: 3px solid var(--licht);
}
/* Seit dem vierzehnten Umbau sind die vier Punkte der zweite Teil des
   Abschnitts "Wer bei Ihnen klingelt". Auf dem Handy ruecken sie
   zusammen: vier Punkte mit je 24 px Luft oben und unten sind dort
   192 px reiner Abstand. */
@media (max-width: 700px) {
  .haltung-teil { margin-top: var(--s6); }
  .haltung-liste { gap: var(--s4); }
  .haltung-liste li { padding: var(--s3) 0 var(--s3) var(--s5); }
  .haltung-liste h3 { margin-bottom: var(--s1); }
}
.haltung-liste h3 { font-size: 1.15rem; margin-bottom: var(--s2); }
/* Die vier Punkte liefen ueber die volle Breite: 1325 px, gemessen
   161 Zeichen je Zeile. Lesbar sind 60 bis 80; ab etwa 100 findet das
   Auge den Zeilenanfang nicht mehr zuverlaessig. Der Absatz direkt
   darueber hoerte schon immer bei --lesebreite auf. */
.haltung-liste li > p { max-width: var(--lesebreite); }
.haltung-liste p { color: var(--leise); font-size: 16.5px; margin: 0; }
.haltung-schluss {
  margin: var(--s6) 0 0;
  font-family: 'Serife', 'Serife Ersatz', Georgia, serif;
  font-size: 1.28rem; color: var(--tinte); max-width: var(--lesebreite);
}

/* ---------- Mittlerer Knopf der Anrufleiste ----------
   Kein WhatsApp-Gruen: die Farben der Seite, sonst zieht das fremde
   Gruen alle Aufmerksamkeit und wirkt wie ein Fremdkoerper. */
@media (max-width: 860px) {
  .anrufleiste-knopf { font-size: 15px; padding: 0 6px; white-space: nowrap; }
  .anrufleiste-knopf svg { width: 18px; height: 18px; }
  .anrufleiste-mitte {
    background: var(--wasser-blass); color: var(--wasser-tief);
    box-shadow: inset 0 0 0 1.5px #C5DFE6;
  }
}

@media (max-width: 960px) {
  .haltung-liste { grid-template-columns: 1fr; gap: var(--s3); }
  .preis-schluss .knopf { flex: 1 1 100%; }
}
@media (max-width: 700px) {
  .faktoren { grid-template-columns: 1fr; }
  .faktor { padding: var(--s5) var(--s5) var(--s5) 70px; }
  .faktor::before { left: var(--s5); top: var(--s5); }
}
@media (max-width: 400px) {
  .anrufleiste-knopf { font-size: 14px; gap: 5px; }
}

/* ---------- Warum Festpreis statt Stunden ----------
   Eigener Block mit warmer Kante wie die Gegenrede im dunklen
   Abschnitt: er erklaert nicht, wovon der Preis abhaengt, sondern
   warum er ueberhaupt fest ist. Zwei verschiedene Gedanken, deshalb
   optisch getrennt von den Faktorkarten. */
.festpreis {
  margin-top: var(--s6);
  padding: var(--s5) 0 var(--s5) var(--s6);
  border-left: 3px solid var(--licht);
  max-width: var(--lesebreite);
}
.festpreis h3 { font-size: 1.15rem; margin-bottom: var(--s3); }
.festpreis p { color: var(--leise); font-size: 16.5px; }
.festpreis p + p { margin-top: var(--s3); }
