/* Die Datei enthaelt genau EINEN Schnitt: Barlow Condensed Medium (usWeightClass 500,
   im Font selbst nachgesehen). Ohne den font-weight-Deskriptor galt sie als 400 —
   jedes font-weight:700 im Stylesheet erzeugte dann kuenstlichen Fettdruck, den der
   Browser durch Verbreitern der Konturen faelscht, und 500 war stillschweigend
   dasselbe wie 400. Deshalb hier ehrlich deklariert und im ganzen Stylesheet nur
   noch 500 angefordert. */
@font-face{font-family:"Barlow Condensed";src:url("vendor/barlow-condensed.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
/* Palette aus dem Markenkit des Kunden (T-Shirt, Visitenkarte, Logo).
   --olive ist der Wert aus seinem Farbwaehler-Screenshot, --ink dieselbe
   Farbfamilie stark abgedunkelt. Das alte Blaugruen #123c2e war kalt und mit
   dem warmen Oliv nicht verwandt — genau das meinte er mit "haessliche Gruene".
   Das Signalorange #c44814 ist deutlich klarer als das fruehere Terrakotta,
   erreicht aber weiterhin AA sowohl als Schrift auf Papier als auch mit
   weisser Schrift auf orangefarbener Flaeche. */
:root{--ink:#2b301f;--ink-2:#3d442d;--paper:#f8f6ef;--flaeche:rgba(248,246,239,.93);--paper-2:#efece1;--accent:#c44814;--accent-text:#c44814;--accent-rgb:196,72,20;--olive:#7e805d;--line:rgba(43,48,31,.2);--pad:clamp(22px,4.5vw,78px);color-scheme:light}

/* ===================== Schriftsystem =====================
   Vorher standen 41 verschiedene Schriftgroessen und drei Familien im Stylesheet.
   Ab hier gibt es genau diese Werte, und keine Regel setzt mehr eine eigene Zahl.
   Wer eine Groesse aendern will, aendert sie hier — und zwar ueberall zugleich.

   ZWEI FAMILIEN:
   --schrift-titel  Barlow Condensed, ein Schnitt (500). Alles Grosse und alles
                    Gesperrt-Versale. Georgia ist raus: es trat nur an drei Stellen
                    auf (Hero, Leistungen, Ladebildschirm) und war dort die einzige
                    Serife der Seite — dieselbe Rangstufe klang je nach Sektion anders.
   --schrift-text   Arial fuer Fliesstext. Systemschrift, kostet keinen Download.

   DREI UEBERSCHRIFTSTUFEN. Die Zuordnung folgt der Rolle, nicht dem Tag:
   --h1  Sektionstitel   – die Ueberschrift, die eine Sektion eroeffnet
   --h2  Blocktitel      – Ueberschrift innerhalb einer Sektion, je Kachel/Objekt
   --h3  Kleintitel      – Stationen, Karten-Popups, Handy-Kapitel

   VIER TEXTGROESSEN. "Alles in einer" geht nicht ganz auf: eine Einleitung, die so
   gross ist wie die Meta-Zeile darunter, hat keine Rangfolge mehr. Also vier klar
   getrennte Rollen statt einer Wolke aus Zufallswerten:
   --t-lead   Einleitungsabsatz unter einer Ueberschrift
   --t        Fliesstext, ueberall derselbe
   --t-klein  Meta: Namen, Ortsangaben, Formularinhalte
   --label    gesperrte Versalzeile: Navigation, Knoepfe, Kicker
   --label-s  dieselbe Rolle in den drei engen Bauteilen (Kopfleiste, Kapitelnavi,
              Kartensuche), wo 10 px die Breite sprengen wuerden */
:root{
  --schrift-titel:"Barlow Condensed",sans-serif;
  --schrift-text:Arial,Helvetica,sans-serif;
  --h1:clamp(46px,6.2vw,110px);
  --h2:clamp(32px,3.6vw,58px);
  --h3:clamp(21px,2.1vw,30px);
  --t-lead:clamp(17px,1.35vw,21px);
  --t:16px;
  --t-klein:13px;
  --label:10px;
  --label-s:8px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;color:var(--ink);background:var(--paper);font-family:var(--schrift-text);font-size:var(--t);line-height:1.55;overflow-x:hidden}
section[id],#ablauf,#leistungen{scroll-margin-top:104px}
/* Eine Klasse fuer jede gesperrte Versalzeile. Vorher stand dieselbe Kombination
   aus Groesse, Fettung, Sperrung und Versalien 27-mal einzeln im Stylesheet — mit
   sieben verschiedenen Groessen und den Gewichten 700 und 800, die bei Arial
   ohnehin dieselbe Schnittdatei treffen. */
.section-number,.text-link,.hero-cta,.hero-place,.hero-zeiten,.hero-mark b,.partners__lead,.audience__lead,
.object__place,.object__scope li,.contact-actions a,.footer-cols h3,.footer-bottom p,.footer-bottom a,
.copy a,.counter,.subpage-kicker,.map-instruction,.map-finder button,.trust-brand span,.proof-case__meta,
.ba__tag,#map-retry,.site-nav a,.nav-services summary,.header-call,.menu-toggle,.mobile-chapter a,
.mobile-hero-copy>p,.mobile-hero-copy li,.mobile-hero-copy a,.mobile-header p,.popup small,
.mobile-notdienst
{font-size:var(--label);font-weight:700;letter-spacing:.12em;text-transform:uppercase}
/* Dieselbe Rolle, eine Stufe kleiner. Nur fuer Bauteile, die eine feste Breite haben
   und bei 10 px umbrechen wuerden: die Kopfleiste muss samt Navigation und Knopf in
   eine Pille passen, die Kapitelnavigation in eine Zeile, die Kartensuche in eine
   Formularzeile. */
.site-brand small,.map-finder label span,.chapter,.objects__leiste button{font-size:var(--label-s);font-weight:700;letter-spacing:.12em;text-transform:uppercase}

/* ===================== Aufdecken: Wortmaske =====================
   Jedes Wort einer Ueberschrift bekommt einen eigenen Kasten mit overflow:hidden,
   das <i> darin wird von unten hereingeschoben. Dadurch kommt die Schrift hinter
   einer Kante hervor, statt aus dem Nichts aufzutauchen. Die Kaesten baut app.js,
   im Markup steht ein ganz normaler Satz — faellt das Skript aus, ist er lesbar.

   Das Polster unten ist der Grund, warum die Maske nicht in die Unterlaengen
   schneidet: bei line-height unter 1 (alle grossen Ueberschriften hier) ist der
   Kasten niedriger als die Glyphen hoch sind, das g und das j wuerden abgesaebelt.
   Der negative Aussenabstand nimmt das Polster aus dem Layout wieder heraus, die
   Zeilenabstaende bleiben also exakt wie ohne Maske. */
.wort{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.18em;margin-bottom:-.18em}
.wort>i{display:inline-block;font-style:normal;will-change:transform}
@media(prefers-reduced-motion:reduce){.wort{overflow:visible}.wort>i{transform:none!important}}
img{display:block;max-width:100%}
a{color:inherit}
button,input{font:inherit}
a:focus-visible,button:focus-visible,input:focus-visible{outline:3px solid var(--accent);outline-offset:4px}
.section-number{margin:0 0 16px;color:var(--accent)}

/* One navigation system across the whole site. */
.site-header{position:fixed;z-index:1000;top:18px;left:50%;border-radius:999px;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:clamp(24px,4vw,70px);width:min(94vw,1540px);min-height:72px;padding:10px 12px 10px 18px;border:1px solid transparent;transform:translate(-50%,0);border-color:rgba(43,48,31,.14);background:var(--paper);box-shadow:0 18px 54px rgba(26,30,18,.14)}
/* Deckend und ab Seitenanfang sichtbar. Das Ein- und Ausblenden beim Scrollen
   gab es nur, weil die Navigation frueher ins Heldenbild gemalt war und die
   echte Leiste sie erst spaeter ersetzen durfte. Seit der Hero aus Einzelteilen
   besteht, gibt es nichts mehr zu ersetzen. Transparenz ebenfalls raus: hinter
   der Leiste laufen Olivband und vollbreite Bilder durch. */
.site-brand{display:flex;align-items:center;gap:11px;text-decoration:none}
.site-brand img{width:55px;height:auto;aspect-ratio:1;object-fit:contain;mix-blend-mode:multiply}
.site-brand span{display:grid;gap:1px}
/* Feste Groesse und damit bewusst ausserhalb der Ueberschriftstufen: die Wortmarke
   ist Teil des Logos, keine Ueberschrift. Sie muss zum 48-px-Zeichen daneben passen,
   nicht zur Rangfolge der Sektionstitel. */
.site-brand strong{font:500 29px/.9 var(--schrift-titel)}
.site-brand small{font-size:9px}
.site-nav{display:flex;align-items:center;justify-content:center;gap:clamp(22px,3vw,52px)}
.site-nav a,.header-call{text-decoration:none}.mobile-nav-contact{display:none}
.site-nav a,.nav-services summary{position:relative;padding:12px 0;font-size:12px;white-space:nowrap}.site-nav a::after,.nav-services summary::after{content:"";position:absolute;right:0;bottom:5px;left:0;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .3s ease}.site-nav a:hover::after,.nav-services summary:hover::after{transform:scaleX(1);transform-origin:left}
.nav-services{position:relative}.nav-services summary{display:flex;align-items:center;gap:8px;list-style:none;cursor:pointer}.nav-services summary::-webkit-details-marker{display:none}.nav-services__arrow{width:7px;height:7px;border-right:1px solid;border-bottom:1px solid;transform:translateY(-2px) rotate(45deg);transition:transform .2s ease}.nav-services[open] .nav-services__arrow{transform:translateY(2px) rotate(225deg)}.nav-services__menu{position:absolute;top:calc(100% - 2px);left:50%;display:grid;width:max-content;min-width:240px;padding:9px 16px;border:1px solid var(--line);border-radius:14px;background:var(--paper);box-shadow:0 16px 40px rgba(26,30,18,.14);transform:translateX(-50%)}.nav-services__menu a{padding:10px 0;font-size:10px}
.header-call{padding:18px 23px;border:1px solid var(--olive);border-radius:999px;color:#fff;background:var(--olive);white-space:nowrap}
/* Nur der Pfeil rueckt ab, nicht die Beschriftung. Frueher stand hier
   `.header-call span`, was seit der zweiten Beschriftung auch diese traefe. */
.header-call>span:last-child{margin-left:14px}
.header-call__kurz{display:none}
.menu-toggle{display:none;min-width:44px;min-height:44px;padding:8px;border:0;border-radius:12px;background:none;color:inherit}
.menu-toggle__icon,.menu-toggle__icon::before,.menu-toggle__icon::after{display:block;width:18px;height:2px;background:currentColor}.menu-toggle__icon{position:relative;margin-left:8px}.menu-toggle__icon::before,.menu-toggle__icon::after{content:"";position:absolute;left:0}.menu-toggle__icon::before{top:-6px}.menu-toggle__icon::after{top:6px}

/* Hero aus Einzelteilen statt als fertiges Bild. */
.image-hero{--hoehe:max(700px,100svh);--rahmen-b:max(100%,calc(var(--hoehe) * 1.79272));position:relative;height:var(--hoehe);overflow:hidden;background:#eae7dc}
.hero-scene{position:absolute;inset:0;overflow:hidden}
/* Traegt das Seitenverhaeltnis des Fotos und ist mindestens so gross wie der
   Abschnitt. Bild und Beschriftungen liegen dadurch im selben Koordinatensystem
   und koennen bei keiner Fensterbreite gegeneinander verrutschen — genau das
   waere passiert, haette das Bild nur ein object-fit und die Marken Prozente
   des Abschnitts. */
/* Der Rahmen wird nicht mehr mittig beschnitten. Alle fuenf Marken liegen
   zwischen 65 % und 87 % der Bildbreite; links davon deckt der Papierkeil das
   Foto ohnehin ab. Ist der Rahmen breiter als der Abschnitt, steht er deshalb
   hoechstens 10 % seiner Breite nach rechts hinaus — der Beschnitt faellt dann
   links an, wo nichts verloren geht. Mittig beschnitten liefen auf Fenstern um
   1280x1024 die rechten Marken aus dem Bild.
   Die Hoehe ergibt sich aus Breite und Seitenverhaeltnis und ist dadurch immer
   mindestens so hoch wie der Abschnitt — ein min-height braucht es nicht. */
.hero-frame{position:absolute;top:50%;right:calc(-1 * min((var(--rahmen-b) - 100%) / 2,var(--rahmen-b) * .1));
  width:var(--rahmen-b);aspect-ratio:2560/1428;transform:translateY(-50%)}
/* Nachkomme, nicht Kind: seit dem Hochkant-Ausschnitt steckt das Bild in
   einem <picture>. display:contents nimmt dem Wrapper seinen Kasten, sonst
   steht das Bild in einem Inline-Fluss statt im Rahmen. */
.hero-frame picture{display:contents}
.hero-frame img{width:100%;height:100%;object-fit:cover}
/* Die Ebene selbst faengt keine Klicks ab — sonst laege eine unsichtbare Platte
   ueber dem halben Heldenbild. Nur die Marken selbst sind anfassbar. */
.hero-marks{position:absolute;inset:0;pointer-events:none}
/* Die Route braucht ein liegendes Fenster. Nachgemessen ueber ein Raster von
   850–1800 px Breite und 700–1400 px Hoehe, samt Alphakanal des Papierkeils:
   unter Seitenverhaeltnis 1,3 schiebt der Keil die Beschriftungen unter sich,
   ueber 2,45 schneidet der Abschnitt oben und unten die aeusseren Marken ab.
   Dazwischen sind alle fuenf vollstaendig sichtbar. Ausserhalb bleibt der Hero
   wie er ist — nur die Route entfaellt, statt halb abgeschnitten dazustehen. */
@media (max-aspect-ratio:13/10),(min-aspect-ratio:49/20){.hero-marks{display:none}}
/* Der Hochkant-Ausschnitt braucht einen hochkanten Rahmen, sonst wuerde ihn das
   cover des Rahmenseitenverhaeltnisses zerschneiden. Auf dem Handy deckt der
   Rahmen deshalb einfach den Abschnitt — dort gibt es keine Marken, also auch
   kein Koordinatensystem zu erhalten. Bedingung wortgleich zum source im
   Markup; laeuft eine der beiden auseinander, landet das Hochformat in einem
   Querformatrahmen. */
@media (max-width:820px) and (orientation:portrait){
  .hero-frame{inset:0;width:auto;aspect-ratio:auto;transform:none}
}
/* Strichstaerke in viewBox-Einheiten: 4 von 2560 sind auf einem 1450 px
   breiten Rahmen rund 2,3 px. 10 nach der Skizze war zu fett, 6 immer noch —
   zu duenn fuer eine Linie, die eine Reihenfolge erzaehlen soll. Bei der
   Schleife um den Bagger war sie auf dem Foto praktisch nicht mehr zu
   lesen, und genau die Schleife ist der Grund fuer die Form. 10 war dann zu
   fett; 6 traegt die Schleife, ohne die Linie zum Hauptmotiv zu machen. */
.hero-marks__line{position:absolute;inset:0;width:100%;height:100%;stroke:var(--accent);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;opacity:.7}
/* --richtung zeigt zum Punkt hin: bei der seitenverkehrten Marke liegt der Punkt
   links, also kehrt sich auch die Bewegung beim Ueberfahren um. Eine Variable
   statt einer zweiten Hover-Regel. */
.hero-mark{--richtung:1;position:absolute;left:var(--x);top:var(--y);display:flex;align-items:center;padding-right:32px;transform:translate(-100%,-50%);pointer-events:auto;text-decoration:none;cursor:pointer}
.hero-mark b{padding:5px 0 5px 11px;border-left:2px solid #fff;color:#fff;line-height:1.15;white-space:nowrap;text-shadow:0 1px 7px rgba(10,20,8,.55);transition:transform .32s cubic-bezier(.2,.7,.2,1),border-color .32s ease}
.hero-mark::before{content:"";position:absolute;top:50%;right:14px;width:18px;height:1px;background:#fff;opacity:.85;transition:background .32s ease,opacity .32s ease}
.hero-mark::after{content:"";position:absolute;top:50%;right:0;width:13px;height:13px;margin-top:-7px;border:2px solid #fff;border-radius:50%;box-shadow:0 0 0 3px rgba(10,20,8,.22);transition:background .32s cubic-bezier(.2,.7,.2,1),transform .32s cubic-bezier(.2,.7,.2,1),box-shadow .32s ease}
/* Der Punkt fuellt sich, die Verbindung glueht auf, die Beschriftung ruckt zum
   Punkt hin. Bewusst am Punkt und nicht an der Schrift: der Punkt sitzt auf dem
   Motiv, um das es geht, und ist damit das, was die Verbindung herstellt. */
.hero-mark:hover b,.hero-mark:focus-visible b{border-color:var(--accent);transform:translateX(calc(5px * var(--richtung)))}
.hero-mark:hover::before,.hero-mark:focus-visible::before{background:var(--accent);opacity:1}
.hero-mark:hover::after,.hero-mark:focus-visible::after{background:var(--accent);transform:scale(1.35);box-shadow:0 0 0 5px rgba(var(--accent-rgb),.28)}
/* Seitenverkehrt fuer Marken, die zu weit links sitzen, um nach links zu
   beschriften — die Beschriftung liefe sonst unter den Papierkeil. */
.hero-mark--rechts{--richtung:-1;padding:0 0 0 32px;transform:translate(0,-50%)}
.hero-mark--rechts b{padding:5px 11px 5px 0;border-left:0;border-right:2px solid #fff}
.hero-mark--rechts::before{right:auto;left:14px}
.hero-mark--rechts::after{right:auto;left:0}
/* Einzige senkrechte Marke: Beim Bagger soll die lange Beschriftung unter dem
   Punkt stehen, damit sie nicht mehr quer ueber Aushub und Papierkeil laeuft. */
.hero-mark--unten{padding:24px 0 0;transform:translate(-50%,0)}
.hero-mark--unten b{padding:5px 0 5px 11px;border-top:0;border-left:2px solid #fff;text-align:center;transform:translateX(-9px)}
.hero-mark--unten::before{display:none}
.hero-mark--unten::after{top:0;right:auto;left:50%;margin:-7px 0 0 -7px}
.hero-mark--unten:hover b,.hero-mark--unten:focus-visible b{transform:translate(-9px,5px)}

/* Der freigestellte Papierkeil. --keil-x schiebt ihn waagerecht; negativ heisst
   nach links. Ein object-position bringt hier nichts: cover skaliert bei diesen
   Fensterformaten ueber die Breite, es gibt also gar keinen seitlichen
   Beschnitt, an dem sich verschieben liesse. Deshalb der Versatz am Element.
   Nach links freigelegte Flaeche rechts ist unkritisch — dort ist der Keil
   ohnehin durchsichtig. */
.image-hero{--keil-x:-23%}
.hero-wedge{position:absolute;z-index:2;top:0;bottom:0;left:var(--keil-x);width:100%;height:100%;object-fit:cover;object-position:left center;pointer-events:none}

/* Spalte folgt dem Keil: bei --keil-x:-23% liegt die Papierkante auf Hoehe der
   Leistungszeile bei 0,369 — die Spalte beginnt bei 0,045, mehr als 0,32 Breite
   passt dort nicht mehr auf das Papier. */
.hero-copy{position:absolute;z-index:3;top:50%;left:var(--pad);width:min(34vw,470px);transform:translateY(-52%)}
/* Blocktitel-Stufe. Der Wechsel von Georgia auf die Schmalschrift kostet keinen
   Grad, sondern bringt welchen ein: Barlow Condensed baut deutlich schmaler, in
   derselben 455-px-Spalte passt damit ein groesserer Grad in eine Zeile. */
.hero-copy h1{margin:0;color:var(--ink);font:500 var(--h2)/1.02 var(--schrift-titel);letter-spacing:-.02em;text-transform:uppercase}
.hero-lead{max-width:26ch;margin:clamp(18px,2vw,30px) 0 0;color:rgba(43,48,31,.82);font-size:var(--t-lead)}
.hero-services{position:relative;margin:clamp(24px,2.6vw,40px) 0 0;padding-top:clamp(20px,2.2vw,32px);color:var(--ink);font-size:var(--t-klein);font-weight:700}
.hero-services::before{content:"";position:absolute;top:0;left:0;width:52px;height:2px;background:var(--accent)}
.hero-cta{display:inline-block;margin-top:clamp(22px,2.4vw,36px);padding-bottom:7px;border-bottom:2px solid var(--accent);color:var(--accent);text-decoration:none}
/* Aussenform der Textspalte.

   Der Papierkeil laeuft nach unten schmaler zu. Gemessen an der Unterkante jedes
   Blocks (Alphakanal der Keilgrafik, abzueglich 10 px Luft) stehen zur Verfuegung:

                   900 px    1440 px   1920 px
   Ueberschrift    0,368     0,362     0,362  der Fensterbreite
   Fliesstext      0,315     0,312     0,320
   Leistungen      0,279     0,284     0,295
   Knopf           0,259     0,265     0,279

   Ueber alle drei Groessen praktisch konstant — deshalb bekommt jeder Block seine
   eigene Hoechstbreite in vw und die Spalte verjuengt sich von selbst wie das Papier,
   statt als Rechteck darin zu stehen.

   Der Fliesstext zusaetzlich in em, nicht nur in vw: wo er umbricht, haengt an der
   Schriftgroesse, und die waechst langsamer als das Fenster. Zwischen 19,8 em und
   24,7 em faellt seine Aussenkante ab — 385/357/119 px bei 1440, 416/386/128 bei
   1920, in em also dieselbe Spanne. 22 em liegt mittig darin. Knapp darunter kippt
   die Form: 204/305/351, die letzte Zeile also die laengste, der Block nach unten
   breiter statt schmaler — genau gegen den Keil. */
.hero-lead{max-width:min(22em,34vw)}
.hero-services{max-width:26vw;text-wrap:balance}
/* Die fallende Dreizeilerform braucht 20 em; ihre laengste Zeile misst dann 336 px.
   Das Papier bietet an der Unterkante des Absatzes rund 33 vw — bei 1000 px also nur
   331 px, die erste Zeile laege 5 px auf dem Foto. Nachgemessen kippt es zwischen
   1000 px (Papier 331, zu wenig) und 1051 px (passt); die Grenze liegt bei 1020 px.
   Darunter lieber die naechstbeste Form gezielt ansteuern statt die gute zu verfehlen:
   bei 17 em bricht der Absatz auf 179/267/165/137 px — kurze Auftaktzeile, danach zwei
   Stufen abwaerts. Ohne diese Regel landet man im Band darueber, und das ist mit
   179/267/307 die schlechteste Form von allen: jede Zeile laenger als die vorige,
   also genau gegen den Keil.
   text-wrap:balance ist hier bewusst NICHT die Loesung — ausprobiert bei 1180 px,
   Chrome liefert damit ebenfalls 179/267/307. Bei der kurzen Leistungszeile greift
   balance dagegen sauber (159/150 statt 222/87 mit "Baumarbeiten" allein). */
@media(max-width:1020px){.hero-lead{max-width:17em}}
.hero-cta span{margin-left:10px}
/* Der Fusspunkt des Heros traegt jetzt zwei Zeilen. Die absolute Position ist
   deshalb an den Behaelter gewandert — sonst muessten zwei Elemente unabhaengig
   voneinander am selben Rand ausgerichtet bleiben und liefen bei jeder
   Groessenaenderung auseinander. .hero-place steht darin nur noch als Zeile. */
.hero-fuss{position:absolute;z-index:3;bottom:clamp(26px,3vw,46px);left:var(--pad);display:grid;gap:12px}
.hero-place{display:flex;align-items:center;gap:9px;margin:0;color:rgba(43,48,31,.72)}
/* Die Notdienstzeile ist das staerkere Versprechen und darf deshalb den Akzent
   tragen — aber nur der Punkt, nicht die Schrift. Ein farbiger Satz neben einer
   grauen Ortsangabe haette wie ein Werbebanner gewirkt. */
.hero-zeiten{margin:0 0 0 26px;color:rgba(43,48,31,.72);line-height:1.55}
/* Der Zusatz steht IMMER in einer eigenen Zeile, nicht erst am schmalen Ende.
   Einzeilig waere die Zeile breiter als das Papier an dieser Hoehe und laege
   teilweise auf dem Foto. Gestapelt liest sie sich ohnehin besser: oben die
   Regel, darunter die Ausnahme davon.
   21 px Einzug = Punkt (7) plus Zeilenluecke (9) plus dessen Versatz (5). */

/* "+ 30 km" ist eine Praezisierung, keine zweite Ortsangabe — deshalb aus den
   fetten Versalien der Zeile herausgenommen statt daneben gestellt. */
.hero-place__radius{color:rgba(43,48,31,.9);font-weight:700;letter-spacing:.1em;opacity:1}
/* Der Papierkeil laeuft nach unten schmaler zu — an der Ortszeile liegt seine
   Kante bei rund 25 vw. "Dortmund & Umgebung (+ 30 km)" ist knapp 300 px breit
   und stand ab etwa 1200 px Fensterbreite mit dem Zusatz auf dem Foto statt auf
   dem Papier. Darunter faellt der Zusatz deshalb in eine eigene Zeile: die
   Ortsangabe rutscht dadurch nach oben, wo der Keil breiter ist. */
/* Ganz am unteren Ende des Desktop-Bereichs (821-900 px, direkt ueber dem Umschalten
   auf die Handy-Fassung) ist der Keil an seiner Unterkante so schmal, dass selbst
   "Dortmund & Umgebung" 2 px auf dem Foto lag — nachgemessen bei 821 px: Text bis 216,
   Papier bis 214. Die Schrift ist dort schon am Minimum ihrer clamp(), kann also nicht
   kleiner. Stattdessen rueckt die Zeile hoeher, wo der Keil breiter ist: die Kante
   faellt um rund 0,4 px je Pixel Hoehe, 31 px hoeher bringt also gut 12 px Papier. */

@media(max-width:900px){.hero-fuss{bottom:clamp(52px,7vw,72px)}}
@media(max-width:1240px){.hero-place{flex-wrap:wrap;row-gap:2px}
  /* 26px = Breite des Ortssymbols (17) plus die Luecke der Zeile (9), damit die
     zweite Zeile unter "Dortmund" beginnt und nicht unter dem Symbol. */
  .hero-place__radius{flex-basis:100%;margin-left:26px}}
.hero-place svg{width:17px;height:17px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6}
.hero-ai-label{position:absolute;z-index:4;right:0;bottom:0;margin:0;padding:11px 14px;color:#fff;background:rgba(43,48,31,.92);font-size:10px;line-height:1.4;letter-spacing:.06em;text-transform:uppercase}
.hero-ai-label[open]{width:min(330px,25vw)}.hero-ai-label summary{display:flex;align-items:center;gap:16px;justify-content:space-between;list-style:none;white-space:nowrap;cursor:pointer;font-weight:700}.hero-ai-label summary::-webkit-details-marker{display:none}.hero-ai-label summary::after{content:"+";font-size:15px;line-height:1}.hero-ai-label[open] summary::after{content:"−"}.hero-ai-label span{display:block;margin-top:6px;color:rgba(255,255,255,.74);font-weight:500}
/* Der weisse Verlauf an der Unterkante ist raus. Er sollte das Heldenbild in die
   Papierflaeche darunter ausblenden — seit dort das Olivband anschliesst, blendet
   er nach Weiss aus und stoesst dann hart auf Oliv. Das Bild endet jetzt mit
   einer klaren Kante gegen das Band. Das ::before auf Mobil bleibt: das ist der
   dunkle Verlauf, der die Schrift im Bild lesbar haelt. */
.mobile-hero-copy{display:none}

/* Feststehendes Bild hinter allem. z-index 0, der Inhalt darueber auf 1 — nicht
   negativ, denn der Seitenhintergrund wird auf die Leinwand hochgereicht und
   uebermalt alles mit negativem Index. display:flow-root spaeter verhindert an
   den richtigen Stellen, dass Randabstaende nach aussen durchschlagen. */
.fixed-bg{position:fixed;z-index:0;inset:0;overflow:hidden;pointer-events:none}
.fixed-bg img{width:100%;height:100%;object-fit:cover}
main,.site-footer{position:relative;z-index:1}
/* Der Schlitz, durch den man das feste Bild sah, ist entfallen. Sichtbar ist es
   jetzt nur noch schwach durch die Abschnittsflaechen hindurch (--flaeche, 93 %).
   Faellt dieser Test auch weg, hat das Bild keine Aufgabe mehr. */

/* Kein Polster oben und unten: die helle Flaeche soll genau so hoch sein wie der
   Kartenblock, damit das Band direkt anschliesst. Die Luft um die Texte kommt
   allein aus dem Innenpolster der Karten. */
.care-rhythm{position:relative;z-index:4;padding:0 var(--pad);background:var(--flaeche)}

.text-link{display:inline-block;padding-bottom:8px;border-bottom:1px solid var(--ink);text-decoration:none}
.rhythm-facts{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
/* Gleiches Polster oben wie unten, und die Hoehe ergibt sich daraus statt aus
   einem min-height. Vorher standen ueber jeder Ueberschrift 62 px Luft und
   darunter rund 52 — die 40 davon kamen aus dem margin-top der h2 weiter
   hinten in derselben Zeile, nicht aus dem Polster hier. */
.rhythm-facts article{padding:clamp(28px,3vw,44px) clamp(18px,2.2vw,38px);border-right:1px solid var(--line)}.rhythm-facts article:nth-child(1){padding-left:0;text-align:left}.rhythm-facts article:nth-child(2){text-align:center}.rhythm-facts article:nth-child(3){padding-right:0;text-align:right}.rhythm-facts article:last-child{border:0}.rhythm-facts h2{margin:0 0 12px;color:var(--ink);font:500 clamp(22px,1.65vw,30px)/1 var(--schrift-titel);letter-spacing:.06em;text-transform:uppercase}.rhythm-facts p{margin:0;max-width:34ch;color:rgba(43,48,31,.72)}.rhythm-facts article:nth-child(2) p{margin-inline:auto}.rhythm-facts article:nth-child(3) p{margin-left:auto}

/* Horizontal visual chapter — one image-world, copy changes with the work. */
.story{position:relative;height:290vh;background:var(--flaeche)}
/* Die Buehne reserviert oben und unten je einen Streifen, in den kein Text darf:
   oben fuer die Kopfleiste, unten fuer Kapitelknoepfe und Fortschrittsleiste.
   Dazwischen liegt genau eine freie Reihe, und der Textblock sitzt darin. Damit
   kann er die beiden Zonen nicht mehr erreichen — unabhaengig davon, wie lang der
   Text wird oder was spaeter noch unten dazukommt.
   Vorher stand der Block auf einem festen Abstand zur Unterkante. Auf breiten,
   flachen Fenstern lief er darueber hinaus: bei 1920x820 gemessen war der Kasten
   200 px hoch, sein Inhalt aber 353 px, und "Leistung ansehen" landete bei drei
   von vier Kapiteln unter den Knoepfen. */
.stage{position:sticky;top:0;height:100svh;min-height:640px;overflow:hidden;isolation:isolate;
  display:grid;grid-template-rows:var(--zone-oben) 1fr var(--zone-unten);
  --zone-oben:113px;--zone-unten:96px}
.viewport,.world{position:absolute;inset:0}.world{width:235vw;will-change:transform}
/* Das vorhandene 3044-px-Masterpanorama ist bereits die nahtlose Komposition.
   Eine Ebene statt zweier Teilbilder: keine Ueberlappung, keine Maske, keine
   Kante. Die horizontale Kamerafahrt bleibt unveraendert. */
.panorama{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
.stage::after{content:"";position:absolute;z-index:2;inset:0;pointer-events:none;background:rgba(22,26,15,.04)}

/* Kein absoluter Sitz mehr, sondern ein Feld der mittleren Reihe. align-self:end
   haelt ihn unten in dieser Reihe, justify-self entscheidet die Seite.
   Das Polster ist jetzt auch hoehenabhaengig: auf flachen Fenstern schrumpft es,
   sonst waere der Block bei 640 px Buehnenhoehe hoeher als die freie Reihe. */
.copy-fog{position:relative;z-index:10;grid-row:2;align-self:end;justify-self:end;
  width:min(46vw,720px);padding:clamp(20px,3.2vh,64px) clamp(30px,4vw,64px)}.copy-fog::before{content:"";position:absolute;z-index:-1;inset:-42% -22%;background:radial-gradient(ellipse at center,rgba(248,246,239,.96) 0,rgba(248,246,239,.8) 34%,rgba(248,246,239,.22) 67%,transparent 76%);filter:blur(14px)}.copy-fog[data-side="right"]{justify-self:start;margin-left:var(--pad)}
.copy-fog[data-side="right"]::before{inset:-42% -18% -42% -58%}.copy-fog[data-side="left"]{margin-right:var(--pad)}
.copy-fog[data-side="left"]::before{inset:-42% -58% -42% -18%}
/* Die data-side-Namen beschreiben die Einblendrichtung; im Layout liegt
   "left" rechts im Bild. Dort folgt auch der Satz der rechten Kante. */
.copy-fog[data-side="left"]{text-align:right}
.copy-fog[data-side="left"] .copy h2,.copy-fog[data-side="left"] .copy p{margin-left:auto}
.copy-fog[data-side="right"]{text-align:left}
.counter{margin:0 0 14px;color:var(--accent)}.copy-stack{display:grid}/* Alle Texte in derselben Rasterzelle: sie liegen uebereinander wie vorher,
   aber der Stapel ist so hoch wie der laengste. Das feste min-height:200px
   war eine Schaetzung, und der Inhalt lief darueber hinaus. */
.copy{grid-area:1/1;opacity:0;visibility:hidden}/* Sichtbarer Ausgangszustand ohne JS. GSAP setzt waehrend der Ueberblendung
   Inline-Werte, die hierueber gewinnen — die Klasse ist nur der Startpunkt. */
.copy.is-active{visibility:visible;opacity:1}/* hyphens:auto als Netz fuer kuenftige Komposita, weiche Trennzeichen im Markup
   fuer die bekannten. Ohne beides steht z. B. "Baumschnittarbeiten" als ein
   unteilbares Wort ueber der max-width und .stage schneidet es ab.
   padding-bottom haelt die Unterlaengen im Kasten: bei line-height .9 ragen die
   Schwaenze von g und j darunter hinaus und wurden von der Aufdeckmaske
   abgeschnitten. */
.copy h2{margin:0;padding-bottom:.14em;max-width:13ch;font:500 var(--h1)/.9 var(--schrift-titel);letter-spacing:-.03em;text-transform:uppercase;hyphens:auto}.copy p{max-width:46ch;margin:22px 0 18px}.copy a{text-decoration:none}
.chapter-nav{position:absolute;z-index:15;bottom:22px;left:50%;transform:translateX(-50%);display:flex;gap:8px}.chapter{padding:7px 12px;border:1px solid rgba(43,48,31,.2);color:var(--ink);background:rgba(248,246,239,.86);cursor:pointer;backdrop-filter:blur(12px)}.chapter.is-active{color:#fff;background:rgba(43,48,31,.86)}
.progress{position:absolute;z-index:18;right:0;bottom:0;left:0;height:5px;background:rgba(43,48,31,.14)}.progress span{display:block;width:100%;height:100%;background:var(--accent);transform:scaleX(0);transform-origin:left}
.mobile-story{display:none}

/* Mehr Luft ueber dem Bild, weniger darunter. Die Textspalte haengt nicht mehr
   in der Mitte, sondern setzt oben an und wird nur durch ihr eigenes Polster
   heruntergedrueckt — so steht sie hoeher als das Bild sie zentrieren wuerde. */
.trust-section{display:grid;grid-template-columns:1.05fr .95fr;align-items:center;column-gap:clamp(55px,9vw,150px);row-gap:clamp(40px,5vw,80px);padding:clamp(58px,6.5vw,112px) var(--pad) clamp(28px,3vw,50px);background:var(--flaeche)}
.trust-copy{align-self:start;padding-top:clamp(20px,6vw,96px)}
.trust-portrait{position:relative;height:clamp(460px,48vw,760px);overflow:hidden;}.trust-portrait img{width:100%;height:100%;min-height:inherit;object-fit:cover;object-position:center 30%;transform:scale(1.03)}.trust-portrait::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 60%,rgba(26,30,18,.72))}.trust-portrait p{position:absolute;z-index:2;right:28px;bottom:24px;left:28px;margin:0;color:#fff;font-size:var(--label);font-weight:700;letter-spacing:.12em;line-height:1.45;text-transform:uppercase}
.visual-note{position:absolute;z-index:5;top:12px;right:12px;padding:7px 9px;border-radius:8px;color:#fff;background:rgba(26,30,18,.82);font-size:9px;font-weight:700;line-height:1.25;letter-spacing:.08em;text-transform:uppercase}
.trust-copy h2{margin:0;max-width:11ch;font:500 var(--h1)/.88 var(--schrift-titel);letter-spacing:-.035em;text-transform:uppercase}.trust-copy>p:not(.section-number){max-width:46ch;margin:30px 0;font-size:var(--t-lead)}

.project-map{padding:clamp(88px,9vw,148px) var(--pad) clamp(42px,4.5vw,72px);background:radial-gradient(circle at 85% 14%,rgba(255,255,255,.14),transparent 34%),linear-gradient(125deg,#626548 0%,var(--olive) 54%,#a4a67e 100%)}
.map-heading{margin-bottom:48px;text-align:center}
/* Volle Breite als eigene Zeile unter den Feldern. Der Kasten steht auf hellem
   Papier, nicht auf der Karte — die Farbe kommt deshalb von --ink, nicht von Weiss. */
.map-finder .map-hinweis{grid-column:1/-1;margin:2px 9px 3px;color:rgba(43,48,31,.72);font-size:11px;line-height:1.45;text-align:center}
.map-finder .map-hinweis a{color:var(--accent)}
.map-gebiet{max-width:56ch;margin:18px auto 0;color:rgba(255,255,255,.72);font-size:var(--t-klein);line-height:1.6}
.map-heading h2{margin:0;max-width:none;color:#fff;font:500 var(--h1)/.9 var(--schrift-titel);letter-spacing:-.035em;text-transform:uppercase}
.map-shell{position:relative;height:min(78svh,780px);min-height:560px;overflow:hidden;border-radius:clamp(22px,2vw,36px);background:#edeae0;box-shadow:0 35px 90px rgba(26,30,18,.15)}.map{position:absolute;inset:0}.map-loading{position:absolute;z-index:600;inset:0;display:flex;align-items:center;justify-content:center;gap:10px;margin:0;color:var(--ink);background:#edeae0;transition:opacity .45s ease}.map-loading.is-done{opacity:0;pointer-events:none}.map-loading span{width:16px;height:16px;border:2px solid rgba(43,48,31,.25);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}
.map-instruction{position:absolute;z-index:520;top:24px;right:24px;margin:0;padding:10px 14px;border:1px solid rgba(255,255,255,.3);color:#fff;background:rgba(34,38,24,.78);backdrop-filter:blur(12px)}
.map-finder{position:absolute;z-index:540;left:50%;bottom:20px;right:auto;width:min(560px,calc(100% - 40px));display:grid;grid-template-columns:minmax(150px,1.4fr) minmax(64px,.4fr) minmax(92px,.6fr) auto;gap:6px;padding:7px;border:1px solid rgba(255,255,255,.5);border-radius:18px;transform:translateX(-50%);transform-origin:bottom center;transition:padding .34s cubic-bezier(.2,.7,.2,1),gap .34s cubic-bezier(.2,.7,.2,1),transform .34s cubic-bezier(.2,.7,.2,1),box-shadow .34s ease,background .34s ease;background:rgba(248,246,239,.93);box-shadow:0 18px 55px rgba(18,21,12,.22);backdrop-filter:blur(18px)}/* Nur das Polster waechst, nicht der Inhalt: so wird der Kasten groesser, ohne dass
   Schrift und Felder mitspringen. :focus-within haelt ihn waehrend der Eingabe offen. */
/* Deutlich staerker: Polster fast vervierfacht, groessere Luecken, der Kasten hebt ab.
   Der Inhalt bleibt unveraendert gross — es waechst nur der Rahmen um ihn herum. */
.map-finder:hover,.map-finder:focus-within{padding:26px;gap:12px;transform:translate(-50%,-10px);background:rgba(248,246,239,.99);box-shadow:0 34px 90px rgba(18,21,12,.42)}
.map-finder label{display:grid;gap:4px}.map-finder label span{padding-left:9px}.map-finder input{width:100%;min-width:0;padding:7px 10px;border:1px solid rgba(43,48,31,.2);border-radius:999px;color:var(--ink);background:#fff;font-size:var(--t-klein)}.map-finder button{display:flex;align-items:center;justify-content:center;gap:8px;padding:8px 14px;border:0;border-radius:999px;color:#fff;background:var(--accent);cursor:pointer}.map-cta{display:flex;width:max-content;max-width:100%;align-items:center;justify-content:center;gap:18px;margin:28px auto 0;padding:17px 24px;border-radius:999px;color:var(--ink);background:var(--paper);font-size:var(--label);font-weight:700;letter-spacing:.08em;text-align:center;text-decoration:none;text-transform:uppercase}.map-cta:hover{background:#fff}.map-cta span{font-size:1.25em}
.distance-label{padding:4px 7px;border:0;border-radius:999px;color:var(--ink);background:rgba(248,246,239,.92);box-shadow:0 2px 10px rgba(26,30,18,.18);font:700 11px/1 var(--schrift-text);letter-spacing:.04em}.distance-label::before{display:none}
.privacy-position-label{padding:6px 9px;border:1px solid rgba(248,246,239,.5);border-radius:8px;color:var(--ink);background:rgba(248,246,239,.88);box-shadow:0 8px 22px rgba(26,30,18,.14);font:650 10px/1.25 var(--schrift-text);letter-spacing:.035em}.privacy-position-label::before{border-top-color:rgba(248,246,239,.88)}
/* Kleiner und laenglicher: scaleY VOR rotate, dadurch streckt sich die Tropfenform
   nach unten statt schraeg zu verzerren. Der innere Punkt war dunkelgruen und
   las sich als schwarzes Loch — jetzt hell. */
.pin-marker{position:relative;display:block;width:24px;height:24px;border:2px solid #fff8e9;border-radius:50% 50% 50% 0;background:var(--accent);transform:scaleY(1.3) rotate(-45deg);box-shadow:0 8px 18px rgba(0,0,0,.34)}.pin-marker::after{content:"";position:absolute;inset:6px;border-radius:50%;background:#fff8e9}.pin-marker--you{background:#7e805d}.marker-cluster-small,.marker-cluster-medium,.marker-cluster-large{background:rgba(var(--accent-rgb),.25)}.marker-cluster-small div,.marker-cluster-medium div,.marker-cluster-large div{color:#fff;background:var(--accent)}.map-shell .leaflet-control-zoom a{width:60px;height:60px;line-height:60px;font-size:30px}.leaflet-popup-content-wrapper{overflow:hidden;color:var(--ink);background:var(--paper);box-shadow:0 20px 54px rgba(0,0,0,.34)}.leaflet-popup-content{width:260px!important;max-width:72vw;margin:0}.leaflet-popup-tip{background:var(--paper)}.popup img{width:100%;height:132px;object-fit:cover}.popup div{padding:13px 15px 16px}.popup small{color:var(--accent)}.popup h3{margin:4px 0 0;font:500 var(--h3)/1 var(--schrift-titel);text-transform:uppercase}.popup p{margin:7px 0 0;font-size:var(--t-klein);line-height:1.45}
.leaflet-control-attribution{font-size:10px!important;background:rgba(248,246,239,.88)!important}

.footer-brand{text-decoration:none}

/* ===== Kopfleiste zwischen Handy und grossem Bildschirm =====
   Drei sichtbare Zustaende, rein in CSS: vollstaendige Wortmarke, nur das
   Signet als platzsparender Zwischenschritt, danach Wortmarke plus Burger.
   Dadurch verschwindet die Navigation erst, wenn selbst die reduzierte Leiste
   nicht mehr passt. */
.site-brand strong,.site-brand small{white-space:nowrap}

@media(max-width:1520px){
  .site-header{gap:clamp(20px,3.4vw,50px)}
  .site-nav{gap:clamp(16px,2.2vw,32px)}
}
@media(max-width:1399px){
  .header-call__lang{display:none}.header-call__kurz{display:inline}
  /* Zweite Stufe der Abstaende. Sie greift genau dann, wenn der Knopf schon
     auf "Kontakt" geschrumpft ist. */
  .site-header{gap:clamp(18px,2.6vw,40px)}
  .site-nav{gap:clamp(14px,1.7vw,26px)}
}

/* Platzsparender Zwischenschritt: Das Signet bleibt sichtbar, nur Name und
   Unterzeile gehen voruebergehend. */
@media(max-width:1070px) and (min-width:821px){
  .site-header{gap:clamp(14px,1.8vw,20px)}
  .site-brand span{display:none}
  .site-nav{gap:clamp(10px,1.2vw,16px)}
}

/* Erst hier das Burger-Menue. Im kompakten Zustand kommt die vollstaendige
   Wortmarke wieder, weil Menuepunkte und Kontaktknopf nicht mehr daneben stehen. */
@media(max-width:820px){
  .site-header{top:10px;display:flex;justify-content:space-between;width:calc(100vw - 20px);min-height:62px;padding:8px 12px;border-radius:999px;opacity:1;pointer-events:auto;transform:translate(-50%,0);background:var(--paper);box-shadow:0 14px 42px rgba(26,30,18,.12)}.site-brand span{display:grid}.site-brand img{width:40px}.site-brand strong{font-size:21px}.menu-toggle{display:inline-flex;align-items:center}.header-call{display:none}.site-nav{position:absolute;top:calc(100% + 8px);right:0;left:0;display:grid;gap:0;padding:10px 18px;border:1px solid var(--line);border-radius:22px;background:rgba(248,246,239,.96);box-shadow:0 18px 40px rgba(26,30,18,.15);opacity:0;visibility:hidden;transform:translateY(-8px);transition:.25s ease}.site-nav.is-open{opacity:1;visibility:visible;transform:none}.site-nav a,.nav-services summary{justify-content:center;padding:15px 4px;border-bottom:1px solid var(--line);text-align:center}.nav-services{display:grid}.nav-services__menu{position:static;width:auto;min-width:0;padding:0 12px 8px;border:0;border-radius:0;background:transparent;box-shadow:none;transform:none}.nav-services__menu a{padding:10px 4px;font-size:9px}.site-nav .mobile-nav-contact{display:block;margin-top:8px;border:0;border-radius:999px;color:#fff;background:var(--accent);text-align:center}
}

@media(max-width:820px){
  /* Die Sektionstitel werden auf dem Handy nicht ueber eine eigene Regel je Sektion
     kleiner gesetzt, sondern ueber die Stufe selbst. Vorher stand derselbe Gedanke
     viermal einzeln im Stylesheet (58 px hier, 46 px dort, 45 px im Handy-Kapitel)
     und lief dadurch auseinander. */
  :root{--h1:clamp(44px,12vw,66px);--h2:clamp(34px,8.6vw,46px);--h3:clamp(22px,5vw,28px)}
    .image-hero{height:100svh;min-height:720px;padding-top:78px;background:#2e3524}/* Auf dem Handy traegt der Keil nicht: er ist quer angelegt, und in einem hohen
     schmalen Rahmen laege die Diagonale ausserhalb des Bildes. Stattdessen wie
     bisher das Foto abgedunkelt mit Text darauf. */
  .hero-wedge,.hero-marks,.hero-copy,.hero-fuss{display:none}
  /* object-position ist hier ersatzlos entfallen: Foto und Rahmen haben
     dasselbe Seitenverhaeltnis, cover schneidet also gar nichts weg — die
     Angabe hat nie gewirkt. Welcher Bildausschnitt auf dem Handy zu sehen
     ist, entscheidet allein die Lage des Rahmens. Seit dieser rechts
     ausgerichtet ist, zeigt der Ausschnitt 64–90 % des Fotos, also
     Heckenschnitt, Freischneider, Bagger und Maeher statt der Fassade. */
  .hero-frame img{filter:saturate(.86) brightness(.72)}.image-hero::before{content:"";position:absolute;z-index:2;inset:0;background:linear-gradient(180deg,rgba(26,30,18,.05) 18%,rgba(26,30,18,.18) 42%,rgba(18,21,12,.9) 100%)}.hero-hit{display:none}.mobile-hero-copy{position:absolute;z-index:3;right:24px;bottom:78px;left:24px;display:grid;justify-items:center;color:#fff;text-align:center}.mobile-hero-copy>p{margin:0 0 12px}
  /* Die einzige bewusste Ausnahme von den drei Stufen. Auf dem Handy ist diese Zeile
     nicht die Ueberschrift einer Sektion, sondern das Bild selbst — sie fuellt den
     halben Bildschirm. Mit --h1 (max. 66 px) waere der Hero eine Textzeile unter
     vielen. */
  .mobile-hero-title{margin:0;font:500 clamp(58px,17vw,90px)/.82 var(--schrift-titel);letter-spacing:-.035em;text-transform:uppercase}.mobile-hero-copy ul{display:flex;width:100%;flex-wrap:wrap;justify-content:center;gap:8px 18px;margin:23px 0 26px;padding:0;list-style:none}.mobile-hero-copy li::before{content:"";display:inline-block;width:5px;height:5px;margin:0 7px 1px 0;border-radius:50%;background:var(--accent)}.mobile-hero-copy a{padding:17px 21px;color:#fff;background:var(--accent);text-decoration:none}.mobile-hero-copy a span{margin-left:14px}
  .hero-ai-label{max-width:calc(100% - 24px);padding:9px 11px;font-size:8px}.hero-ai-label[open]{width:min(330px,calc(100% - 24px))}
  .rhythm-facts{grid-template-columns:1fr}.rhythm-facts article,.rhythm-facts article:first-child{padding:28px 0;border-right:0;border-bottom:1px solid var(--line)}.rhythm-facts article:nth-child(n){text-align:center}.rhythm-facts article:nth-child(n) p{margin-inline:auto}.rhythm-facts article:last-child{border-bottom:0}.rhythm-facts h2{margin:0 0 10px}
  .story{display:none}.mobile-story{display:grid;gap:70px;padding:90px 18px 110px;background:var(--flaeche)}.mobile-header p{margin:0 0 14px;color:var(--accent)}.mobile-header h2{margin:0;font:500 var(--h1)/.92 var(--schrift-titel);letter-spacing:-.03em;text-transform:uppercase}.mobile-chapter{display:grid;gap:22px}.mobile-scene{position:relative;height:58svh;min-height:420px;overflow:hidden;}.mobile-panorama{width:350%;max-width:none;height:116%;object-fit:cover;object-position:var(--scene-x) center;transform:translateY(-7%)}.mobile-chapter h2{margin:10px 0;font:500 var(--h2)/1 var(--schrift-titel);text-transform:uppercase}.mobile-chapter p{margin:0 0 14px}.mobile-chapter a{text-decoration:none}
  .trust-section{grid-template-columns:1fr}.trust-portrait{min-height:62svh}
  .map-shell{min-height:720px}.map-finder{grid-template-columns:1fr 1fr;right:10px;bottom:10px;left:10px}.map-finder label:first-child{grid-column:1/-1}.map-finder button{grid-column:1/-1}.map-instruction{top:12px;right:58px;left:12px;padding-right:8px;padding-left:8px;font-size:var(--label-s);text-align:center}
  .proof-section,.contact-actions{flex-direction:column}
}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;animation-duration:.01ms!important;transition-duration:.01ms!important}.story{height:auto}.stage{position:relative}.world{width:100%}.copy-fog{position:absolute}.chapter-nav,.progress{display:none}}

/* ===================== Preloader: Rasen waechst, Rasen wird gemaeht =====================
   Aus 03-prototypes/preloader-lab uebernommen. Der Rasen wird zur Laufzeit als SVG
   erzeugt — kein Bild, kein Netzwerk-Asset, damit der Ladebildschirm nicht selbst auf
   einen Download wartet. Details und Stellschrauben: preloader-lab/HANDOFF-PRELOADER.md */
body.is-loading{overflow:hidden}
/* z-index MUSS ueber dem der Kopfleiste liegen (die steht auf 1000). Bei 200 lag
   die Navigation vor dem Ladebildschirm und war die ganze Zeit sichtbar — der
   Ladebildschirm soll aber alles verdecken, was danach kommt. */
.preloader{position:fixed;z-index:2000;inset:0;display:grid;grid-template-rows:1fr auto auto;align-items:end;
  padding:clamp(1.5rem,5vw,5rem);background:var(--paper);transition:opacity .6s ease,visibility .6s ease}
.preloader.is-done{opacity:0;visibility:hidden}
.preloader__brand{align-self:center;justify-self:center;text-align:center;color:var(--ink)}
.preloader__brand strong{display:block;font:500 var(--h1)/.8 var(--schrift-titel);letter-spacing:-.03em;text-transform:uppercase}
/* Zweite Zeile ohne zweite Schriftfamilie: der Unterschied kommt jetzt aus Grad und
   Sperrung statt aus einer Kursiven. Georgia stand hier fuer ein einziges Wort und
   war damit die dritte Familie der Seite. */
.preloader__brand span{display:block;margin-top:.9rem;color:var(--ink-2);font:500 var(--h3)/1 var(--schrift-titel);letter-spacing:.42em;text-indent:.42em;text-transform:uppercase}
/* --cut = wie weit von oben abgedeckt wird. Kleiner = Schnitt hoeher angesetzt. */
.preloader__grass{--cut:47%;position:relative;height:clamp(6rem,14vw,10rem);overflow:hidden}
.preloader__grass svg{position:absolute;inset:0;width:100%;height:100%}
.preloader__growth{position:absolute;inset:0;background:var(--paper);transform-origin:right;transform:scaleX(1)}
.preloader__cut{position:absolute;z-index:2;left:0;right:0;top:0;height:var(--cut);background:var(--paper);transform:scaleX(0);transform-origin:left}
.preloader__tips{z-index:2;pointer-events:none;clip-path:inset(0 100% 0 0)}
.preloader__debris{z-index:4;pointer-events:none;overflow:visible}
.preloader__blade{position:absolute;z-index:3;top:calc(var(--cut) - 7%);bottom:0;width:2px;background:var(--accent);left:0;opacity:0;box-shadow:0 0 1.2rem var(--accent)}
.preloader__percent{margin:.7rem 0 0;text-align:right;font:500 var(--t)/1 var(--schrift-titel);letter-spacing:.15em}
@media(prefers-reduced-motion:reduce){.preloader{display:none}}

/* ===================== Ablauf als Weg =====================
   Statt einer Liste eine Route, die sich beim Scrollen zeichnet. Gleiche raeumliche
   Sprache wie die Horizontalfahrt — eine Tabelle mit Nummern davor war der Fremdkoerper.
   Die Linie liegt als SVG hinter den Stationen; die Stationen sitzen auf einem
   4-Spalten-Raster genau ueber den Punkten, an denen die Kurve durchlaeuft. */


/* ===================== Vorher/Nachher-Vergleich =====================
   Das Nachher-Bild liegt unten, das Vorher-Bild darueber in einem Container, dessen
   Breite der Regler steuert. Das innere Bild behaelt volle Rahmenbreite, sonst wuerde
   es beim Ziehen mitgestaucht statt aufgedeckt. Bedienung ueber ein echtes
   <input type=range>: damit funktioniert Tastatur und Screenreader ohne Zusatzcode. */

.ba{margin:0}
.ba__frame{--split:50%;position:relative;overflow:hidden;aspect-ratio:4/3;background:#232817;isolation:isolate}
/* width statt max-width + margin-inline:auto. Auto-Margins lassen ein Grid-Element
   auf seinen Inhalt schrumpfen — hier sind alle Bilder absolut positioniert, also
   war der Inhalt 0 breit und der Rahmen verschwand komplett. */
.ba__frame--portrait{aspect-ratio:3/4;width:min(430px,100%);justify-self:center}
@media(max-width:820px){.ba__frame--portrait{max-width:100%}}
.ba__frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;user-select:none;-webkit-user-drag:none}
/* clip-path statt einer schrumpfenden Box: das Bild behaelt immer die volle
   Rahmenbreite und wird nur beschnitten. Mit width:var(--split) wurde es beim Ziehen
   mitgestaucht — dann vergleicht man zwei verschieden breite Bilder statt derselben Stelle. */
.ba__before{position:absolute;inset:0;clip-path:inset(0 calc(100% - var(--split)) 0 0)}
.ba__handle{position:absolute;top:0;bottom:0;left:var(--split);z-index:3;width:2px;margin-left:-1px;background:var(--paper);pointer-events:none;box-shadow:0 0 0 1px rgba(26,30,18,.25)}
.ba__handle::after{content:"";position:absolute;top:50%;left:50%;width:44px;height:44px;margin:-22px 0 0 -22px;border:2px solid var(--paper);border-radius:50%;background:rgba(26,30,18,.35);backdrop-filter:blur(6px)}
.ba__handle::before{content:"‹ ›";position:absolute;top:50%;left:50%;z-index:1;transform:translate(-50%,-50%);color:var(--paper);font-size:var(--t);letter-spacing:2px}
/* Der Regler liegt unsichtbar ueber dem ganzen Rahmen und ist die eigentliche Bedienung. */
.ba__range{position:absolute;inset:0;z-index:4;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:ew-resize;-webkit-appearance:none;appearance:none;background:transparent}
.ba__range::-webkit-slider-thumb{-webkit-appearance:none;width:52px;height:100%;cursor:ew-resize}
.ba__range::-moz-range-thumb{width:52px;height:100%;border:0;cursor:ew-resize}
.ba__range:focus-visible{opacity:1;outline:none}
.ba__range:focus-visible+.ba__tag,.ba:focus-within .ba__handle{box-shadow:0 0 0 2px var(--accent)}
.ba__tag{position:absolute;top:16px;z-index:3;padding:7px 12px;background:rgba(26,30,18,.72);color:var(--paper);backdrop-filter:blur(8px);pointer-events:none}
.ba__tag--before{left:16px}
.ba__tag--after{right:16px}
.ba figcaption{margin-top:16px;color:rgba(248,246,239,.72)}

/* ===================== Kontakt: zwei Kreise, Parallax, Pulsieren =====================
   Als echte Elemente statt ::before, damit GSAP sie einzeln bewegen kann. Das Pulsieren
   laeuft bewusst langsam und mit unterschiedlicher Dauer je Kreis — synchron wirkt es
   wie ein Ladebalken. */
.contact-orb{position:absolute;left:50%;aspect-ratio:1;border:1px solid rgba(255,255,255,.28);border-radius:50%;pointer-events:none;will-change:transform}
/* Zentriert ueber negative Margins statt transform: GSAP animiert scale auf denselben
   Elementen, ein translate im CSS wuerde davon ueberschrieben. */
.contact-orb--lg{--d:min(70vw,900px);top:50%;width:var(--d);margin:calc(var(--d)/-2) 0 0 calc(var(--d)/-2)}
.contact-orb--sm{--d:min(34vw,430px);top:50%;width:var(--d);margin:calc(var(--d)/-2) 0 0 calc(var(--d)/-2);border-color:rgba(255,255,255,.4)}
@media(prefers-reduced-motion:reduce){.contact-orb{display:none}}

/* ===================== Footer =====================
   Bis 16.08.2026 dunkles Oliv-Schwarz. Jetzt derselbe Papierton wie die uebrigen
   Sektionen — und zwar var(--paper) und nicht var(--flaeche): der Footer ist die
   einzige Flaeche, die ausdruecklich NICHT durchscheinen soll. Das feste
   Hintergrundbild endet damit sichtbar am Fussbereich.
   Alles, was vorher hell auf dunkel stand, ist mitgedreht — Trennlinien auf
   var(--line), Schrift auf var(--ink). */
.site-footer{padding:clamp(64px,7vw,110px) var(--pad) 34px;color:var(--ink);background:var(--paper)}
.footer-top{display:grid;align-items:end;gap:clamp(30px,5vw,90px);
  padding-bottom:clamp(40px,4.5vw,66px);border-bottom:1px solid var(--line)}
/* Zeichen und Wortmarke als eine Einheit. Das Logo ist ein helles Oliv mit
   Transparenz; auf Papier wirkt es sonst verwaschen. mix-blend-mode:multiply
   rechnet es in den Untergrund hinein — dieselbe Behandlung wie in der
   Kopfleiste und ueber "Das sind wir.", damit die Marke ueberall gleich aussieht. */
.footer-lockup{display:flex;align-items:flex-end;gap:clamp(16px,1.8vw,28px)}
.footer-lockup img{width:clamp(64px,7vw,118px);height:auto;aspect-ratio:1;object-fit:contain;mix-blend-mode:multiply}
.footer-brand{display:block;font:500 var(--h1)/.82 var(--schrift-titel);letter-spacing:-.03em;text-transform:uppercase;text-decoration:none}
/* :not(.wort) ist Pflicht, sobald app.js die Zeile wortweise zerlegt: die
   Wortkaesten sind ebenfalls <span> und wuerden von einem blossen
   ".footer-brand span" mitgefaerbt — dann steht die ganze Wortmarke in der
   Akzentfarbe statt nur die zweite Zeile. Direkter Kindbezug, damit die Regel
   auch dann noch genau ein Element trifft. */
.footer-brand>span:not(.wort){display:block;color:var(--accent)}

.footer-cols{display:grid;grid-template-columns:repeat(4,1fr);gap:34px;padding:clamp(40px,4.5vw,66px) 0}
.footer-cols h3{margin:0 0 16px;color:rgba(43,48,31,.5)}
.footer-cols a{display:block;padding:7px 0;color:var(--ink);text-decoration:none;transition:color .25s ease,padding-left .25s ease}
.footer-cols a:hover{color:var(--accent);padding-left:6px}
.footer-bottom{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:16px;padding-top:26px;border-top:1px solid var(--line)}
.footer-bottom p{margin:0;color:rgba(43,48,31,.55)}
.footer-bottom a{color:var(--ink);text-decoration:none}
@media(max-width:820px){
  .footer-top{grid-template-columns:1fr;align-items:start}
  .footer-lockup{align-items:center;gap:14px}
  .footer-lockup img{width:56px;height:auto}
  .footer-cols{grid-template-columns:1fr 1fr;gap:26px}
}

/* ===================== Referenzen: Fall fuer Fall =====================
   Vorher zeigen und daneben erzaehlen, was gemacht wurde. Die Sticky-Textspalte davor
   liess keinen Platz fuer die Falltexte — jetzt Intro oben, darunter je Fall Vergleich
   und Beschreibung nebeneinander, im Wechsel gespiegelt. */
.proof-section{position:relative;padding:clamp(70px,8vw,120px) var(--pad) clamp(80px,9vw,140px);color:var(--paper);background:var(--ink)}

/* Konzept-Unterseiten: eigene, ruhige Kopfzeile statt der eingeblendeten
   Hauptnavigation — die haengt an Scrollpositionen der Startseite. */
.subpage-head{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:clamp(20px,2.4vw,34px) var(--pad);border-bottom:1px solid var(--line);background:var(--paper)}
.subpage-intro{max-width:1540px;margin:0 auto;padding:clamp(60px,7vw,120px) var(--pad) clamp(40px,4.5vw,72px)}
.subpage-kicker{margin:0 0 14px;color:var(--accent)}
.subpage-intro h1{margin:0;font:500 var(--h1)/.9 var(--schrift-titel);letter-spacing:-.035em;text-transform:uppercase}
.subpage-intro p:not(.subpage-kicker){max-width:52ch;margin:22px 0 0;color:rgba(43,48,31,.72);font-size:var(--t-lead)}
@media(max-width:820px){.subpage-head{flex-direction:column;align-items:flex-start;gap:14px}}



.proof-cases{display:grid;gap:clamp(56px,7vw,110px)}
.proof-case{display:grid;grid-template-columns:1.35fr .65fr;align-items:center;gap:clamp(28px,4vw,64px);margin:0}
.proof-case--flip{grid-template-columns:.65fr 1.35fr}
.proof-case--flip .ba__frame{order:2}
.proof-case--flip .proof-case__copy{order:1}
.proof-case__copy h3{margin:0;font:500 var(--h2)/1.05 var(--schrift-titel);letter-spacing:-.01em;text-transform:uppercase}
.proof-case__copy p{margin:16px 0 0;color:rgba(43,48,31,.8);line-height:1.6}
.proof-case__meta{color:var(--accent)!important}
@media(max-width:820px){
  .proof-case,.proof-case--flip{grid-template-columns:1fr;gap:22px}
  .proof-case--flip .ba__frame{order:0}
  .proof-case--flip .proof-case__copy{order:0}
}
.trust-lead{margin:18px 0 0;max-width:40ch;font-size:var(--t-lead);color:rgba(43,48,31,.75)}


/* ===================== Rezensionen: stehendes, schmales Band =====================
   Kein Laufband mehr — dauernde Bewegung zog die Aufmerksamkeit vom Inhalt ab und
   liess sich nicht in Ruhe lesen. Aufbau wie das Band unter dem Hero: Trennlinien
   statt Karten, kein Aussenabstand, die Sektion selbst ist der Rahmen. */
.reviews{padding:clamp(40px,5vw,80px) var(--pad) 0;background:var(--flaeche)}
/* Eigene CSS-Pfeile statt Unicode-Glyphen: auf iOS und Android keine
   Emoji-Ersatzdarstellung und keine externe Icon-Bibliothek. */
.icon-arrow{position:relative;display:inline-block;width:.88em;height:.88em;margin-left:.5em;vertical-align:-.08em}
.icon-arrow::before{content:"";position:absolute;top:50%;left:0;width:100%;height:1.5px;background:currentColor}
.icon-arrow::after{content:"";position:absolute;top:calc(50% - .22em);right:0;width:.44em;height:.44em;border-top:1.5px solid currentColor;border-right:1.5px solid currentColor;transform:rotate(45deg)}
.icon-arrow--up{transform:rotate(-45deg)}
.reviews__head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;gap:12px;padding:30px 0 40px}
.reviews__head p{margin:0;font-size:var(--t-klein);color:rgba(43,48,31,.7)}
.reviews__head strong{color:var(--ink)}
.reviews__grid{display:grid;grid-template-columns:repeat(4,1fr);padding-top:22px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.reviews__grid article{border-right:1px solid var(--line)}
/* Die ganze Karte ist der Link, nicht nur der Name — eine Rezension liest man am
   Stueck, und ein Klickziel von der Groesse einer Zeile ist auf dem Handy eine
   Zumutung. Das Polster sitzt deshalb am Link und nicht mehr am <article>,
   sonst waere der Rand der Karte tote Flaeche. */
/* Spalte mit Fussleiste: die Rezensionen sind unterschiedlich lang, ohne das
   stuende der Name mal hoch, mal tief. Mit margin-top:auto auf .reviews__who
   liegen alle vier Namenszeilen auf einer Linie — echte Rezensionen sind nun
   einmal nicht gleich lang, erfundene waren es. */
.reviews__link{display:flex;flex-direction:column;height:100%;padding:22px clamp(16px,2vw,34px) 24px;color:inherit;text-decoration:none;transition:background .3s ease}
.reviews__link .reviews__who{margin-top:auto;padding-top:14px}
.reviews__grid article:first-child .reviews__link{padding-left:0}
.reviews__grid article:last-child .reviews__link{padding-right:0}
.reviews__grid article:last-child{border-right:0}
.reviews__link:hover{background:rgba(43,48,31,.045)}
.reviews__link:hover .reviews__who strong{color:var(--accent)}
.reviews__link:hover .reviews__who b{transform:translate(2px,-2px)}
.reviews__who b{display:inline-block;font-weight:inherit;transition:transform .3s cubic-bezier(.2,.7,.2,1)}
.reviews__head a{color:var(--accent)}
.reviews__stars{margin:0;color:#f5a623;font-size:var(--t-klein);letter-spacing:2px}
.reviews__text{margin:11px 0 0;color:rgba(43,48,31,.82)}
.reviews__who{margin:14px 0 0;font-size:var(--t-klein);line-height:1.45}
.reviews__who strong{display:block;color:var(--ink)}
.reviews__who span{color:rgba(43,48,31,.55)}
@media(max-width:820px){
  .reviews__grid{grid-template-columns:1fr}
  .reviews__grid article,.reviews__grid article:first-child,.reviews__grid article:last-child{
    border-right:0;border-bottom:1px solid var(--line)}
  .reviews__grid article:last-child{border-bottom:0}
  .reviews__link,.reviews__grid article:first-child .reviews__link,.reviews__grid article:last-child .reviews__link{padding:20px 0}
}
#map-retry{margin-left:8px;padding:5px 12px;border:1px solid currentColor;background:transparent;color:inherit;cursor:pointer}

/* ===================== Für wen wir arbeiten =====================
   Bewusst kein drittes Band im gleichen Muster wie die 3 Blöcke und die Bewertungen —
   drei identische Streifen hintereinander lesen sich als Stapel. Deshalb eine einzelne
   Zeile: Einleitung links, vier Zielgruppen rechts, leicht getönter Grund als Absetzung.
   Die Sektion beantwortet die Frage, die ein Besucher in den ersten Sekunden hat:
   "Bin ich damit gemeint?" — für Hausverwaltungen und Privatleute gleichzeitig. */
/* Die einzige grosse Flaeche in der Markenfarbe. Zielgruppen und Partner sitzen
   bewusst im selben Block: die Liste behauptet, fuer wen gearbeitet wird, die
   Logos belegen es. Deshalb kein Abstand dazwischen, nur eine Trennlinie. */
.audience{position:relative;isolation:isolate;overflow:hidden;color:#fff;background:var(--olive)}
.audience::before{content:"";position:absolute;z-index:-1;inset:0;background:url("assets/hex.svg") repeat;opacity:.16;pointer-events:none}
.audience__inner{width:100%;padding:clamp(26px,3vw,42px) var(--pad)}
.audience__lead{margin:0 0 clamp(12px,1.4vw,20px);color:rgba(255,255,255,.72);text-align:center}
/* Auf __inner eingegrenzt: als ".audience ul" traf die Regel auch die Partner-
   liste im selben Abschnitt und machte aus der Laufband-Reihe ein Vierer-Raster. */
.audience__row{display:grid;width:100%;grid-template-columns:repeat(5,auto);justify-content:space-between;gap:clamp(14px,2vw,34px);margin:0;padding:0;list-style:none}
.audience__track>.audience__row~.audience__row{display:none}
.audience__inner li{display:grid;gap:3px;text-align:center}
/* Titel einzeilig; die Spalten richten sich nach ihnen, der Rest wird verteilt. */
.audience__inner strong{font:500 var(--h3)/1.1 var(--schrift-titel);letter-spacing:.01em;text-transform:uppercase;white-space:nowrap}
/* Knapp ueber dem Handy-Umbruch (821–900px) reicht --h3 (min. 21px) nicht fuer
   fuenf Titel nebeneinander: dort mit der Breite leicht verkleinern. */
@media(min-width:821px){.audience__inner strong{font-size:min(var(--h3),2.35vw)}}
/* Voll deckendes Weiss statt 80 %: auf dem Markenoliv liegt der Kontrast bei
   4,1:1, angehobenes Weiss holt davon jeden Punkt mit. Wer die 4,5:1 der
   WCAG-Stufe AA braucht, setzt --olive im :root auf #5f6146 — dieselbe
   Farbfamilie, nur dunkler, dann sind es 6,4:1. */
.audience__inner span{font-size:var(--t-klein);line-height:1.45;color:#fff}
.section-breath{height:clamp(8px,1vw,14px);background:rgba(248,246,239,.72)}

/* Laufband. Die Spur besteht aus zwei gleichen Haelften, deshalb faellt der
   Ruecksprung bei -50 % auf ein Bild, das ohnehin schon dasteht. Wie viele
   Reihen eine Haelfte braucht, entscheidet app.js anhand der Fensterbreite —
   eine Haelfte muss das Fenster allein fuellen koennen. Dauer setzt app.js
   ebenfalls, damit das Tempo nicht mit der Spurlaenge waechst; der Wert hier
   ist nur der Startwert, bevor das Skript laeuft. */
/* Sitzt direkt unter dem Hero — die klassische Vertrauensleiste. Traegt ihren
   Grund jetzt selbst, weil sie ihn nicht mehr von .audience erbt. z-index wie
   .care-rhythm, damit sie ueber dem auslaufenden Verlauf des Heros liegt. */
/* Schmaler Streifen unter den Vorteilen, in der Hoehe an das Band
   "Wir arbeiten fuer" angeglichen — gleiches Polster oben wie unten. */
.partners{position:relative;z-index:4;isolation:isolate;overflow:hidden;padding:clamp(26px,3vw,42px) 0;color:#fff;background:var(--olive)}
.partners::before{content:"";position:absolute;z-index:-1;inset:0;background:url("assets/hex.svg") repeat;opacity:.16;pointer-events:none}
.partners__lead{margin:0 0 clamp(12px,1.4vw,20px);color:rgba(255,255,255,.6);text-align:center}
.partners__viewport{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.partners__track{display:flex;width:max-content;animation:partners-ticker 46s linear infinite}

.partners__row{display:flex;align-items:center;gap:clamp(38px,5vw,86px);margin:0;padding:0 clamp(19px,2.5vw,43px);list-style:none}
.partners__row li{display:flex;align-items:center;gap:11px;color:#fff;font:500 var(--h3)/1 var(--schrift-titel);letter-spacing:.07em;text-transform:uppercase;white-space:nowrap}
.partners__row svg{width:24px;height:24px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;opacity:.75}
@keyframes partners-ticker{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.partners__track{animation:none}.partners__viewport{overflow-x:auto}}

@media(max-width:820px){
  .audience__inner{padding:26px 0}
  .audience__viewport{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
  .audience__track{display:flex;width:max-content;animation:audience-ticker 38s linear infinite}
  .audience__row,.audience__track>.audience__row~.audience__row{display:flex;width:max-content;flex:none;gap:34px;padding:0 17px}
  .audience__row li{display:flex;align-items:baseline;gap:8px;white-space:nowrap}
  .partners__row{gap:34px;padding:0 17px}
}
@keyframes audience-ticker{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.audience__track{animation:none}.audience__viewport{overflow-x:auto}}

/* ===================== Referenzen: Bewegtbild hinter Milchglas =====================
   Das GIF ist nur 480x270 — auf Vollbild gezogen waere es sichtbar unscharf. Genau das
   wird hier zum Mittel: eine kraeftige Weichzeichnung nimmt die Aufloesung als Thema raus
   und laesst die fallenden Halme als Bewegung stehen. Darueber eine Milchglasscheibe
   (halbtransparent + backdrop-filter), die den Kontrast fuer die weisse Schrift liefert.
   ponytail: bewusst im Browser gerechnet — laut Jannis spaeter durch ein lokal
   gerendertes Video ersetzt, dann fallen Blur-Kosten und 4,2 MB GIF gemeinsam weg. */
/* background-attachment:fixed, damit "cover" gegen den Bildschirm rechnet und nicht
   gegen die rund 2000 px hohe Sektion. Sonst wird das 480x270-GIF 7,5-fach vergroessert
   statt 3,3-fach — das war der Uebermassige Zoom. */
/* Standbild liegt IMMER darunter. Spielt der Browser das Video nicht ab — iOS-Strom-
   sparmodus pausiert automatisch startende Videos — bleibt einfach das Standbild stehen
   statt einer schwarzen Flaeche. Dafuer braucht es kein JavaScript. */
/* Bewegtbild-Hintergrund entfallen (15.08.2026): das animierte Gras passte nicht
   mehr zum ruhigeren Bildstil. Damit sind .proof-bg, .proof-bg__video, die
   Verlaufsschicht darueber und deren Sonderfaelle gegenstandslos und geloescht.
   Der Abschnitt steht jetzt auf einem ruhigen dunklen Grund. */
.proof-cases{position:relative}
.proof-case__copy{padding:clamp(20px,2.2vw,32px);color:var(--ink);background:var(--paper);
  box-shadow:0 18px 50px rgba(14,17,9,.34)}


/* Markenzeile ueber "Das sind wir." — dieselbe Sperrung wie im Kopf, damit die
   beiden als eine Marke gelesen werden. multiply, weil der Logoanschnitt hell
   ist und auf Papier sonst verwaschen wirkt. */
/* Zeitstrahl ueber die volle Breite unter Foto und Text.
   Schmal (Handy): senkrecht, Jahr | Punkt | Text, Linie exakt mittig.
   Ab 700px Rahmenbreite: echte Zeitachse 2016 -> heute. Jede Station liegt nach
   --pos (Anteil der Zeit, siehe index.html) auf der Achse, Beschriftung
   abwechselnd oben und unten, Jahresstriche als Skala, Pfeil bei "heute".
   Animation: app.js setzt .ist-animiert (Ausgangslage) und beim Hineinscrollen
   .ist-sichtbar. Die Linie zeichnet sich in --dauer linear von links nach rechts,
   jede Station erscheint genau dann, wenn die Linie sie erreicht
   (Verzoegerung = --pos x --dauer). Ohne JS oder bei reduzierter Bewegung steht
   alles sofort da. */
.zeitstrahl-rahmen{--dauer:2.2s;--rand:clamp(50px,6cqw,90px);position:relative;container-type:inline-size;width:100%;grid-column:1/-1;margin:0 0 clamp(16px,3vw,40px)}
.zeitstrahl{display:grid;max-width:460px;margin:0 auto;padding:0;list-style:none}
.zeitstrahl li{display:grid;grid-template-columns:1fr 14px 1fr;column-gap:18px;align-items:center;min-height:54px;transform:translateY(var(--y,0))}
.zeitstrahl li::before,.zeitstrahl li::after{content:"";grid-column:2;grid-row:1;justify-self:center}
.zeitstrahl li::before{z-index:1;box-sizing:border-box;width:14px;height:14px;border:3px solid var(--accent);border-radius:50%;background:#f8f6ef}
.zeitstrahl li::after{align-self:stretch;width:2px;background:rgba(43,48,31,.22);transform-origin:top}
.zeitstrahl li:first-child::after{align-self:end;height:50%}
.zeitstrahl li:last-child::after{align-self:start;height:50%}
.zeitstrahl time{grid-column:1;grid-row:1;text-align:right;color:var(--ink);font:500 24px/1 var(--schrift-titel)}
.zeitstrahl span{grid-column:3;grid-row:1;color:rgba(43,48,31,.8);font-size:14px;line-height:1.3}
.zeitstrahl__heute{display:none}

@container (min-width:700px){
  .zeitstrahl{position:relative;display:block;max-width:none;height:260px;margin:0 var(--rand);
    background:repeating-linear-gradient(90deg,rgba(43,48,31,.3) 0 1px,transparent 1px 10%) 0 50%/100% 12px no-repeat}
  .zeitstrahl::before,.zeitstrahl::after{content:"";position:absolute;top:calc(50% - 1px);left:0;right:0;height:2px}
  .zeitstrahl::before{background:rgba(43,48,31,.2)}
  .zeitstrahl::after{background:var(--accent);transform-origin:left}
  .zeitstrahl li{--abstand:30px;position:absolute;z-index:1;left:calc(var(--pos) * 100%);display:flex;flex-direction:column;align-items:center;gap:6px;width:max-content;max-width:7.5em;min-height:0;font-size:15px;text-align:center;transform:translate(-50%,var(--y,0))}
  .zeitstrahl li:nth-child(odd){bottom:calc(50% + var(--abstand));flex-direction:column-reverse}
  .zeitstrahl li:nth-child(even){top:calc(50% + var(--abstand))}
  .zeitstrahl li::before{position:absolute;left:50%;width:16px;height:16px;margin-left:-8px}
  .zeitstrahl li:nth-child(odd)::before{top:calc(100% + var(--abstand) - 8px)}
  .zeitstrahl li:nth-child(even)::before{bottom:calc(100% + var(--abstand) - 8px)}
  .zeitstrahl li::after,.zeitstrahl li:first-child::after,.zeitstrahl li:last-child::after{position:absolute;left:50%;width:1px;height:calc(var(--abstand) - 12px);margin-left:-.5px;background:rgba(43,48,31,.35)}
  .zeitstrahl li:nth-child(odd)::after{top:calc(100% + 3px);transform-origin:bottom}
  .zeitstrahl li:nth-child(even)::after{bottom:calc(100% + 3px)}
  .zeitstrahl time{font-size:clamp(26px,3cqw,36px);text-align:center}
  .zeitstrahl span{font-size:inherit;text-align:center}
  .zeitstrahl__heute{display:block;position:absolute;top:50%;left:calc(100% - var(--rand));transform:translate(-50%,18px);color:var(--accent);font:700 11px/1 var(--schrift-text);letter-spacing:.14em;text-transform:uppercase}
  .zeitstrahl__heute::before{content:"";position:absolute;top:-18px;left:50%;margin-top:-6px;border:6px solid transparent;border-right:0;border-left:11px solid var(--accent)}
}

@media(prefers-reduced-motion:no-preference){
  .ist-animiert .zeitstrahl::after{transform:scaleX(0)}
  .ist-animiert .zeitstrahl li{--y:12px;opacity:0;transition:opacity .5s ease,transform .7s cubic-bezier(.2,.8,.2,1)}
  .ist-animiert .zeitstrahl li::before{transform:scale(0);transition:transform .45s cubic-bezier(.3,1.6,.5,1)}
  .ist-animiert .zeitstrahl li::after{transform:scaleY(0);transition:transform .35s ease-out}
  .ist-animiert .zeitstrahl__heute{opacity:0;transition:opacity .5s ease}
  .ist-sichtbar .zeitstrahl::after{transform:none;transition:transform var(--dauer) linear}
  .ist-sichtbar .zeitstrahl li{--y:0px;opacity:1;transition-delay:calc(var(--pos) * var(--dauer))}
  .ist-sichtbar .zeitstrahl li::before,.ist-sichtbar .zeitstrahl li::after{transform:none;transition-delay:calc(var(--pos) * var(--dauer))}
  .ist-sichtbar .zeitstrahl__heute{opacity:1;transition-delay:var(--dauer)}
}
@container (min-width:700px){
  .ist-animiert .zeitstrahl li:nth-child(even){--y:-12px}
  .ist-sichtbar .zeitstrahl li:nth-child(even){--y:0px}
}

/* Nur fuer ?marken-editor: ein lokaler Abnahmehelfer, kein Bestandteil der
   Kundenseite. Die Werte werden als Prozent des Bildrahmens ausgegeben. */
.hero-mark-editor{position:fixed;z-index:2000;bottom:18px;left:18px;width:min(360px,calc(100vw - 36px));padding:16px;border:1px solid var(--line);color:var(--ink);background:var(--paper);box-shadow:0 20px 55px rgba(26,30,18,.22)}
.hero-mark-editor p{margin:0 0 10px;font-size:var(--t-klein);line-height:1.4}.hero-mark-editor textarea{display:block;width:100%;min-height:132px;margin:0 0 10px;padding:9px;border:1px solid var(--line);resize:vertical;color:var(--ink);background:#fff;font:12px/1.45 ui-monospace,SFMono-Regular,monospace}.hero-mark-editor button{padding:9px 12px;border:1px solid var(--ink);color:#fff;background:var(--ink);cursor:pointer}.hero-mark.is-editing{cursor:grab}.hero-mark.is-editing:active{cursor:grabbing}
.trust-brand{display:flex;align-items:center;gap:14px;margin:0 0 clamp(14px,1.4vw,22px)}
.trust-brand img{width:clamp(68px,5vw,82px);height:auto;aspect-ratio:1;object-fit:contain;mix-blend-mode:multiply;filter:saturate(1.55) brightness(.72);opacity:1}
.trust-brand span{color:rgba(43,48,31,.62);font-size:clamp(1.08rem,1.35vw,1.35rem);font-weight:700;letter-spacing:.01em}
.trust-years{margin-top:-12px!important;color:var(--ink)!important}
.trust-years strong{font-weight:800}


/* Referenzobjekte. Das Bild laeuft ueber die volle Breite und ist die Aussage;
   der Text steht klein darunter und erklaert nur nach. Deshalb hat die Sektion
   selbst kein seitliches Polster — das tragen Kopf und Textspalte einzeln, damit
   sie in derselben Flucht stehen wie der Rest der Seite. */
/* Die Einleitung bleibt vollstaendig auf der hellen Flaeche; das Bild beginnt
   erst danach, damit die neue zweizeilige Ueberschrift nicht hineinragt. */
.objects{padding:clamp(72px,7vw,108px) 0 clamp(60px,7vw,110px);background:var(--flaeche)}
.objects__head{position:relative;z-index:2;max-width:1540px;margin:0 auto clamp(14px,1.8vw,28px);padding:0 var(--pad);text-align:center}
/* Ohne festen Zeilenumbruch im Markup: die Ueberschrift laeuft in einer Zeile
   ueber die Breite und bricht auf schmalen Fenstern von selbst um.
   Die Obergrenze richtet sich nicht nach dem Fenster, sondern nach dem auf
   1540 px gedeckelten Kopf: bei 145 px passte die Zeile dort nicht mehr und
   brach auf breiten Bildschirmen zweizeilig um. */
.objects__head h2{margin:0;font:500 var(--h1)/.92 var(--schrift-titel);letter-spacing:-.035em;text-transform:uppercase;text-wrap:balance}
.objects__head p{max-width:56ch;margin:22px auto 0;font-size:var(--t-lead);color:rgba(43,48,31,.72)}
.object{margin-bottom:clamp(64px,7.5vw,120px)}
.object:last-child{margin-bottom:0}
/* Das Bild ist absichtlich hoeher als sein Rahmen: der Ueberstand ist der Weg,
   den es beim Scrollen zuruecklegt. 146 % Hoehe bei -23 % Versatz heisst 23 %
   Reserve nach oben und unten — knapp das Dreifache des vorherigen Wegs.
   app.js liest den Ueberstand aus dem Layout aus, statt ihn zu kennen: wer hier
   die Prozente aendert, aendert damit automatisch auch den Ausschlag. */
.object__media{position:relative;height:min(86svh,900px);margin:0;overflow:hidden;background:var(--paper-2)}
.object__media>img{position:absolute;top:-23%;left:0;width:100%;height:146%;object-fit:cover;will-change:transform}
.object__copy{position:absolute;z-index:3;left:var(--pad);bottom:clamp(24px,3.4vw,52px);display:grid;
  grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:clamp(20px,2.8vw,52px);width:min(760px,calc(100% - var(--pad)*2));
  margin:0;padding:clamp(22px,2.2vw,34px);color:var(--ink);background:rgba(247,244,234,.9);
  border:1px solid rgba(255,255,255,.42);border-radius:clamp(16px,1.6vw,26px);box-shadow:0 20px 55px rgba(10,22,14,.2);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}
.object__copy--right{right:var(--pad);left:auto}

/* ---- Buehne: klebendes Fenster mit Lamellenwechsel ----
   Nach dem Codrops-Vorbild "SVG Mask Transitions on Scroll" (Hiroki Watanabe,
   MIT), Variante 01 Horizontal Blinds. Uebernommen ist die Mechanik: 30 Lamellen,
   je zwei Rechtecke, die aus der Lamellenmitte nach oben und unten aufwachsen,
   gestaffelt von unten nach oben. Bildwelt, Timing und Textfuehrung sind eigene.

   Das Kleben macht CSS, nicht ScrollTrigger: position:sticky braucht kein Pinning,
   keinen Platzhalter und keinen Wiedereinstieg. Genau deren Ein- und Austritt war
   der Bruch, den Jannis an der Leistungs-Kamerafahrt weghaben wollte.

   Alle Regeln haengen an .objects--buehne. Die Klasse setzt app.js nur, wenn der
   Effekt wirklich laeuft — ohne JavaScript, bei reduzierter Bewegung und auf dem
   Handy bleibt der gestapelte Aufbau von oben stehen. */
/* Kein klebender Abschnitt mehr: gewechselt wird ueber die Marken, nicht ueber
   den Scrollweg. Der Abschnitt ist damit einen Bildschirm hoch statt 420 svh —
   grosse Bilder bleiben, die vier Bildschirme Scrollzwang entfallen. */
.objects--buehne{--spalte-h:min(58svh,520px);--leiste-h:clamp(52px,4.5vw,66px);--leiste-inset:22px;--objekt-flaeche:rgba(248,246,239,.86);--objekt-radius:clamp(12px,1vw,18px);padding-bottom:0}
.objects--buehne .objects__viewport{position:relative;height:100svh;overflow:hidden}
.objects--buehne .object{position:absolute;inset:0;margin:0}
/* Ohne background waere jede gestapelte Figur ein deckender Kasten: das
   oberste Objekt haette alle darunter verdeckt, und weil sein Bild noch
   weggeschnitten ist, blieb nur eine leere Flaeche stehen. Im Stapel traegt
   die Sektion den Hintergrund, nicht die einzelne Figur. */
.objects--buehne .object__media{height:100%;background:none}
/* Kein Ueberstand mehr: im klebenden Fenster gibt es keine Parallaxe, das Bild
   fuellt den Rahmen. Damit ist auch die alte Kopplung an die 146 % erledigt. */
.objects--buehne .object__media>img{top:0;height:100%}

/* Eckige Hochkantspalte statt breitem Kasten unten, abwechselnd links und
   rechts. justify-content verteilt Ort/Name oben und Text/Leistungen unten, das
   traegt die Hochkantform ohne feste Innenabstaende. */
/* Die Spalte steht ueber ihrem eigenen Fach: --spalte-x kommt aus app.js und ist
   der linke Rand des Fachs in Prozent. Das min() haelt die letzte Spalte im Bild.
   Damit entfaellt der Wechsel zwischen links und rechts — die Lage sagt jetzt
   etwas aus, statt nur abzuwechseln. */
.objects--buehne .object__copy{
  /* Breite = Fachbreite, damit Spalte und Fach wirklich uebereinander stehen.
     --spalte-b kommt aus app.js als 100 % / Anzahl. Die Untergrenze faengt
     schmale Fenster ab: bei vier Faechern auf 1024 px waeren es 256 px, und
     darunter wird der Absatz zur Schlucht. */
  --breite:max(280px,var(--spalte-b,25%));
  top:auto;bottom:calc(var(--leiste-h) + var(--leiste-inset));right:auto;transform:none;
  left:min(var(--spalte-x,0%),calc(100% - var(--breite)));
  display:flex;flex-direction:column;justify-content:space-between;
  z-index:51;gap:clamp(20px,2.4vw,40px);width:var(--breite);min-height:var(--spalte-h);
  padding:clamp(24px,2vw,38px);border:0;border-radius:var(--objekt-radius) var(--objekt-radius) 0 0;background:var(--objekt-flaeche);
  box-shadow:none;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}

/* Eigenstaendige Uebergangsformen: Sie liegen ZUSAETZLICH neben der Karte,
   veraendern also keine einzige Bannerkante. Das Quadrat wird nur an seiner
   oberen inneren Ecke gerundet; genau diese Kurve laeuft von der senkrechten
   Kartenflanke weich in die Buttonleiste. */
.objects--buehne .object__corner{position:absolute;z-index:2;bottom:calc(-1 * var(--objekt-radius));display:block;width:var(--objekt-radius);height:var(--objekt-radius);background:var(--objekt-flaeche);pointer-events:none;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.objects--buehne .object__corner--left{left:calc(-1 * var(--objekt-radius));border-top-right-radius:var(--objekt-radius)}
.objects--buehne .object__corner--right{right:calc(-1 * var(--objekt-radius));border-top-left-radius:var(--objekt-radius)}
/* Nur die frei liegenden unteren Ecken der beiden Aussenkarten bleiben rund. */
.objects--buehne .object:first-child .object__copy{border-bottom-left-radius:var(--objekt-radius)}
.objects--buehne .object:last-child .object__copy{border-bottom-right-radius:var(--objekt-radius)}
/* Ist die linke Aussenkarte selbst offen, geht ihre linke Unterkante ohne
   Gegenkurve direkt in die Leiste. Bei jedem anderen aktiven Objekt greift
   wieder die Regel darueber und die Rundung ist sichtbar. */
.objects--buehne .object:first-child.is-active-object .object__copy{border-bottom-left-radius:0}

/* ---- Leiste an der Bildunterkante ----
   Die Schalter nehmen die volle Breite ein und sind nur durch Haarlinien
   getrennt. Der aktive verliert Flaeche UND Beschriftung: sein Name ist nach
   oben in die Spalte gewandert, das Fach darunter steht offen und zeigt den
   unteren Streifen des Bildes. Damit gibt es dort keinen Text mehr, der auf
   einem Foto lesbar bleiben muesste — das Kontrastproblem entfaellt, statt
   geloest zu werden. */
.objects--buehne .objects__leiste{position:absolute;z-index:50;bottom:var(--leiste-inset);left:50%;width:min(78vw,1120px);height:var(--leiste-h);
  display:flex;overflow:hidden;border-radius:var(--objekt-radius);transform:translateX(-50%);transition:border-radius .3s ease}
/* Bei einer geoeffneten Aussenkarte ist nur ihre obere Aussenkante gerade:
   Karte und Leiste sitzen dort wie ein gemeinsames Material. Unten bleibt die
   Rundung am Rand der gesamten Buttonleiste sichtbar. */
.objects--buehne .objects__leiste.is-first-active{border-top-left-radius:0}
.objects--buehne .objects__leiste.is-last-active{border-top-right-radius:0}
.objects--buehne .objects__leiste button{display:grid;place-items:center;padding:0 10px;color:var(--ink);
  background:var(--objekt-flaeche);border:0;border-left:1px solid rgba(43,48,31,.16);cursor:pointer;
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  flex:1;font-size:clamp(10px,min(.85vw,1.6svh),14px);line-height:1.15;letter-spacing:.1em;text-wrap:balance;
  transition:flex .42s cubic-bezier(.2,.7,.2,1),background .55s ease,color .35s ease}
.objects--buehne .objects__leiste button:first-child{border-left:0}
.objects--buehne .objects__leiste button:hover{background:var(--objekt-flaeche)}
.objects--buehne .objects__leiste button.is-active{flex:1.8;color:transparent;background:var(--objekt-flaeche);cursor:default}
/* Die Rundung sitzt an der offenen Karte selbst. Die Leiste darunter bleibt
   als ruhige, durchgehende Flaeche erhalten und erzeugt keine Gegenkurve. */

/* Pfeile: eckig wie die Spalte, nicht rund. Sie springen umlaufend — vom ersten
   Objekt nach links landet man beim letzten. So bewegt sich bei jedem Klick
   etwas, und keine der beiden Tasten ist je wirkungslos. */
/* Unter der Spalte, nicht auf halber Hoehe: die Spalte steht jetzt ueber ihrem
   eigenen Fach und kann damit ganz links sitzen — dort lag der linke Pfeil
   vorher mitten im Text. Der Versatz rechnet sich aus derselben Hoehe, die die
   Spalte benutzt, die beiden koennen also nicht auseinander laufen. */
.objects--buehne .objects__pfeil{position:absolute;z-index:50;
  /* Echte vertikale Bildmitte: die Karte bleibt zwischen den beiden seitlichen
     Steuerungen, statt dass die Pfeile nur im freien Raum oberhalb stehen. */
  top:50%;transform:translateY(-50%);
  bottom:auto;
  display:grid;place-items:center;width:clamp(46px,3.4vw,58px);aspect-ratio:1;padding:0;
  color:var(--ink);background:rgba(248,246,239,.9);border:1px solid rgba(43,48,31,.16);cursor:pointer;
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);transition:background .3s ease}
.objects--buehne .objects__pfeil:hover{background:#fff}
.objects--buehne .objects__pfeil svg{width:42%;fill:none;stroke:currentColor;stroke-width:2}
.objects--buehne .objects__pfeil--links{left:clamp(22px,3vw,58px)}
.objects--buehne .objects__pfeil--rechts{right:clamp(22px,3vw,58px)}
.objects--buehne .objects__pfeil{border-radius:var(--objekt-radius)}

.object__place{margin:0 0 9px;color:var(--accent)}
.object__copy>div{min-width:0}
.object__copy h3{max-width:100%;margin:0;font:500 var(--h2)/.95 var(--schrift-titel);letter-spacing:-.02em;
  text-transform:uppercase;text-wrap:balance;hyphens:auto;overflow-wrap:break-word}
.objects--buehne .object__copy h3{font-size:clamp(28px,min(3.3vw,7svh),54px)}
.object__copy p:not(.object__place){margin:0;max-width:52ch;line-height:1.6;color:rgba(43,48,31,.8)}
.object__scope{display:flex;flex-wrap:wrap;gap:8px 22px;margin:18px 0 0;padding:0;list-style:none}
.object__scope li{color:rgba(43,48,31,.55)}
.object__scope li::before{content:"";display:inline-block;width:4px;height:4px;margin:0 8px 2px 0;border-radius:50%;background:var(--accent)}
@media(max-width:820px){
  .objects{padding:70px 0 50px}
  .object__media{height:min(58svh,520px)}
  /* Auf dem Handy ist der Rahmen schmal und hoch — bei 146 % bliebe vom Motiv
     seitlich fast nichts uebrig. Weniger Ueberstand, und app.js drosselt den
     Ausschlag dadurch von selbst mit. */
  .object__media>img{top:-13%;height:126%}
  .object__copy,.object__copy--right{right:18px;bottom:18px;left:18px;grid-template-columns:1fr;gap:12px;width:auto;padding:18px}
  .object__copy p:not(.object__place){display:none}
}

/* ---- Ablauf + Kontakt: ein Abschnitt mit einer Linie als Rueckgrat ---- */
.ablauf{position:relative;isolation:isolate;--spur:clamp(26px,3vw,52px);background:var(--olive)}
.ablauf::before{content:"";position:absolute;z-index:0;inset:0;background:url("assets/hex.svg") repeat fixed;opacity:.09;pointer-events:none}
/* Heller Auftakt ueber der Farbkante. Er traegt die Ueberschrift und laesst der
   Linie darunter noch Platz, damit sie den Wechsel nach Dunkel ueberquert — ein
   durchgehendes Element macht die Kante unsichtbar. */
/* Kein Farbverlauf: Ueber dem hellen Auftakt liegen die echte Olivflaeche und
   das identische Wabenmuster des Kontaktblocks. Nur ihre Sichtbarkeit wird an
   der Kante maskiert, bis beide Ebenen unten exakt ineinander uebergehen. */
.ablauf__auftakt{position:relative;z-index:1;isolation:isolate;overflow:hidden;padding:clamp(66px,7vw,118px) var(--pad) clamp(132px,14vw,230px);background:linear-gradient(to bottom,var(--paper) 0%,color-mix(in srgb,var(--paper) 68%,var(--olive)) 54%,var(--olive) 100%);text-align:center}
.ablauf__auftakt::after{content:"";position:absolute;z-index:0;inset:0;background:url("assets/hex.svg") repeat fixed;opacity:.09;pointer-events:none;-webkit-mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.28) 38%,#000 100%);mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.28) 38%,#000 100%)}
/* Wortweise maskiert: jedes Wort sitzt in einem eigenen Kasten mit
   overflow:hidden, damit es beim Einschwingen hinter einer Kante hervorkommt
   statt aus dem Nichts zu erscheinen. Die Kaesten baut app.js. */
.ablauf__titel{position:relative;z-index:2;margin:0 auto;color:var(--ink);font-family:var(--schrift-titel);font-weight:500;text-transform:uppercase;text-wrap:balance}
.ablauf__titel-klein,.ablauf__titel-gross{display:block}
.ablauf__titel-klein{margin-bottom:.18em;font-size:var(--h3);line-height:1;letter-spacing:.05em}
.ablauf__titel-gross{font-size:var(--h1);line-height:.9;letter-spacing:-.025em}
.ablauf__block{position:relative;z-index:1;overflow:hidden;padding:clamp(76px,8vw,138px) 0 clamp(80px,9vw,140px);color:#fff}
.ablauf__inner{position:relative;z-index:2;max-width:1540px;margin:0 auto;padding:0 var(--pad)}

/* Hoehe setzt app.js: die Linie endet am letzten Punkt, nicht am Abschnittsende.
   Ausserdem naehme ein SVG mit top und bottom sonst seine eigene Hoehe aus dem
   viewBox statt der des Kastens — gemessen fehlten 334 px. */
.ablauf__linie{position:absolute;z-index:3;top:0;left:50%;width:2px;height:100%;margin-left:-1px}
.ablauf__linie path{fill:none;stroke-width:2;vector-effect:non-scaling-stroke}
.ablauf__linie-grund{stroke:rgba(255,255,255,.16)}
.ablauf__linie-zug{stroke:var(--accent)}

/* Zwei gleich breite Spalten ohne Luecke: die Spaltenkante liegt damit exakt auf
   der Linie, und die Punkte sitzen an der Innenkante der jeweiligen Spalte.
   grid-row ist ausgeschrieben, sonst packt die automatische Platzierung Station
   zwei neben Station eins in dieselbe Zeile. */
.ablauf__steps{display:grid;grid-template-columns:1fr 1fr;column-gap:0;margin:0;padding:0;list-style:none}
.ablauf__step{position:relative}
.ablauf__steps .ablauf__step{padding-bottom:clamp(48px,5.5vw,92px)}
.ablauf__steps .ablauf__step:nth-child(1){grid-row:1;grid-column:1}
.ablauf__steps .ablauf__step:nth-child(2){grid-row:2;grid-column:2}
.ablauf__steps .ablauf__step:nth-child(3){grid-row:3;grid-column:1}
.ablauf__steps .ablauf__step:nth-child(odd){padding-right:var(--spur);text-align:right}
.ablauf__steps .ablauf__step:nth-child(even){padding-left:var(--spur);text-align:left}
.ablauf__steps .ablauf__step:nth-child(odd) p{margin-left:auto}

/* Der Punkt sitzt mittig auf der 2 px breiten Linie. box-sizing muss hier stehen:
   der Reset oben ist "* { box-sizing:border-box }" und erfasst Pseudoelemente
   NICHT. Ohne das ist der Punkt 12 px Inhalt plus 2 px Rand je Seite, also 16 px
   breit — und der Versatz von -6 px setzt ihn 4 px neben die Linie. */
.ablauf__step::before{content:"";box-sizing:border-box;position:absolute;z-index:4;top:calc(.62em - 6px);width:12px;height:12px;border:2px solid var(--paper);border-radius:50%;background:rgba(255,255,255,.3);transition:background .3s ease,transform .3s ease}
.ablauf__steps .ablauf__step:nth-child(odd)::before{right:-6px}
.ablauf__steps .ablauf__step:nth-child(even)::before{left:-6px}
.ablauf__step.ist-erreicht::before{background:var(--accent);transform:scale(1.25)}
.ablauf__step h3{margin:0;font:500 var(--h3)/1.06 var(--schrift-titel);letter-spacing:.005em;text-transform:uppercase}
.ablauf__step p{max-width:40ch;margin:11px 0 0;color:rgba(255,255,255,.74);line-height:1.6}

/* Letzte Station: mittig unter dem Punkt statt links oder rechts. Die Kreise
   liegen hier und nicht mehr im ganzen Block — dadurch sitzen sie tief und genau
   um den Aufruf herum. */
.ablauf__ziel-feld{position:relative}
.ablauf__ziel{position:relative;z-index:2;display:grid;justify-items:center;padding-top:clamp(46px,4.6vw,82px);text-align:center}
.ablauf__ziel::before{display:none}
.ablauf__ziel-inhalt{position:relative;z-index:4;display:grid;justify-items:center}
.ablauf__ziel-inhalt h2>img{position:relative;z-index:1;display:block;width:74px;height:auto;margin:clamp(18px,2vw,30px) auto;filter:brightness(0) invert(1);opacity:.75}
.ablauf__ziel-inhalt h2{margin:0;max-width:15ch;font:500 var(--h1)/.86 var(--schrift-titel);letter-spacing:-.03em;text-transform:uppercase}
.ablauf__ziel-inhalt h2>span:not(.wort){display:block;margin-top:.42em;color:rgba(255,255,255,.72)}
@media(min-width:821px){.ablauf__ziel-inhalt h2{max-width:none}.ablauf__ziel-inhalt h2>span:not(.wort){white-space:nowrap}}
.contact-actions{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:clamp(34px,3.5vw,56px)}
.contact-action{display:inline-flex;flex:0 1 clamp(220px,18vw,280px);align-items:center;justify-content:center;min-height:54px;padding:15px 21px;border:1px solid rgba(255,255,255,.42);border-radius:999px;color:#fff;text-decoration:none;transition:color .25s ease,background .25s ease,border-color .25s ease,transform .25s ease}
.contact-action:hover{color:var(--ink);background:var(--paper);border-color:var(--paper);transform:translateY(-2px)}
.contact-action--primary{color:#fff;background:var(--accent);border-color:var(--accent)}
.contact-action--primary:hover{color:#fff;background:#a93d11;border-color:#a93d11}

@media(max-width:820px){
  /* Handy/Tablet: die Spur laeuft am linken Rand, die Stationen stehen frei und
     linksbuendig daneben — so kreuzt die Linie nie einen Text, und es braucht
     keine Flaeche hinter der Schrift. Punkt auf Hoehe der ersten Titelzeile.
     Linie: var(--pad) + 6px vom Abschnittsrand = Mitte des 12px-Punkts, der am
     linken Rand der Station sitzt (Station beginnt bei var(--pad)). */
  .ablauf__linie{z-index:1;left:calc(var(--pad) + 6px);margin-left:-1px}
  .ablauf__steps{grid-template-columns:1fr}
  .ablauf__steps .ablauf__step:nth-child(n){grid-row:auto;grid-column:1;padding:0 0 44px 34px;text-align:left}
  .ablauf__steps .ablauf__step:nth-child(n) p{margin-right:0;margin-left:0}
  .ablauf__steps .ablauf__step:nth-child(n)::before{top:calc(var(--h3) * .53 - 6px);right:auto;left:0;margin-left:0}
  .ablauf__ziel{justify-items:start;padding-left:var(--spur);text-align:left}
  .ablauf__ziel::before{left:-6px;margin-left:0}
  .ablauf__ziel-inhalt{justify-items:start}
  .contact-actions{align-items:stretch;justify-content:flex-start;flex-direction:column;width:min(100%,360px);gap:10px}
  .contact-action{width:100%}
}
/* Die Kapitel-Buttons der Leistungsbuehne folgen demselben subtilen Radius. */
.chapter{border-radius:clamp(12px,1vw,18px)}
/* Kartenobjekte: die grosse Flaeche und der Finder bleiben leicht gerundet,
   aber deutlich naeher an einer klaren Ecke. Eingabefelder bleiben bewusst
   pillenfoermig, weil sie als Eingaben sofort erkennbar sein sollen. */
.map-shell{border-radius:clamp(12px,1vw,18px)}
.map-finder{border-radius:12px}
/* Kartenzoom bewusst gut bedienbar, aber nicht dominant. */
.map-shell .leaflet-control-zoom a{width:48px;height:48px;line-height:48px;font-size:25px}
@media(prefers-reduced-motion:reduce){.ablauf__linie-zug{display:none}}

/* Zeiten unter den Kontaktknoepfen. Bewusst in der Textschrift und nicht in den
   Versalien der Knopfreihe: es ist eine Auskunft, keine Handlungsaufforderung. */
.contact-zeiten{max-width:46ch;margin:clamp(16px,1.8vw,26px) 0 0;color:rgba(43,48,31,.62);font-size:var(--t-klein);line-height:1.55}
.contact-zeiten strong{display:block;margin-top:.45em;color:var(--accent);font-weight:700}

/* Handy: .hero-fuss ist dort ausgeblendet, die Aussage fehlte sonst ganz.
   Sitzt vor dem Knopf, weil sie ein Grund zum Anrufen ist und kein Nachsatz. */
.mobile-notdienst{display:flex;align-items:center;gap:8px;margin:0 0 4px;color:rgba(255,255,255,.86);line-height:1.5}
.mobile-notdienst .punkt{width:6px;height:6px;flex:none;border-radius:50%;background:var(--accent)}

/* ===== Karte: Standbild, Startknopf, Blende ===== */

/* Das Standbild liegt im overlayPane ueber den Kacheln. Ausblenden gibt sie frei
   — deshalb eine Blende auf die Deckkraft und sonst nichts. Wuerde man das Bild
   stattdessen wegschieben oder verkleinern, saehe man es wandern. */
.map-vorschau{transition:opacity .55s ease}
.map-vorschau.ist-weg{opacity:0}

/* Solange nur das Standbild da ist: kein Greifcursor, keine Zoomknoepfe. Beides
   verspricht eine Bedienbarkeit, die es in diesem Zustand nicht gibt. */
.map-shell--ruhend .leaflet-container{cursor:default}
.map-shell--ruhend .leaflet-control-zoom{display:none}

.map-start{position:absolute;z-index:620;top:50%;left:50%;display:grid;
  justify-items:center;gap:12px;
  max-width:min(420px,calc(100% - 40px));padding:18px 26px 20px;
  border:1px solid rgba(255,255,255,.5);border-radius:18px;
  color:var(--ink);background:rgba(248,246,239,.94);
  box-shadow:0 18px 55px rgba(18,21,12,.24);backdrop-filter:blur(18px);
  text-align:center;transform:translate(-50%,-50%)}
.map-start__knopf{padding:11px 24px;border:0;border-radius:999px;
  color:#fff;background:var(--ink);cursor:pointer;
  font-size:var(--label);font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  transition:background .2s ease,transform .2s ease}
.map-start__knopf:hover{background:#1d2115;transform:scale(1.03)}
.map-start__knopf:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
/* Der Satz steht unter dem Knopf und nicht daneben: er ist die Bedingung des
   Klicks und muss vor dem Ausloesen gelesen werden koennen. */
.map-start__hinweis{margin:0;color:rgba(43,48,31,.72);font-size:11px;line-height:1.5;text-wrap:balance}
.map-start__hinweis a{color:var(--accent-text);text-underline-offset:2px}

@media(max-width:820px){.map-start{padding:15px 20px 17px}.map-start__hinweis{font-size:10.5px}}



/* ===== Kontrast =====
   Das neue Signalorange #c44814 erreicht auf dem Papier 4,53:1 und mit weisser
   Schrift 4,90:1. Flaechen und Schrift koennen daher denselben Markenton nutzen. */
.hero-cta,.map-finder .map-hinweis a,.map-start__hinweis a,.object__place,
.counter,.section-number,.subpage-kicker,.proof-case__meta,
.reviews__head a,.footer-cols a:hover{color:var(--accent-text)}

/* Auch hier war der Grund kurz dunkler. Zurueckgenommen, gleicher Grund.
   Die Deckkraft der Schrift bleibt oben — sie schadet nicht und hilft ein wenig. */
.audience__lead{color:rgba(255,255,255,.92)}

/* ===== MERKSATZ ZUM OLIV =====
   Auf #7e805d ist WCAG AA fuer kleine Schrift mit keiner hellen Schriftfarbe
   erreichbar. Nachgerechnet:

       reines Weiss   4,09:1     Papier #f8f6ef  3,78:1
       reines Schwarz 5,13:1     Tinte #2b301f   3,32:1

   Der Ton liegt genau in der Mitte der Helligkeitsskala — das ist der
   unguenstigste Fall. Nach oben ist bei 4,09 Schluss, nach unten braucht es
   fast Schwarz (#12140b, 4,54:1), und dunkle Schrift auf Oliv ist ein voellig
   anderes Bild als die weisse.

   Drei Wege, falls es jemals gefordert wird:
     1. Schrift groesser: ab 24 px, oder ab 18,7 px fett, gelten 3:1 —
        weiss reicht dann mit 4,09 bequem.
     2. Kleinschrift auf eine eigene, dunklere Flaeche innerhalb der Sektion
        legen statt direkt auf das Oliv.
     3. Das Oliv minimal abdunkeln. #767755 traegt weisse Kleinschrift mit
        4,63:1 und liegt bei ΔE 3,5 zum Original — nebeneinander gerade eben
        unterscheidbar, einzeln gesehen nicht.
   Alle drei sind Gestaltungsentscheidungen. Keine davon ist getroffen. */

/* Die Rezensionszeile stand bei .55 und damit auf 3,29:1. */
.reviews__who span{color:rgba(43,48,31,.72)}

/* Sprunglink: 79 Elemente sind mit der Tabulatortaste erreichbar. Ohne diesen
   Link muss sich jemand, der die Seite mit der Tastatur bedient, auf jeder
   Seite erst durch die gesamte Navigation arbeiten. Sichtbar wird er nur, wenn
   er den Fokus hat — genau dann, wenn er gebraucht wird. */
.skip-link{position:absolute;z-index:2000;top:8px;left:8px;
  padding:12px 20px;border-radius:999px;
  color:#fff;background:var(--ink);
  font-size:var(--label);font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;text-decoration:none;
  transform:translateY(-160%);transition:transform .18s ease}
.skip-link:focus{transform:none;outline:2px solid var(--accent);outline-offset:3px}

/* Zweiter Durchgang, diesmal an den echten Bildpunkten gemessen statt an den
   CSS-Werten: bei Verlaeufen und halbdurchsichtigen Flaechen sagt die
   Deklaration nicht, was am Ende auf dem Schirm steht. Alle Werte unten sind
   aus Bildschirmfotos von vier Seitenabschnitten gelesen.

   Das Muster ist ueberall dasselbe: weisse Schrift mit 72 bis 74 Prozent
   Deckkraft auf dem Oliv. Auf dunklem Grund traegt das, auf dem mittelhellen
   Oliv nicht mehr. */
/* Hier stand kurz ein dunkleres Oliv. Zurueckgenommen: #7e805d ist die Farbe,
   die der Inhaber ausdruecklich so haben will — sie wird nicht angefasst.
   Der Kontrast auf dieser Flaeche ist damit eine Gestaltungsfrage, keine
   technische; die Zahlen dazu stehen unten im Merksatz. */
.map-gebiet{color:rgba(255,255,255,.92)}                    /* 3,30 -> 4,9:1 */
.ablauf__step p{color:rgba(255,255,255,.9)}                 /* 4,37 -> 5,3:1 */
.hero-zeiten__zusatz{opacity:.8}                         /* 4,28 -> 5,1:1 */

/* Die Ortszeile ueber den Objektnamen steht auf einem hellen Bildausschnitt,
   nicht auf Papier — dort reicht auch der dunklere Akzent nicht. Sie bekommt
   denselben Schutz wie die Ueberschrift daneben. */
.object__place{color:#8f3f1c}   /* auf hellem Bildausschnitt, deshalb dunkler als --accent-text */
/* Beide Absaetze im Ablaufteil, nicht nur der in .ablauf__step p. */
.ablauf__step,.ablauf__step p,.ablauf__ziel-inhalt p{color:rgba(255,255,255,.92)}

/* Zeitstrahl: Jahreszahl und Beschreibung standen bei 0,62 Deckkraft und damit
   auf 3,99:1 — Lighthouse hat genau die fuenf <time>-Elemente beanstandet.
   0,72 bringt 5,2:1 auf dem Papier. Gleiche Korrektur wie in Runde 41 an den
   uebrigen Kleintexten; hier war sie noch offen. */

/* ===================== Mobile Komposition =====================
   Der schmale Bildschirm ist kein verkleinerter Desktop. Diese Regeln halten
   Bildhoehen, Abstaende und Bedienflaechen auch auf kurzen Telefonen im
   sichtbaren Bereich. */
.icon-arrow--north{transform:rotate(-90deg)}

@media(max-width:820px){
  :root{--t:15px;--t-lead:clamp(16px,4.6vw,19px)}

  .site-header{top:8px;width:calc(100vw - 16px);min-height:58px;padding:7px 10px}
  .site-brand{gap:8px}.site-brand img{width:36px}.site-brand strong{font-size:20px}.site-brand small{font-size:7.5px}

  .image-hero{height:100svh;min-height:560px;padding-top:68px}
  .mobile-hero-copy{right:clamp(16px,5vw,24px);bottom:clamp(46px,7svh,68px);left:clamp(16px,5vw,24px)}
  .mobile-hero-copy>p{margin-bottom:8px}
  /* Der qualifizierte Selektor gewinnt bewusst gegen die allgemeine
     .mobile-hero-copy>p-Labelregel weiter oben. */
  .mobile-hero-copy>.mobile-hero-title{margin:0 0 14px;font:500 clamp(48px,14vw,72px)/.84 var(--schrift-titel);letter-spacing:-.035em;text-transform:uppercase}
  .mobile-hero-copy ul{gap:6px 14px;margin:16px 0 17px}
  .mobile-hero-copy a{display:inline-flex;align-items:center;min-height:46px;padding:12px 16px;border-radius:12px}
  .mobile-hero-copy a .icon-arrow{margin-left:12px}
  .mobile-notdienst{margin-bottom:11px;letter-spacing:.09em}

  .mobile-story{gap:38px;padding:62px 16px 72px}
  .mobile-header{margin-bottom:2px;text-align:center}
  .mobile-header p{margin-bottom:10px}
  .mobile-chapter{gap:14px}
  .mobile-scene{height:clamp(190px,30svh,270px);min-height:0;border-radius:12px}
  .mobile-panorama{width:100%;max-width:100%;height:100%;object-fit:cover;object-position:var(--scene-x) center;transform:none}
  .visual-note{top:8px;right:8px;padding:5px 7px;border-radius:6px;font-size:7px}
  .mobile-chapter>div:last-child{padding:0 2px;text-align:center}
  .mobile-chapter h2{margin:0 0 8px;font-size:clamp(30px,8.5vw,40px);line-height:.94}
  .mobile-chapter p{margin:0 0 10px;line-height:1.5}
  .mobile-chapter a{display:inline-flex;align-items:center;min-height:40px}

  .trust-section{display:flex;flex-direction:column;gap:0;padding:58px 16px 64px}
  .trust-copy{display:contents}
  .trust-copy h2{order:-5;margin:0 0 20px;text-align:center}
  .trust-portrait{order:-4;height:clamp(220px,36svh,320px);min-height:0;margin-bottom:30px;border-radius:12px}
  .trust-copy>p.trust-lead{order:-3}
  .trust-copy>p:not(.trust-brand):not(.trust-lead){order:-2}
  .trust-brand{order:-1;justify-content:center}
  .trust-portrait img{height:100%;min-height:0;object-position:center 38%;transform:scale(1.01)}
  .trust-portrait::after{display:none}
  .trust-copy>p.trust-brand{margin:0 0 16px}.trust-brand img{width:58px}.trust-brand span{font-size:1rem}
  .trust-copy>p:not(.section-number){margin:20px 0;text-align:center}

  .audience__row li span{display:none}

  .reviews{text-align:center}
  .reviews__link{align-items:center}
  .reviews__text{max-width:36ch;margin-inline:auto}

  .objects__head{text-align:center}

  .project-map{padding:64px 16px 38px}
  .map-heading{margin-bottom:30px}
  .map-shell{height:clamp(520px,78svh,650px);min-height:0}
  .map-finder{right:10px;left:10px;width:auto;transform:none}
  .map-finder:hover,.map-finder:focus-within{padding:12px;gap:8px;transform:translateY(-4px)}
  .map-finder button{min-height:42px}
  .map-cta{margin-top:20px;padding:14px 18px}

  .objects{padding-top:58px}
  .objects--buehne .objects__viewport{height:clamp(610px,92svh,760px);min-height:0;overflow:hidden}
  .objects--buehne .object__media{display:flex;flex-direction:column;height:100%;padding:0 14px;background:none}
  .objects--buehne .object__media>img{position:relative;top:auto;left:auto;flex:0 0 clamp(260px,42svh,340px);width:100%;height:clamp(260px,42svh,340px);border-radius:12px 12px 0 0;object-fit:cover}
  .objects--buehne .object__copy,.objects--buehne .object__copy--right{position:relative;inset:auto;display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;min-height:0;padding:18px;border-radius:0 0 12px 12px;background:rgba(247,244,234,.94);text-align:center;transform:none}
  .objects--buehne .object__copy p:not(.object__place){display:block;font-size:14px;line-height:1.45}
  .objects--buehne .object__copy h3{font-size:clamp(28px,9vw,40px)}
  .objects--buehne .object__scope{gap:6px 14px;margin-top:12px;font-size:11px}
  .objects--buehne .object__scope{justify-content:center}
  .objects--buehne .object__corner,.objects--buehne .objects__leiste{display:none}
  .objects--buehne .objects__pfeil{top:calc(clamp(260px,42svh,340px)/2);width:46px;border-radius:12px}
  .objects--buehne .objects__pfeil--links{left:22px}
  .objects--buehne .objects__pfeil--rechts{right:22px}

  .ablauf__block{padding-top:68px;padding-bottom:76px}
  .ablauf__ziel{justify-items:center;padding-left:0;text-align:center}
  .ablauf__ziel-inhalt{justify-items:center;width:100%}
  .contact-actions{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;width:min(100%,360px);gap:8px;margin-top:28px}
  .contact-action{width:auto;min-height:44px;padding:10px 12px;font-size:11px;line-height:1.25;text-align:center;background:rgba(18,21,12,.28)}
  .contact-action--primary{grid-row:1;grid-column:1/-1;background:var(--accent)}
  .contact-actions .contact-action:first-child{grid-row:2;grid-column:1}
  .contact-actions .contact-action:last-child{grid-row:2;grid-column:2}
  .contact-zeiten{margin-top:16px;color:rgba(255,255,255,.88)}
  .contact-zeiten strong{color:#f0a07a}

  .footer-cols{row-gap:26px}
}

/* Kurze Telefone und Querformat: weniger sichtbare Hoehe darf weder den Hero
   noch die Bildkapitel kuenstlich auf Desktop-Hoehe zwingen. */
@media(max-width:820px) and (max-height:700px){
  .image-hero{min-height:480px}
  .mobile-hero-copy{bottom:42px}
  .mobile-hero-copy>.mobile-hero-title{font-size:clamp(42px,12.5vw,58px)}
  .mobile-hero-copy ul{margin:11px 0 12px}
  .mobile-notdienst{margin-bottom:7px}
  .mobile-hero-copy a{min-height:42px;padding:10px 14px}
  .mobile-scene{height:clamp(180px,32svh,230px)}
  .trust-portrait{height:clamp(200px,34svh,260px)}
  .map-shell{height:540px}
}

@media(max-width:820px) and (orientation:landscape) and (max-height:560px){
  .image-hero{height:100svh;min-height:380px}
  .mobile-hero-copy{top:78px;right:18px;bottom:24px;left:18px;align-content:end}
  .mobile-notdienst{display:none}
  .mobile-hero-copy>.mobile-hero-title{font-size:clamp(36px,8vw,48px)}
  .mobile-hero-copy ul{margin:8px 0 9px}
  .mobile-hero-copy li{font-size:8px}
  .mobile-notdienst{margin-bottom:5px}
  .mobile-hero-copy a{min-height:38px;padding:8px 13px}
  .hero-ai-label{font-size:7px}
}

@media(hover:none) and (max-width:820px){
  .map-finder:hover{padding:7px;gap:6px;transform:none;background:rgba(248,246,239,.93);box-shadow:0 18px 55px rgba(18,21,12,.22)}
}
.service-shutter{position:fixed;z-index:10000;inset:0;pointer-events:none}
.service-shutter svg{display:block;width:100%;height:100%}

/* Vorerst ausgeblendet, nicht geloescht: Referenzen (bis echte Fotos freigegeben
   sind). Zum Einblenden nur die
   Klasse am jeweiligen Element entfernen — Fundstellen: grep "ausgeblendet". */
.ausgeblendet{display:none!important}

/* Link zum Bewertungshinweis (§ 5b Abs. 3 UWG), neben "Jetzt alle ansehen". */
.reviews__hinweis{text-align:center}
.reviews__hinweis a{color:inherit;text-decoration:underline;text-underline-offset:3px}

/* Ziel des Karten-Knopfs: Kontaktbox komplett unter der Kopfleiste zeigen. */
#termin{scroll-margin-top:120px}

/* Foto "Das sind wir": wird beim Hineinscrollen von links aufgezogen (Startsignal
   in app.js, wie beim Zeitstrahl). Der KI-Hinweis folgt, sobald das Bild steht. */
@media(prefers-reduced-motion:no-preference){
  /* Zugeschnitten wird das Bild, nicht der Rahmen: ein ganz weggeschnittener
     Rahmen meldet dem IntersectionObserver nie "sichtbar". */
  .trust-portrait.ist-animiert img{clip-path:inset(0 100% 0 0);transition:clip-path 1.3s cubic-bezier(.7,0,.2,1)}
  .trust-portrait.ist-sichtbar img{clip-path:inset(0 0 0 0)}
  .trust-portrait.ist-animiert::after{opacity:0;transition:opacity .6s ease .7s}
  .trust-portrait.ist-sichtbar::after{opacity:1}
  .trust-portrait.ist-animiert .visual-note{opacity:0;transition:opacity .4s ease 1.1s}
  .trust-portrait.ist-sichtbar .visual-note{opacity:1}
}

/* Logo und Text teilen sich einen Satzspiegel; unter dem Logo ist die ganze
   Textbreite frei. Auf schmalen Bildschirmen steht das Logo vor den Absätzen. */
.trust-section:has(.trust-portrait--logo){grid-template-columns:minmax(0,1fr)}
.trust-portrait--logo{display:grid;place-items:center end;width:100%;height:auto;overflow:visible}
.trust-copy:has(>.trust-portrait--logo){
  display:flow-root;
  width:min(100%,1120px + var(--breit,0px) * .23);
  margin-inline:auto;
  padding-top:0;
}
@media(min-width:821px){
  .trust-copy>.trust-portrait--logo{
    float:left;
    width:min(43%,625px);
    margin:18px clamp(24px,4vw,64px) 24px 0;
  }
  .trust-copy:has(>.trust-portrait--logo)>p:not(.section-number,.trust-brand){
    display:flow-root;
    max-width:none;
  }
  .trust-copy>.trust-full-width{clear:left}
}
.trust-copy:has(>.trust-portrait--logo) h2{margin-inline:auto;padding-bottom:12px;text-align:center}
@media(max-width:820px){
  .trust-copy:has(>.trust-portrait--logo)>p{margin-inline:auto}
}
.logo-zeichnung{position:relative;display:block;width:min(100%,625px)}
.trust-portrait--logo .logo-zeichnung img{width:100%;height:auto;min-height:0;object-fit:contain;transform:none}
.logo-zeichnung__linien{position:absolute;inset:0;display:none;width:100%;height:100%;overflow:visible}
.logo-zeichnung__linien path{fill:none;stroke:#7fa64e;stroke-width:4;stroke-linecap:round;stroke-linejoin:round}
@media(max-width:820px){.trust-portrait--logo{place-items:center}.logo-zeichnung{width:min(92%,480px)}}
/* Zeichnen: jede Linie laeuft per Strichlaenge (pathLength=1) von 0 auf voll,
   leicht versetzt; danach kommt das echte Logo und die Linien gehen. */
@media(prefers-reduced-motion:no-preference){
  .trust-portrait--logo.ist-animiert .logo-zeichnung__linien{display:block;transition:opacity .9s ease 2.05s}
  .trust-portrait--logo.ist-animiert .logo-zeichnung__linien path{stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset 1.6s cubic-bezier(.45,0,.25,1) calc(var(--i) * .04s)}
  .trust-portrait--logo.ist-sichtbar .logo-zeichnung__linien path{stroke-dashoffset:0}
  .trust-portrait--logo.ist-animiert img{clip-path:none;opacity:0;transition:opacity 1s ease 1.55s}
  .trust-portrait--logo.ist-sichtbar img{opacity:1}
  .trust-portrait--logo.ist-sichtbar .logo-zeichnung__linien{opacity:0}
  /* Zuruecksetzen (Logo ganz aus dem Bild) ohne Rueckwaerts-Animation. */
  .trust-portrait--logo.ist-animiert:not(.ist-sichtbar) *{transition:none!important}
}
.trust-portrait--logo::after{display:none}

/* Grossbildschirme: Die Schrift waechst mit der Breite, auf flachen Fenstern langsamer. */
@media(min-width:1921px){
  :root{
    --breit:clamp(0px,min(100vw - 1920px,max(320px,(100svh - 880px) * 2)),1280px);
    --h1:calc(110px + var(--breit) * .028);
    --h2:calc(58px + var(--breit) * .028);
    --h3:calc(30px + var(--breit) * .009);
    --t-lead:calc(21px + var(--breit) * .009);
    --t:calc(16px + var(--breit) * .0055);
    --t-klein:calc(13px + var(--breit) * .0045);
    --label:calc(10px + var(--breit) * .0036);
    --label-s:calc(8px + var(--breit) * .003);
  }
  section[id],#ablauf,#leistungen{scroll-margin-top:calc(104px + var(--breit) * .02)}
  .hero-copy{width:min(34vw,470px + var(--breit) * .25)}
  .hero-ai-label{font-size:var(--label)}
  .copy-fog{width:min(46vw,720px + var(--breit) * .34)}
  .copy h2{max-width:calc(13ch + var(--breit) * .32)}
  .copy p{max-width:calc(46ch + var(--breit) * .08)}
  .site-header{width:min(94vw,1540px + var(--breit) * .38)}
  .site-brand img{width:calc(55px + var(--breit) * .019)}
  .site-brand strong{font-size:calc(29px + var(--breit) * .01)}
  .site-brand small{font-size:calc(9px + var(--breit) * .003)}
  .site-nav a,.nav-services summary{font-size:calc(12px + var(--breit) * .004)}
  .nav-services__menu a{font-size:var(--label)}
}
