@font-face{
  font-family:'Marcellus';
  src:url('../fonts/Marcellus.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Manrope';
  src:url('../fonts/Manrope.woff2') format('woff2');
  font-weight:200 800;font-style:normal;font-display:swap;
}
/* Cinzel – römische Capitalis, nur für die grossen Namenszüge (Willkommens-
   seite, Hero, Seitenkopf). Der Fliesstext bleibt Marcellus/Manrope. */
@font-face{
  font-family:'Cinzel';
  src:url('../fonts/Cinzel.woff2') format('woff2');
  font-weight:400 700;font-style:normal;font-display:swap;
}
/* Parisienne – die kalligrafische Schreibschrift des Hero-Namenszugs.
   AUSSER BETRIEB seit dem 02.09.2026 (Ruecknahme auf Ansage): Der Namenszug
   steht wieder in Cinzel-Versalien, siehe `.hero h1` weiter unten. In v13
   und v14 war sie in Betrieb, davor und danach nicht.

   Auskommentiert statt geloescht, und `assets/fonts/Parisienne.woff2`
   (22 KB) bleibt ebenfalls im Paket liegen — Wiedereinschalten heisst,
   diese Kommentarzeichen zu entfernen und die vier Werte in `.hero h1`
   sowie den margin-top von `.hero .sub` zurueckzustellen; alle fuenf sind
   dort einzeln benannt.

   Zur Herkunft, damit sie nicht neu recherchiert werden muss: eigene
   Bibliothek `~/Services/fonts`, SIL OFL 1.1, Pruefsumme gegen das
   Manifest verglichen — nichts nachgeladen.

   `font-display:block` stand hier AUSDRUECKLICH anders als bei den drei
   Schriften darueber: Bei `swap` stuende der Name den ersten Moment in der
   Ersatzschrift und spraenge dann in die Handschrift — bei einer
   Schreibschrift ist der Unterschied so gross (andere Breite, andere Hoehe,
   andere Anmutung), dass das als Fehler gelesen wird.

@font-face{
  font-family:'Parisienne';
  src:url('../fonts/Parisienne.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:block;
}
*/
:root{
  /* Zweites Netz gegen den erzwungenen Dunkelmodus mobiler Browser
     (14.09.2026). Das erste ist <meta name="color-scheme" content="only light">
     im Kopf jeder Seite — es greift schon vor dem ersten Zeichnen. Diese
     Regel hier faengt den Fall ab, dass eine Seite ohne das Meta-Element
     ausgeliefert wird. "only light" statt "light": das Schluesselwort only
     verbietet dem Browser ausdruecklich, ein anderes Schema zu erzwingen.
     Anlass war der Befund vom 10.09.2026, dass der Hintergrund auf einem
     Samsung-Geraet viel dunkler aussieht als gebaut — Chrome fuer Android
     kippt bei Seiten ohne Farbschema den cremefarbenen Schleier ins Dunkle.
     Die Seite hat KEINEN eigenen Dunkelmodus-Zweig (kein
     prefers-color-scheme im ganzen Stylesheet), deshalb ist das hier eine
     reine Aussage ueber den Bestand, keine Einschraenkung. */
  color-scheme:only light;

  --olive:#4C5539;
  --olive-dark:#3A4129;
  --olive-soft:#6B7355;
  --cream:#FAF5F1;
  --cream-panel:rgba(250,245,241,.92);
  --cream-panel-strong:rgba(250,245,241,.97);
  --ink:#33392A;
  --line:rgba(76,85,57,.18);
  --shadow:0 18px 50px rgba(58,65,41,.14);
  --radius:18px;
}
*{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;overflow-x:hidden;}
body{
  font-family:'Manrope',system-ui,-apple-system,sans-serif;
  background:var(--cream);
  color:var(--ink);
  line-height:1.75;
  font-size:17px;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,.serif{font-family:'Marcellus',Georgia,serif;font-weight:400;color:var(--olive);}

/* ============ Willkommens-Overlay (Bild) ============ */
#intro{
  position:fixed;inset:0;z-index:1000;background:#5d7a49;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  overflow:hidden;
  transition:opacity 1.4s ease;
}
#intro.fade{opacity:0;pointer-events:none;}
/* Solange die Willkommensseite liegt, bewegt sich dahinter nichts */
body.intro-an{overflow:hidden;}
/* Grundfarbe, falls das Bild noch nicht da ist */
#introBg{
  position:absolute;inset:0;z-index:0;
  background:url('../img/welcome-wald2.jpg') center/cover no-repeat;
  filter:blur(22px) saturate(.95) brightness(.88);
  transform:scale(1.12);
}
/* Das Bild füllt IMMER den ganzen Bildschirm – es trägt keinen Text mehr,
   deshalb sind die früheren „contain“-Ausnahmen entfallen. */
#introImg{
  position:absolute;inset:0;z-index:1;
  width:100%;height:100%;
  object-fit:cover;object-position:center center;
}
/* Heller Schleier: hält das lichte Waldbild licht und trägt zugleich die
   grüne Schrift – dieselbe Handschrift wie Hero und Navigation, dadurch
   geht die Willkommensseite ohne Bruch in die Startseite über. */
#introVeil{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    radial-gradient(ellipse at 50% 44%, rgba(250,245,241,.60) 0%, rgba(250,245,241,.40) 42%, rgba(250,245,241,.14) 68%, rgba(250,245,241,0) 82%),
    linear-gradient(180deg, rgba(250,245,241,.26) 0%, rgba(250,245,241,0) 34%, rgba(250,245,241,0) 62%, rgba(250,245,241,.30) 100%);
}
#introInner{
  position:absolute;z-index:3;left:50%;top:44%;transform:translate(-50%,-50%);
  width:min(92vw,860px);text-align:center;padding:0 4vw;
}
#introLogo{
  width:clamp(96px,13vw,150px);height:clamp(96px,13vw,150px);
  border-radius:50%;object-fit:cover;
  box-shadow:0 20px 60px rgba(20,26,14,.45);
  margin-bottom:clamp(20px,3.4vw,34px);
}
#introName{
  font-family:'Cinzel','Marcellus',Georgia,serif;font-weight:400;
  font-size:clamp(28px,5.6vw,62px);
  text-transform:uppercase;letter-spacing:.12em;
  color:var(--olive-dark);line-height:1.15;
  text-shadow:0 1px 0 rgba(250,245,241,.6), 0 0 22px rgba(250,245,241,.92), 0 0 60px rgba(250,245,241,.7);
}
#introSub{
  margin-top:clamp(12px,1.8vw,20px);
  font-family:'Manrope',sans-serif;font-weight:700;
  font-size:clamp(11.5px,1.5vw,15px);
  letter-spacing:.2em;text-transform:uppercase;line-height:1.6;
  color:var(--olive);
  text-shadow:0 0 18px rgba(250,245,241,.95), 0 0 44px rgba(250,245,241,.7);
}
#skipBtn{
  position:absolute;z-index:2;left:50%;bottom:clamp(18px,4vh,46px);
  transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:3px;
  background:rgba(76,85,57,.82);color:var(--cream);
  border:1px solid rgba(250,245,241,.65);border-radius:999px;
  padding:12px 38px 13px;font-family:'Manrope',sans-serif;
  cursor:pointer;white-space:nowrap;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  box-shadow:0 10px 30px rgba(58,65,41,.35);
  transition:background .3s,color .3s,transform .3s;
}
#skipBtn .sb-1{font-size:14px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;line-height:1.2;}
#skipBtn .sb-2{font-size:11px;font-weight:600;letter-spacing:.24em;text-transform:uppercase;line-height:1.2;opacity:.88;}
#skipBtn:hover{background:var(--cream);color:var(--olive);transform:translateX(-50%) translateY(-2px);}
@media(max-width:560px){
  #skipBtn{padding:11px 28px 12px;}
  #skipBtn .sb-1{font-size:12.5px;letter-spacing:.12em;}
  #skipBtn .sb-2{font-size:10px;letter-spacing:.18em;}
}

/* ============ Hintergrund-Video (Wald, Dauerschleife, ohne Ton) ============
   DIESE FASSUNG IST DER VIDEO-ZWILLING VON v11 (Entscheidung 01.09.2026).
   Inhaltlich ist alles aus v11 hier drin — helle Fusszeile, behobene
   Kastenkante am Hero-Schein, Cursor-Effekte, freigestelltes Logo.
   Der EINZIGE Unterschied ist der Hintergrund: hier laeuft wieder das
   Wald-Video, dort steht das Kleefoto.

   Was dieser Unterschied kostet, gehoert genannt:
     Datenvolumen     4,8 MB gegen 236 KB. Das bleibt der Preis.
                      (Bis 14.09.2026 waren es 8,9 MB — das zugekaufte
                      wald.mp4. Der eigene Waldweg-Loop ist kleiner.)
     Ruhige Darstellung  Ein Loop IST fortwaehrende Bewegung. Bei
                      prefers-reduced-motion wird das Video gar nicht
                      erst geholt (site.js) und waldweg-standbild.jpg
                      liegt darunter.

   KONTRAST — und hier stand zuerst eine Behauptung, die die Messung
   widerlegt hat. Der Gedanke war: ein Video hat eine Laufzeit, also auch
   Stellen, an denen es dunkel wird, also ist der Kontrast wieder eine
   Wahrscheinlichkeit. Das war bis v9 richtig. Seit den Aenderungen des
   01.09.2026 stimmt es nicht mehr, denn drei Ebenen tragen die Schrift
   inzwischen unabhaengig vom Hintergrund: der Kopfverlauf (.88/.60/.18),
   der Radialschein des Hero und die helle Fusszeile.

   Nachgerechnet gegen ein KOMPLETT SCHWARZES Videobild — die haerteste
   Stelle, die das Video ueberhaupt liefern kann:
     Navigation      5,22 : 1     Hero H1 (Zeilenrand)   7,01 : 1
     Hero Unterzeile 5,53 : 1     Hero Ortszeile         4,99 : 1
     Scroll-Hinweis  5,11 : 1     Fusszeile         6,17 bis 10,27 : 1
   Alles ueber 4,5. Der Kontrast ist damit auch in dieser Fassung eine
   feste Groesse, nicht mehr eine Wahrscheinlichkeit — er haengt nicht
   mehr davon ab, was das Video gerade zeigt.
   (Gerechnet wird je Textzeile gegen ihr AEUSSERES Ende: dort ist der
   Radialschein am duennsten. Wer Hero-Text verbreitert, muss neu rechnen.)

   Die Bilddateien der Foto-Fassungen (klee-gruen-hintergrund*.jpg,
   klee-hintergrund*.jpg, wald-hintergrund*.jpg) bleiben im Ordner
   liegen, sie werden hier nur nicht geladen. Schleier und Blattwerk
   stehen deshalb wieder auf ihren VIDEO-Werten aus v9, nicht auf den
   fuer das dunkle Kleefoto gerechneten — die waeren hier falsch herum. */
#bgWrap{
  position:fixed;inset:0;z-index:-2;overflow:hidden;background:var(--olive-dark);
}
#bgVideo{
  position:absolute;top:50%;left:50%;
  min-width:100%;min-height:100%;width:auto;height:auto;
  /* Hinterste der drei Parallax-Ebenen (Faktor 0,014 auf --sy, das site.js
     beim Scrollen schreibt) — sie wandert am wenigsten, deshalb wirkt sie
     am weitesten entfernt.

     Zwei Zahlen haengen zusammen und duerfen nur gemeinsam geaendert werden:
     scale(1.10) ist die Reserve, die verhindert, dass beim Verschieben der
     Videorand ins Bild rutscht — sie betraegt 5 % der Videohoehe oben.
     max(-22px, …) ist die Klemme, die die Verschiebung darunter haelt.
     22 px < 5 % gilt ab 440 px Videohoehe, also auf jedem realen Geraet.
     Wer die Klemme lockert, muss scale mit anheben. */
  transform:translate(-50%,calc(-50% + max(-22px,calc(var(--sy,0) * -0.014px))))
            scale(1.10) translateZ(0);
  object-fit:cover;
  /* Gemessen am 14.09.2026 gegen das NEUE Material (Waldweg, Handy-Aufnahme
     hochkant). Es ist deutlich dunkler als das alte Wald-Video: die
     Leuchtdichte im obersten Zehntel liegt im Mittel bei 0,178 statt im
     hellen Bereich — oben steht dichtes Laubdach, nicht Nebel.
     brightness(1.10) hebt das an, contrast(.98) zieht dabei die fast
     schwarzen Stellen im Unterholz mit hoch, ohne dass der Himmel zwischen
     den Kronen ausbrennt (bei brightness 1.14 lag die helle Spitze im
     obersten Band bereits bei 0,922 — geprueft und verworfen).
     saturate bleibt knapp unter 1: das Gruen ist in der Aufnahme schon
     kraeftig, und Aufhellen laesst Farbe ohnehin lebendiger wirken. */
  filter:saturate(.94) brightness(1.10) contrast(.98);
}
/* DER OBERSTE STOPP IST AM 14.09.2026 VON DUNKLEM OLIV AUF CREME GEDREHT —
   mit dem neuen Video waere er sonst falsch herum.

   Die Regel dahinter ist in diesem Projekt schon dreimal bestaetigt worden:
   Ein dunkler Stopp DAEMPFT einen hellen Hintergrund (richtig), ueber einem
   dunklen Hintergrund drueckt derselbe Stopp Schwarz auf Schwarz (falsch).
   Das alte Wald-Video war oben hell (Nebel, offener Himmel), deshalb stand
   hier rgba(58,65,41,.30). Das neue Material ist oben dichtes Laubdach.

   Gemessen am Standbild des neuen Loops (Sekunde 10), Kette Video ->
   CSS-filter -> Schleier -> Kopfverlauf, dunkelste Stelle je Band:
                       alter Stopp (Oliv .30)   neuer Stopp (Creme .42)
     Kopfzeile oben          8,10 : 1                 8,85 : 1
     Kopfzeile Mitte         5,01 : 1                 6,81 : 1
     Kopfzeile unten         2,14 : 1                 4,40 : 1
   Die mittlere Zeile traegt die Navigation; die untere ist der Rand des
   Kopfverlaufs, an dem kein Text steht. Der Wechsel kostet nichts und
   bringt fast zwei Stufen.

   Wer hier wieder ein helles Video einsetzt, dreht den Stopp zurueck. */
#bgVeil{
  position:fixed;inset:0;z-index:-1;
  background:linear-gradient(180deg,
    rgba(250,245,241,.42) 0%,
    rgba(250,245,241,.55) 38%,
    rgba(250,245,241,.82) 100%);
  pointer-events:none;
}

/* ============ Navigation ============ */
header{
  position:fixed;top:0;left:0;right:0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;
  padding:16px 5vw;
  transition:background .4s,box-shadow .4s,padding .4s;
}
header.scrolled{
  background:var(--cream-panel-strong);
  box-shadow:0 6px 30px rgba(58,65,41,.10);
  padding:10px 5vw;
}
.brand{display:flex;align-items:center;gap:14px;text-decoration:none;}
/* Freigestelltes Monogramm statt der Kreis-Kachel (01.09.2026). In der
   alten Datei war der Schriftzug „PSYCHOTHERAPIE RALF BÜRGMANN" mit
   eingebrannt — bei 46 px war er ohnehin nur noch ein grauer Streifen,
   und der Kreis stand als heller Fleck ueber dem Wald. Der weiche
   Schein ersetzt den Schlagschatten: er traegt das dunkle Monogramm
   ueber hellen wie dunklen Stellen des Fotos. */
.brand img{
  width:44px;height:44px;object-fit:contain;display:block;
  filter:drop-shadow(0 0 10px rgba(250,245,241,.9))
         drop-shadow(0 2px 6px rgba(250,245,241,.7));
}
header.scrolled .brand img{filter:none;}
.brand span{font-family:'Marcellus',serif;font-size:19px;letter-spacing:.06em;color:var(--olive);}
nav{display:flex;gap:28px;}
nav a{
  text-decoration:none;color:var(--olive);font-size:13.5px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;position:relative;padding:4px 0;
  transition:color .4s;
}
nav a::after{
  content:'';position:absolute;left:0;bottom:0;width:0;height:1.5px;
  background:currentColor;transition:width .3s;
}
/* Über dem Hintergrund steht die Navigation ebenfalls in Grün (wie der
   Hero). Der helle Verlauf darunter trägt sie.

   AM 01.09.2026 NACHGESCHÄRFT — und zwar gemessen, nicht nach Gefühl:
   Das neue Waldfoto ist im oberen Bildbereich deutlich dunkler und
   satter als das frühere Video. Am gerenderten Bild ergab die alte
   Abstufung (.78 / .34) hinter der Menüzeile nur noch 3,7 : 1, an den
   dunkelsten Stellen 2,8 : 1 — unter der Schwelle von 4,5 : 1, die für
   Schrift unter 18 pt gilt. Der Textschatten half dem Auge, aber er
   zählt in keiner Messung mit.

   Zwei Änderungen zusammen, weil eine allein nicht gereicht hätte:
   der Verlauf trägt mehr (.88 / .60), und die Schrift wird dunkler
   (--olive-dark statt --olive). Gemessen danach: 6,3 : 1 im Mittel,
   5,2 : 1 an der dunkelsten Stelle der Kopfleiste.

   Die untere Kante läuft 18 px in die Seite hinein aus, sonst endete
   der helle Streifen an einer sichtbaren Linie. */
header:not(.scrolled)::before{
  content:'';position:absolute;inset:0 0 -18px 0;z-index:-1;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(250,245,241,.88) 0%,
    rgba(250,245,241,.60) 62%,
    rgba(250,245,241,.18) 88%,
    rgba(250,245,241,0)   100%);
}
@media(min-width:901px){
  header:not(.scrolled) nav a{color:var(--olive-dark);text-shadow:0 0 14px rgba(250,245,241,.95),0 0 34px rgba(250,245,241,.75);}
}
header:not(.scrolled) .brand span{color:var(--olive-dark);text-shadow:0 0 14px rgba(250,245,241,.95),0 0 34px rgba(250,245,241,.75);}
header:not(.scrolled) #navToggle{color:var(--olive-dark);text-shadow:0 0 14px rgba(250,245,241,.95),0 0 34px rgba(250,245,241,.75);}
header .brand span,header #navToggle{transition:color .4s;}
header:has(nav.open) #navToggle{color:var(--olive);text-shadow:none;}
nav a:hover::after{width:100%;}
#navToggle{display:none;background:none;border:none;cursor:pointer;color:var(--olive);font-size:28px;line-height:1;}
@media(max-width:900px){
  nav{
    position:fixed;top:0;right:-290px;height:100vh;width:270px;
    flex-direction:column;gap:8px;background:var(--cream-panel-strong);
    padding:96px 34px;box-shadow:-10px 0 40px rgba(58,65,41,.18);
    transition:right .35s ease;backdrop-filter:blur(10px);
  }
  nav.open{right:0;}
  nav a{font-size:15px;padding:10px 0;}
  #navToggle{display:block;position:relative;z-index:110;}
}

/* ============ Hero ============ */
.hero{
  min-height:100vh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  padding:120px 6vw 80px;
}
/* Nur noch das Monogramm: kein weisser Kreis, kein Schriftzug darunter,
   und leicht durchscheinend (Vorgabe 01.09.2026). Die Angaben, die
   frueher im Bild standen, stehen zwei Zeilen tiefer als echte Schrift —
   sie sind damit vorlesbar, durchsuchbar und skalieren mit.

   object-fit:contain statt cover: das Monogramm ist quadratisch und darf
   an keiner Kante angeschnitten werden. Der weiche Schein steht an der
   Stelle des frueheren Schlagschattens; er traegt das dunkle Zeichen
   ueber jeder Stelle des Waldfotos, so wie der Textschatten die
   Ueberschrift darunter traegt. */
.hero img.hero-logo{
  width:clamp(118px,15vw,178px);height:clamp(118px,15vw,178px);
  object-fit:contain;display:block;
  opacity:.84;
  filter:drop-shadow(0 0 18px rgba(250,245,241,.95))
         drop-shadow(0 8px 30px rgba(250,245,241,.65));
  margin-bottom:30px;
}
/* Weicher heller Schein hinter dem Hero-Text – trägt die grüne Schrift
   auch dann, wenn im Wald-Video gerade eine dunkle Stelle läuft.
   Liegt über dem Video-Schleier (#bgVeil) und unter dem Text. */
.hero{position:relative;}
/* LETZTER STOPP 70 %, NICHT 78 % — und das ist keine Geschmacksfrage.
   `radial-gradient(ellipse at center, …)` ohne Groessenangabe bedeutet
   `farthest-corner`: 100 % des Verlaufs ist die ECKE des Kastens. Die
   vier SEITEN liegen damit bei genau 1/√2 = 70,7 % des Radius. Steht
   der letzte Stopp weiter draussen, ist an der Kastenkante noch Deckung
   uebrig — hier waren es rund 0,13 — und die schneidet der Kasten hart
   ab. Ergebnis ist ein sichtbares helles Rechteck mitten im Bild.
   Ueber dem hellen Waldfoto ging der Absatz unter, ueber dem dunklen,
   glatten Kleefoto stand er als Kontur da (gemeldet 01.09.2026).
   Bei 70 % ist die Deckung auf der GESAMTEN Kastenkante null: an den
   Seiten (70,7 %) ebenso wie an den Ecken (100 %).
   Wer den letzten Stopp je wieder ueber 70,7 % schiebt, holt die
   Kontur zurueck — der Kasten muss dann mitwachsen. Die Zwischenstopps
   0/40/62 % bleiben unangetastet, und damit auch alle gemessenen
   Kontrastwerte: der gesamte Hero-Text sitzt innerhalb von 62 %. */
.hero::before{
  content:'';position:absolute;z-index:-1;
  left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(1180px,96vw);height:min(820px,92vh);
  background:radial-gradient(ellipse at center,
    rgba(250,245,241,.80) 0%,
    rgba(250,245,241,.62) 40%,
    rgba(250,245,241,.28) 62%,
    rgba(250,245,241,0) 70%);
  pointer-events:none;
}
/* ============ Der Namenszug im Hero ============
   ZURUECKGENOMMEN am 02.09.2026 auf Ansage: wieder Cinzel in Versalien, also
   Zeichen fuer Zeichen der Stand aus v12. Die Handschrift (Parisienne) war
   nur in v13 und v14 in Betrieb.

   Vier Werte gehoeren zusammen und sind gemeinsam zurueckgedreht — wer nur
   die Schriftfamilie tauscht, bekommt weder das eine noch das andere sauber:
     font-family      Cinzel statt Parisienne
     font-size        clamp(28px,4.8vw,56px) statt clamp(42px,7.2vw,84px)
     text-transform   uppercase statt none
     letter-spacing   .12em statt 0
   Dazu die fuenfte Stelle eine Regel tiefer: `.hero .sub{margin-top}` geht
   von 30 auf 18 px zurueck. Die 30 px waren allein fuer die Unterlaenge des
   handgeschriebenen „g" da; Versalien haben keine Unterlaenge, der Abstand
   sieht sonst nach Loch aus.

   `line-height` steht hier wieder gar nicht: Cinzel kam immer mit dem
   Vorgabewert aus, die 1.06 waren eine Folge der Schreibschrift.

   KONTRAST — und hier stand zuerst eine Zahl, die die Messung widerlegt hat.
   Die Annahme war: mit der Ruecknahme wird die Zeile schmaler (555 -> 433 px)
   und rueckt in den dichteren Teil des Radialscheins. Falsch, und zwar aus
   einem Grund, der es wert ist, hier zu stehen:

     Die 433 px stammten aus einer Canvas-Messung von „Ralf Bürgmann".
     Canvas wendet `text-transform` NICHT an — gemessen wurde also die
     gemischte Schreibweise, waehrend die Seite Versalien rendert.
     Versalien sind breiter. Am gerenderten Element nachgemessen betraegt
     die Zeilenbreite je Punktgroesse 10,711 statt der angenommenen 6,176.

   Tatsaechlich ist die Versalien-Zeile mit 600 px bei 1672 px Fenster die
   BREITERE der beiden und steht damit weiter aussen im Schein, wo er duenner
   ist. Neu gerechnet gegen ein komplett schwarzes Videobild, Schein im
   schwaechsten Moment seiner Animation, ohne text-shadow:
     400 px Fenster   5,06 : 1   <- schwaechste Stelle
     ab 583 px        6,36 bis 6,42 : 1
   (Die Handschrift lag bei 5,37 bzw. 6,43–6,47 — sie war minimal besser,
   weil schmaler.) Beide Fassungen liegen ueber 4,5 und weit ueber den 3,0
   fuer grossen Text. Diese Zahlen gelten rueckwirkend auch fuer v12 und
   alle frueheren Fassungen; der Zustand ist nicht neu, nur die Zahl war
   vorher falsch. Skript: scratchpad/hero_kontrast.py.

   MERKER fuer jede kuenftige Breitenmessung an dieser Zeile: am
   gerenderten Element messen, nicht per Canvas — sonst faellt
   text-transform still unter den Tisch. */
.hero h1{
  font-family:'Cinzel','Marcellus',Georgia,serif;
  font-size:clamp(28px,4.8vw,56px);
  text-transform:uppercase;letter-spacing:.12em;
  color:var(--olive-dark);
  text-shadow:0 1px 0 rgba(250,245,241,.6), 0 0 22px rgba(250,245,241,.9), 0 0 60px rgba(250,245,241,.7);
}
/* margin-top wieder 18 px (Ruecknahme 02.09.2026). Er war fuer die Dauer von
   v13/v14 auf 30 px gestanden, weil die Handschrift die Unterlaenge des „g"
   37 px unter die Grundlinie setzte. Mit den Versalien gibt es keine
   Unterlaenge mehr — bliebe der Wert stehen, sieht der Abstand nach Loch
   aus. Der Merker dahinter gilt weiter: ein Abstand gehoert zur Schrift,
   die darueber steht, nicht zur Zeile darunter. */
.hero .sub{
  margin-top:18px;font-size:clamp(13.5px,1.6vw,16px);
  letter-spacing:.2em;text-transform:uppercase;font-weight:700;
  color:var(--olive);text-shadow:0 0 18px rgba(250,245,241,.9), 0 0 44px rgba(250,245,241,.65);
  max-width:min(100%,44ch);line-height:1.6;
}
/* --olive statt --olive-soft (01.09.2026): Über dem neuen Foto kam die
   weiche Variante an den dunkelsten Stellen nur auf 3,3 : 1. Dieselbe
   Zeile in --olive misst 5,2 : 1. Der Unterschied im Bild ist kaum zu
   sehen, der in der Messung entscheidet. */
.hero .orte{
  margin-top:14px;color:var(--olive);font-size:15px;letter-spacing:.08em;font-weight:600;
  text-shadow:0 0 16px rgba(250,245,241,.9), 0 0 40px rgba(250,245,241,.6);
}
.hero .cta{
  margin-top:42px;display:flex;gap:16px;flex-wrap:wrap;justify-content:center;
}

/* ---- Knopfzeilen am Handy mittig (14.09.2026, Nutzerwunsch) --------------
   Ausgangslage, am 390-px-Geraet gemessen (deviceScaleFactor 2, mobile):
   Die beiden Hero-Knoepfe standen mittig (die Regel darueber), die drei
   Knoepfe weiter unten dagegen linksbuendig — „Anfahrt & Parken" lag mit
   0 px links an der Kachelkante und liess rechts 25 px frei. Bei einem
   Knopf, der fast so breit ist wie die Kachel, liest sich das nicht als
   Ausrichtung, sondern als Schieflage.

   Zwei Stellen sind betroffen, beide auf der Startseite, beide heissen
   „Anfahrt & Parken": der einzelne Knopf unter den Standort-Kacheln
   (.knopfzeile) und die Dreier-Reihe im Kontakt-Teaser. Die Reihe wird als
   GANZES zentriert — ein einzelnes Kind einer Flex-Reihe mittig zu setzen,
   waehrend die Geschwister links bleiben, waere die naechste Schieflage.

   Ab 641 px bleibt alles linksbuendig: dort steht die Kachel breit, der
   Knopf ist deutlich schmaler als sie, und die linke Kante ist die Linie,
   an der Ueberschrift, Text und Knopf gemeinsam haengen. Genau so wurde
   die Fensteransicht abgenommen. */
@media(max-width:640px){
  .knopfzeile{text-align:center;}
  #kontakt-teaser .cta{justify-content:center;}
}
.btn{
  display:inline-block;text-decoration:none;border-radius:999px;
  padding:14px 38px;font-size:14px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;
  /* `transition:all` stand hier bis v8. Das animierte auch Rahmenbreite und
     Innenabstand mit — also Layout, das der Browser bei jedem Zwischenschritt
     neu rechnen muss. Benannte Eigenschaften laufen dagegen auf dem
     Compositor. Dauer von .3s auf .42s: ruhiger, passend zum Rest. */
  transition:transform .42s cubic-bezier(.22,.61,.36,1),
             background-color .42s ease,
             color .42s ease,
             border-color .42s ease,
             box-shadow .42s ease;
}
/* ============ Farbwechsel beim Darueberfahren ============
   Vorgabe 01.09.2026: JEDER Knopf tauscht die Farben, so wie es
   „Anfahrt & Parken" (.btn-line) schon immer getan hat — der Knopf
   kehrt sich um, Grund und Schrift wechseln die Plaetze. Das ist eine
   Aussage, kein Effekt: man sieht auf einen Blick, worauf der Zeiger
   steht, auch aus dem Augenwinkel.

   Bis v9 wurde .btn-solid beim Hover nur eine Spur dunkler
   (--olive -> --olive-dark). Der Unterschied betrug 1,2 : 1 — messbar,
   aber nicht sichtbar. Die Umkehr bringt 6,3 : 1.

   Dieselbe Umkehr liegt weiter unten auf .map-ph button, .gal-nav,
   .p-btn und den Galeriepunkten; :focus-visible bekommt sie ebenfalls,
   sonst waere die Tastatur schlechter gestellt als die Maus. */
.btn-solid{background:var(--olive);color:var(--cream);border:1px solid var(--olive);}
/* Der Hub kommt als Variable, nicht als transform — siehe „MAGNETIC
   BUTTON" am Dateiende: alle Zustaende teilen sich EINE transform-Angabe. */
.btn-solid:hover,.btn-solid:focus-visible{
  background:var(--cream);color:var(--olive);border-color:var(--olive);
  --mgl:-2px;
}
.btn-ghost{background:rgba(250,245,241,.16);color:var(--cream);border:1px solid rgba(250,245,241,.7);backdrop-filter:blur(6px);}
.btn-ghost:hover,.btn-ghost:focus-visible{background:var(--cream);color:var(--olive);border-color:var(--cream);}
.scroll-hint{
  margin-top:64px;color:var(--olive);font-size:12px;letter-spacing:.3em;font-weight:600;
  text-transform:uppercase;opacity:.9;animation:drift 3s ease-in-out infinite;
  text-shadow:0 0 16px rgba(250,245,241,.85);
}
@keyframes drift{0%,100%{transform:translateY(0)}50%{transform:translateY(8px)}}

/* ============ Sektionen ============ */
section{padding:0 6vw;}
.panel{
  max-width:1060px;margin:0 auto 90px;
  background:var(--cream-panel);
  border:1px solid var(--line);
  border-radius:var(--radius);
  box-shadow:var(--shadow);
  padding:clamp(38px,6vw,74px);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.kicker{
  font-size:12.5px;font-weight:700;letter-spacing:.3em;text-transform:uppercase;
  color:var(--olive-soft);margin-bottom:14px;
}
.panel h2{font-size:clamp(27px,3.6vw,40px);margin-bottom:26px;line-height:1.25;}
.panel p{margin-bottom:18px;max-width:72ch;}
.panel p:last-child{margin-bottom:0;}
.lead{font-size:clamp(18px,2.2vw,21px);color:var(--olive-dark);line-height:1.7;}

.two-col{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,60px);align-items:center;}
.two-col img{width:100%;border-radius:var(--radius);box-shadow:var(--shadow);display:block;}
@media(max-width:820px){.two-col{grid-template-columns:1fr;}}

/* „Über mich": Foto rechts eingebunden, der Text fließt darum herum.
   Das Bild endet damit innerhalb des ersten Absatzes statt neben dem
   ganzen Block (Vorgabe RB) – und es bleibt kein leerer Raum darunter. */
.bio::after{content:"";display:block;clear:both;}
.bio-foto{
  float:right;width:340px;max-width:40%;
  margin:6px 0 22px 38px;
  border-radius:var(--radius);box-shadow:var(--shadow);
}
/* Auf schmalen Schirmen kein Umfluss – sonst bleiben Textschnipsel daneben.
   Das Bild steht im Quelltext vorne (Float-Zwang); per order rutscht es hier
   wieder unter die Überschrift, damit die Lesereihenfolge stimmt.
   Absätze tragen dieselbe order und bleiben deshalb untereinander in
   Quelltext-Reihenfolge. */
@media(max-width:640px){
  .bio{display:flex;flex-direction:column;}
  .bio .kicker{order:1;}
  .bio h2{order:2;}
  .bio-foto{order:3;float:none;width:100%;max-width:320px;margin:0 0 26px;}
  .bio p{order:4;}
}

.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:20px;margin-top:10px;}
.card{
  background:rgba(255,255,255,.55);border:1px solid var(--line);
  border-radius:14px;padding:26px 24px;
}
.card h3{font-size:19px;margin-bottom:10px;}
.card p{font-size:15.5px;margin:0;line-height:1.65;}

.quote{
  border-left:3px solid var(--olive);padding:6px 0 6px 26px;
  font-family:'Marcellus',serif;font-size:clamp(19px,2.4vw,24px);
  color:var(--olive-dark);line-height:1.6;margin:30px 0;
}
.quote small{display:block;font-family:'Manrope',sans-serif;font-size:13px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--olive-soft);margin-top:12px;}

/* Standorte */
.locs{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,4vw,44px);}
@media(max-width:820px){.locs{grid-template-columns:1fr;}}
.loc{background:rgba(255,255,255,.5);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;}
.loc .loc-body{padding:26px 28px 30px;}
.loc h3{font-size:22px;margin-bottom:8px;}
.loc p{font-size:15.5px;margin-bottom:6px;}
.loc .addr{font-weight:700;color:var(--olive-dark);}

/* ============ Bildergalerie zum Durchklicken (Standorte) ============ */
.gal{
  position:relative;height:clamp(230px,26vw,290px);
  background:rgba(76,85,57,.10);overflow:hidden;
  touch-action:pan-y;user-select:none;
}
.gal-stage{position:absolute;inset:0;}
.gal-stage img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  opacity:0;transition:opacity .55s ease;cursor:pointer;
}
.gal-stage img.on{opacity:1;}
/* Pfeile links/rechts */
.gal-nav{
  position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  width:38px;height:38px;border-radius:50%;border:1px solid rgba(250,245,241,.7);
  background:rgba(58,65,41,.45);color:var(--cream);
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:background .25s,transform .25s,opacity .25s;padding:0;
}
.gal-nav svg{width:15px;height:15px;fill:currentColor;}
/* Umkehr wie bei allen Knoepfen: heller Grund, gruener Pfeil. */
.gal-nav:hover,.gal-nav:focus-visible{
  background:var(--cream);color:var(--olive);border-color:var(--cream);
}
.gal-nav.prev{left:12px;}
.gal-nav.next{right:12px;}
.gal-nav:focus-visible{outline:2px solid var(--cream);outline-offset:2px;}
/* Punkte + Zähler */
.gal-dots{
  position:absolute;left:0;right:0;bottom:11px;z-index:3;
  display:flex;justify-content:center;gap:7px;
}
.gal-dots button{
  width:8px;height:8px;padding:0;border-radius:50%;cursor:pointer;
  border:1px solid rgba(250,245,241,.85);background:rgba(58,65,41,.35);
  transition:background .25s,transform .25s;
}
.gal-dots button.on{background:var(--cream);transform:scale(1.25);}
.gal-dots button:hover,.gal-dots button:focus-visible{background:var(--cream);}
.gal-count{
  position:absolute;right:12px;bottom:10px;z-index:3;
  font-size:11.5px;font-weight:700;letter-spacing:.14em;color:var(--cream);
  background:rgba(58,65,41,.45);border-radius:999px;padding:3px 10px;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
/* sanfter Verlauf unten, damit Punkte und Zähler auf jedem Bild lesbar bleiben */
.gal::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:78px;z-index:2;
  background:linear-gradient(to top,rgba(58,65,41,.42),rgba(58,65,41,0));
  pointer-events:none;
}
@media(max-width:560px){
  .gal-nav{width:34px;height:34px;}
  .gal-count{font-size:10.5px;}
}


/* Honorar */
.fee-row{display:flex;flex-wrap:wrap;gap:20px;margin-top:26px;}
.fee{
  flex:1 1 220px;background:rgba(255,255,255,.55);border:1px solid var(--line);
  border-radius:14px;padding:26px;text-align:center;
}
.fee .big{font-family:'Marcellus',serif;font-size:34px;color:var(--olive);}
.fee .lbl{font-size:13px;letter-spacing:.18em;text-transform:uppercase;color:var(--olive-soft);margin-top:6px;}

/* Kontakt */
.contact-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin-top:24px;}
@media(max-width:640px){.contact-grid{grid-template-columns:1fr;}}
.contact-grid a{color:var(--olive-dark);text-decoration:none;font-weight:700;word-break:break-word;}
.contact-grid a:hover{text-decoration:underline;}

/* ============ Fusszeile ============
   Bis v9 stand hier eine deckende olivgruene Flaeche — der einzige Block
   der Seite, hinter dem der Wald aufhoerte. Seit dem 01.09.2026 laesst
   sie ihn durch, in derselben Handschrift wie die Kacheln darueber:
   Grundfarbe mit Restdeckung, weichgezeichneter Untergrund, feine Kante.

   Die Deckung ist NICHT frei gewaehlt. Gerechnet wurde gegen den
   hellsten Untergrund, der unter der Fusszeile vorkommen kann (Schleier
   .86 Creme ueber einer hellen Bokeh-Stelle des Fotos, rund 241/240/234):

       Deckung 1,00  -> Textkontrast 6,30 : 1
       Deckung 0,88  -> Textkontrast 4,71 : 1   <- gewaehlt
       Deckung 0,82  -> Textkontrast 4,09 : 1   (unter WCAG AA)

   Mehr Durchsicht als 0,88 kostet die Lesbarkeit — und ein Rechtstext,
   den man nicht lesen kann, ist kein Rechtstext. */
/* ============ Fusszeile ============
   Bis 01.09.2026 war das ein gruener Block: rgba(76,85,57,.88) plus
   backdrop-filter, cremefarbene Schrift darauf. Auf Ansage ist daraus
   eine helle Auflage geworden, gebaut wie der Seitenkopf — dieselbe
   Handschrift oben wie unten, kein Kasten mehr.

   DREI Dinge muessen dafuer zusammen weg, nicht nur die Hintergrundfarbe:
   1. Die Flaechenfarbe wird ein Verlauf, der oben bei NULL beginnt.
      Nur so gibt es keine Oberkante.
   2. `border-top` faellt weg — eine Linie ist eine Kante.
   3. `backdrop-filter` faellt weg. Er wirkt auf den GANZEN Kasten und
      hoert an dessen Kante hart auf; selbst hinter einem voellig
      durchsichtigen Verlauf zeichnet er die Oberkante nach. Das ist
      dieselbe Falle wie beim Radialschein des Hero, nur eine Etage
      tiefer.
   Die Schrift dreht damit von Creme auf Oliv, und das Monogramm von
   der hellen auf die dunkle Fassung (logo-mono.png in allen vier
   HTML-Dateien).

   GEMESSEN am gerenderten Bildschirmfoto, je Textzeile der dunkelste
   Grund links und rechts aussen (dort steht keine Schrift), am
   01.09.2026:
     Name --olive            6,16 : 1
     Telefon/Mail --olive    6,55 : 1
     Impressum/DSE           9,06 : 1
     Fliesstext --ink        9,51 bis 9,75 : 1
     Kleingedrucktes --ink  10,31 : 1
   Der gruene Block kam an derselben Stelle auf 4,80 bis 5,96 : 1. Die
   helle Auflage ist also nicht nur eine Formfrage, sie ist auch besser
   lesbar. Oberkante gegengeprueft: groesster Helligkeitssprung im
   Umkreis von 10 px = 0,008, also keine Kante mehr auffindbar. */
footer{
  background:linear-gradient(to bottom,
    rgba(250,245,241,0)   0%,
    rgba(250,245,241,.52) 11%,
    rgba(250,245,241,.80) 30%,
    rgba(250,245,241,.92) 100%);
  color:var(--ink);text-align:center;
  padding:56px 6vw 120px;font-size:14px;line-height:2;
}
/* Dasselbe freigestellte Monogramm wie im Kopf und jetzt auch in
   derselben Farbe: die helle Fassung logo-mono-hell.png war fuer den
   gruenen Block gedacht und ist auf der hellen Auflage unsichtbar.
   Kein Kreis, kein Schriftzug, leicht durchscheinend. */
footer .f-logo{
  width:76px;height:76px;object-fit:contain;display:block;
  margin:0 auto 16px;opacity:.86;
}
footer .f-name{font-family:'Marcellus',serif;font-size:20px;letter-spacing:.1em;color:var(--olive);}
footer a{color:var(--olive);}
/* Die Deckung .75 ist hier bewusst entfallen: sie drueckte den Kontrast
   des Kleingedruckten auf 3,4 : 1 und lag damit schon vor dem Umbau
   unter der Schwelle. Leise bleibt der Absatz ueber die Schriftgroesse,
   nicht ueber die Sichtbarkeit — deshalb steht er auch nach dem Wechsel
   auf Hell im vollen --ink und nicht in einem blassen Grau. */
footer .legal{font-size:12.5px;margin-top:18px;color:var(--ink);}

/* ============ Scroll-Reveal: die ganze Kachel auf einmal ============
   „Scroll-triggered full card reveal" — die Kachel tritt als EIN Element
   hervor. Deshalb steht .reveal ausschliesslich auf .panel und auf keinem
   Kind darin: Überschrift, Fliesstext, Zitat und Logo sind zu diesem
   Zeitpunkt längst im Dokument und werden nie einzeln angefasst. Wer hier
   später ein .reveal auf eine .card oder ein h2 setzt, zerlegt genau das.

   Weg und Dauer bewusst am ruhigen Ende: 40 px und 1,15 s. Beide
   Eigenschaften teilen Dauer und Kurve, damit sie exakt gleichzeitig
   ankommen — die weisse Kachel schiebt sich langsam aus dem Waldgrund
   nach vorn, statt zu springen. Die Kurve läuft weich aus und schwingt
   nicht über; ein Überschwinger würde bei einer 1.000 px breiten Kachel
   wie ein Ruck aussehen.

   Der .js-Vorsatz ist kein Schmuck: Ohne ihn stünde jede Kachel auf
   opacity:0, sobald JavaScript ausfällt — die Seite wäre leer. Gesetzt
   wird die Klasse als erste Zeile im <head>, also bevor gezeichnet wird. */
.js .reveal{
  opacity:0;
  transform:translateY(40px);
  transition:opacity 1.15s cubic-bezier(.22,.61,.36,1),
             transform 1.15s cubic-bezier(.22,.61,.36,1);
}
.js .reveal.in{opacity:1;transform:none;}

/* Ruhige Darstellung: Der Vorsatz .js muss hier mitgeführt werden, sonst
   gewinnt die Regel darüber nach Spezifität und die Kachel bliebe unsichtbar. */
@media(prefers-reduced-motion:reduce){
  .reveal,.js .reveal{opacity:1;transform:none;transition:none;}
  .scroll-hint{animation:none;}
}

/* ============ Audio-Player ============ */
/* Maße bewusst klein gehalten (rund ein Drittel der ursprünglichen Fläche) */
#player{
  position:fixed;left:14px;bottom:14px;z-index:200;
  background:var(--cream-panel-strong);
  border:1px solid var(--line);border-radius:999px;
  box-shadow:0 8px 26px rgba(58,65,41,.24);
  display:flex;align-items:center;gap:7px;
  padding:5px 11px 5px 5px;
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  max-width:min(260px,calc(100vw - 28px));
  transition:transform .35s ease,opacity .35s ease;
}
#player.mini .p-meta,#player.mini .p-ctrl,#player.mini .p-bar{display:none;}
#player.mini{padding:4px;gap:0;}
#pLogo{
  width:32px;height:32px;border-radius:50%;object-fit:cover;flex-shrink:0;
  box-shadow:0 3px 9px rgba(58,65,41,.25);cursor:pointer;
}
#player.playing #pLogo{animation:spin 14s linear infinite;}
@keyframes spin{to{transform:rotate(360deg)}}
.p-meta{min-width:0;line-height:1.25;}
.p-title{font-family:'Marcellus',serif;font-size:11.5px;color:var(--olive);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.p-sub{font-size:7.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--olive-soft);white-space:nowrap;}
.p-bar{width:44px;height:2px;border-radius:99px;background:rgba(76,85,57,.18);overflow:hidden;flex-shrink:0;}
.p-bar i{display:block;height:100%;width:0%;background:var(--olive);border-radius:99px;}
.p-ctrl{display:flex;align-items:center;gap:2px;flex-shrink:0;}
.p-btn{
  background:none;border:none;cursor:pointer;color:var(--olive);
  width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  transition:background .25s;padding:0;
}
/* Auch die drei Knoepfe des Players tauschen die Farben — bis v9 wurde
   hier nur ein Hauch Grau hinterlegt. */
.p-btn:hover,.p-btn:focus-visible{background:var(--olive);color:var(--cream);}
.p-btn svg{width:11px;height:11px;fill:currentColor;}
.p-btn.main{width:26px;height:26px;background:var(--olive);color:var(--cream);}
.p-btn.main:hover,.p-btn.main:focus-visible{
  background:var(--cream);color:var(--olive);box-shadow:inset 0 0 0 1px var(--olive);
}
.p-btn.main svg{width:12px;height:12px;}
@media(max-width:560px){
  .p-bar{display:none;}
  .p-title{max-width:88px;}
}

/* =====================================================================
   Unterseite Kontakt & Anfahrt
   ===================================================================== */
.page-head{
  min-height:56vh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  padding:150px 6vw 70px;
}
.page-head{position:relative;}
/* Letzter Stopp 70 % statt 78 % — dieselbe Kanten-Falle wie beim Hero,
   ausfuehrlich dort erklaert. Betrifft Kontakt, Impressum und
   Datenschutz, also alle Seitenkoepfe. */
.page-head::before{
  content:'';position:absolute;z-index:-1;
  left:50%;top:52%;transform:translate(-50%,-50%);
  width:min(1100px,96vw);height:min(560px,72vh);
  background:radial-gradient(ellipse at center,
    rgba(250,245,241,.80) 0%,
    rgba(250,245,241,.60) 40%,
    rgba(250,245,241,.26) 62%,
    rgba(250,245,241,0) 70%);
  pointer-events:none;
}
.page-head h1{
  font-family:'Cinzel','Marcellus',Georgia,serif;
  font-size:clamp(25px,4.2vw,48px);text-transform:uppercase;letter-spacing:.12em;
  color:var(--olive-dark);
  text-shadow:0 1px 0 rgba(250,245,241,.6), 0 0 22px rgba(250,245,241,.9), 0 0 56px rgba(250,245,241,.7);
}
.page-head .sub{
  margin-top:16px;font-size:clamp(13px,1.6vw,15.5px);
  letter-spacing:.2em;text-transform:uppercase;font-weight:700;
  color:var(--olive);text-shadow:0 0 18px rgba(250,245,241,.9), 0 0 40px rgba(250,245,241,.65);
}
.page-head .orte{
  margin-top:12px;color:var(--olive);font-size:15px;letter-spacing:.08em;font-weight:600;
  text-shadow:0 0 16px rgba(250,245,241,.9), 0 0 36px rgba(250,245,241,.6);
}

/* Kontaktformular */
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px 22px;margin-top:26px;}
.form-grid .full{grid-column:1/-1;}
@media(max-width:700px){.form-grid{grid-template-columns:1fr;}}
.field{display:flex;flex-direction:column;gap:7px;}
.field label{
  font-size:12.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--olive-soft);
}
.field input,.field select,.field textarea{
  font-family:'Manrope',sans-serif;font-size:16px;color:var(--ink);
  background:rgba(255,255,255,.72);
  border:1px solid var(--line);border-radius:12px;
  padding:13px 15px;line-height:1.5;
  transition:border-color .25s,box-shadow .25s,background .25s;
  width:100%;
}
.field textarea{min-height:170px;resize:vertical;}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--olive);background:#fff;
  box-shadow:0 0 0 3px rgba(76,85,57,.14);
}
.field input::placeholder,.field textarea::placeholder{color:rgba(51,57,42,.42);}
.consent{
  grid-column:1/-1;display:flex;gap:12px;align-items:flex-start;
  font-size:14.5px;line-height:1.6;color:var(--olive-dark);
}
.consent input{
  width:20px;height:20px;flex-shrink:0;margin-top:3px;accent-color:var(--olive);cursor:pointer;
}
.form-actions{
  grid-column:1/-1;display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-top:6px;
}
button.btn{border:none;cursor:pointer;font-family:'Manrope',sans-serif;}
.btn-line{
  background:transparent;color:var(--olive);border:1px solid var(--olive);
  cursor:pointer;font-family:'Manrope',sans-serif;
}
.btn-line:hover,.btn-line:focus-visible{background:var(--olive);color:var(--cream);}
.form-note{font-size:14px;color:var(--olive-soft);margin-top:16px;line-height:1.65;}
.form-msg{
  grid-column:1/-1;font-size:15px;line-height:1.6;border-radius:12px;
  padding:14px 18px;display:none;
}
.form-msg.ok{display:block;background:rgba(76,85,57,.12);border:1px solid var(--line);color:var(--olive-dark);}
.form-msg.err{display:block;background:rgba(163,88,58,.12);border:1px solid rgba(163,88,58,.3);color:#7d3f27;}

/* Standort-Block auf der Kontaktseite */
.route{display:grid;grid-template-columns:1fr 1fr;gap:clamp(26px,4vw,48px);align-items:start;}
@media(max-width:900px){.route{grid-template-columns:1fr;}}
.route img.house{
  width:100%;height:clamp(220px,26vw,300px);object-fit:cover;
  border-radius:var(--radius);box-shadow:var(--shadow);display:block;
}
.route h3{font-size:23px;margin-bottom:6px;}
.route .addr{font-weight:700;color:var(--olive-dark);font-size:16.5px;line-height:1.6;margin-bottom:18px;}
.way{margin-bottom:22px;}
.way:last-child{margin-bottom:0;}
.way h4{
  font-family:'Manrope',sans-serif;font-size:12.5px;font-weight:800;
  letter-spacing:.2em;text-transform:uppercase;color:var(--olive-soft);
  margin-bottom:9px;display:flex;align-items:center;gap:9px;
}
.way h4 svg{width:17px;height:17px;fill:currentColor;flex-shrink:0;}
.way ul{list-style:none;margin:0;padding:0;}
.way li{
  position:relative;padding-left:19px;font-size:15.5px;line-height:1.65;margin-bottom:7px;
}
.way li::before{
  content:'';position:absolute;left:0;top:10px;width:6px;height:6px;
  border-radius:50%;background:var(--olive-soft);
}
.way li strong{color:var(--olive-dark);}
.price-tag{
  display:inline-block;background:rgba(76,85,57,.10);border:1px solid var(--line);
  border-radius:999px;padding:2px 12px;font-size:13.5px;font-weight:700;
  color:var(--olive-dark);margin-left:2px;white-space:nowrap;
}
.route-links{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px;}
.route-links a{
  display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  font-size:13px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--olive);border:1px solid var(--olive);border-radius:999px;
  padding:9px 20px;transition:background .25s,color .25s;
}
.route-links a:hover,.route-links a:focus-visible{background:var(--olive);color:var(--cream);}

/* Karte mit Zwei-Klick-Ladung (DSGVO) */
.map-box{
  position:relative;margin-top:20px;border-radius:var(--radius);overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--shadow);
  background:linear-gradient(150deg,#e6e3d5,#d6d8c4);
  aspect-ratio:16/10;
}
.map-box iframe{width:100%;height:100%;border:0;display:block;}
.map-ph{
  position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:14px;text-align:center;padding:26px;
}
.map-ph p{font-size:14.5px;color:var(--olive-dark);max-width:34ch;margin:0;line-height:1.6;}
.map-ph button{
  background:var(--olive);color:var(--cream);border:1px solid var(--olive);border-radius:999px;
  padding:12px 28px;font-family:'Manrope',sans-serif;font-size:13px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;cursor:pointer;transition:background .25s;
}
/* Umkehr wie bei allen Knoepfen (siehe .btn-solid). border statt none,
   damit der Knopf beim Wechsel auf Creme seine Kontur behaelt und die
   Flaeche nicht um einen Pixel springt. */
.map-ph button:hover,.map-ph button:focus-visible{
  background:var(--cream);color:var(--olive);border-color:var(--olive);
}
.map-credit{font-size:12.5px;color:var(--olive-soft);margin-top:8px;}
.map-credit a{color:var(--olive-soft);}

.divider{height:1px;background:var(--line);margin:clamp(40px,6vw,64px) 0;}
.note-soft{
  font-size:15px;color:var(--olive-soft);line-height:1.7;
  background:rgba(255,255,255,.42);border:1px solid var(--line);
  border-radius:14px;padding:20px 24px;margin-top:26px;
}

/* =====================================================================
   Logo-Kachel: klein, unten mittig in jeder großen Sektions-Kachel
   (nicht in den kleinen Karten darin – bewusst am Dateiende, damit der
   zusätzliche Fußraum die Innenabstände des Panels überschreibt)
   ===================================================================== */
.panel{position:relative;padding-bottom:calc(clamp(38px,6vw,74px) + 56px);}
.panel::after{
  content:'';position:absolute;left:50%;bottom:clamp(22px,3vw,32px);transform:translateX(-50%);
  width:44px;height:44px;border-radius:12px;
  background:url('../img/logo-kachel.png') center/cover no-repeat;
  box-shadow:0 2px 12px rgba(58,65,41,.16);
}

/* =====================================================================
   Rechtstexte: Impressum und Datenschutzerklärung (neu am 31.08.2026)
   ---------------------------------------------------------------------
   Bewusst nüchtern gehalten: dieselbe Kachel und dieselbe Schrift wie der
   Rest der Seite, aber engere Zeilen und kleinere Überschriften – ein
   Rechtstext wird gelesen, nicht bewundert.
   ===================================================================== */

/* Fusszeile: die beiden Pflichtlinks, deutlich sichtbar über dem Kleingedruckten */
footer .f-links{margin-top:22px;display:flex;gap:26px;justify-content:center;flex-wrap:wrap;}
footer .f-links a{
  color:var(--olive-dark);font-weight:700;font-size:13.5px;
  letter-spacing:.08em;text-transform:uppercase;
  text-decoration:none;border-bottom:1px solid rgba(76,85,57,.45);padding-bottom:2px;
}
footer .f-links a:hover{border-bottom-color:var(--olive-dark);}

/* Der Textkörper eines Rechtstextes */
.rechts{max-width:78ch;}
.rechts h3{
  font-size:clamp(18px,2.1vw,22px);margin:38px 0 14px;
  padding-top:16px;border-top:1px solid var(--line);
}
.rechts h3:first-of-type{margin-top:8px;border-top:none;padding-top:0;}
.rechts h4{font-size:16px;color:var(--olive-dark);margin:22px 0 8px;}
.rechts p{margin-bottom:16px;}
.rechts ul{margin:0 0 18px 22px;}
.rechts li{margin-bottom:9px;}
.rechts a{color:var(--olive-dark);font-weight:600;}

/* Datenblock des Impressums: Bezeichnung links, Angabe rechts.
   Auf schmalen Geräten fällt es auf eine Spalte zurück. */
.daten{display:grid;grid-template-columns:minmax(150px,220px) 1fr;gap:10px 26px;margin:0 0 24px;}
.daten dt{font-weight:700;color:var(--olive-soft);font-size:13px;letter-spacing:.06em;
  text-transform:uppercase;padding-top:3px;}
.daten dd{margin:0;}
@media(max-width:640px){
  .daten{grid-template-columns:1fr;gap:2px 0;}
  .daten dt{margin-top:14px;}
}

/* OFFENE ANGABE – muss vor dem Livegang ersetzt werden.
   Absichtlich auffällig: ein Platzhalter, den man übersieht, geht
   irgendwann als Tatsache online. */
.offen{
  display:inline-block;background:#F7E9CF;color:#6A3B12;
  border:1px dashed #B07A2E;border-radius:8px;
  padding:3px 10px;font-size:14px;font-weight:700;line-height:1.5;
}
.offen-block{
  display:block;background:#F7E9CF;color:#6A3B12;
  border-left:4px solid #B07A2E;border-radius:0 8px 8px 0;
  padding:14px 18px;margin:18px 0;font-size:15px;
}
.offen-block strong{color:#5A3210;}

/* „Stand: …" unter der Überschrift und die Rückkehr nach oben */
.stand{font-size:13.5px;color:var(--olive-soft);margin-bottom:26px;}
.zurueck{margin-top:40px;padding-top:22px;border-top:1px solid var(--line);}

/* Sicherheitsnetz für lange Überschriften auf schmalen Geräten: Ein einzelnes
   langes Wort (z. B. „Datenschutzerklärung") kann sonst nicht umbrechen und
   ragt seitlich aus dem Bild. Wo es passt, ändert diese Regel nichts. */
.page-head h1{overflow-wrap:break-word;}

/* =====================================================================
   ANIMATIONS-SYSTEM v9 (01.09.2026)
   ---------------------------------------------------------------------
   Fuenf Bausteine, mehr nicht — das ist die eigentliche Entscheidung.
   Eine Therapie-Seite darf nicht wirken, als wolle sie etwas verkaufen;
   jede zusaetzliche Bewegung haette genau das getan.

     1  Soft Fade Up + Full Content Reveal .... steht bereits weiter oben
                                                (.js .reveal, seit v8)
     2  Subtle Forest Parallax ................ drei Ebenen, eine Variable
     3  Organic Mask Reveal ................... .mask-reveal, 6 Stellen
     4  Slow Ambient Motion ................... Nebel + Lichtatmung
     5  Premium Microinteractions ............. Hover, Druck, Fokus

   Gemeinsame Kurve fuer alles, was traegt: cubic-bezier(.22,.61,.36,1).
   Sie laeuft weich aus und schwingt NICHT ueber — ein Ueberschwinger ist
   der schnellste Weg, „hochwertig" in „verspielt" zu verwandeln.
   ===================================================================== */

/* ---------------------------------------------------------------------
   2 · SUBTLE FOREST PARALLAX
   ---------------------------------------------------------------------
   Drei Ebenen, exakt eine Zahl: site.js schreibt --sy (den geklemmten
   Scrollstand) an <html>, jede Ebene multipliziert ihn mit ihrem eigenen
   Faktor. Das ist der Kern von Parallaxe — gleicher Weg, verschiedene
   Geschwindigkeit — und es bedeutet einen einzigen Schreibzugriff pro
   Bild statt drei.

       hinten   Wald-Video    Faktor 0,014   (siehe #bgVideo oben)
       Mitte    Nebelbank     Faktor 0,075
       vorn     Blattwerk     Faktor 0,340

   Die Faktoren sind bewusst um eine Groessenordnung kleiner als bei den
   ueblichen Parallax-Seiten. Der Effekt soll Tiefe andeuten, nicht
   auffallen: bei 800 px Scrollweg wandert das Video 11 px.
   --------------------------------------------------------------------- */
.fog{
  position:absolute;inset:-14% -8%;pointer-events:none;
}
/* Zwei Ebenen ineinander, weil zwei Dinge gleichzeitig transformieren:
   aussen der Scroll-Versatz, innen die Dauerbewegung. Ein Element kann
   nur EIN transform tragen — der Versuch, beides in eine Regel zu
   schreiben, laesst die Keyframes den Scrollwert ueberschreiben. */
.fog>i{display:block;position:absolute;inset:0;}

#fogA{transform:translate3d(0,calc(var(--sy,0) * -0.075px),0);}
#fogA>i{
  background:
    radial-gradient(60% 40% at 22% 62%, rgba(250,245,241,.42) 0%, rgba(250,245,241,0) 70%),
    radial-gradient(46% 32% at 74% 38%, rgba(250,245,241,.30) 0%, rgba(250,245,241,0) 72%);
  animation:nebelA 96s ease-in-out infinite;
}
/* Ebene B bekommt bewusst KEINEN Scroll-Faktor: damit bleiben es drei
   scroll-gekoppelte Ebenen. Sie treibt nur. */
#fogB>i{
  background:
    radial-gradient(54% 36% at 54% 78%, rgba(250,245,241,.34) 0%, rgba(250,245,241,0) 74%);
  animation:nebelB 138s ease-in-out infinite;
}

#canopy{
  position:fixed;left:-3%;right:-3%;top:0;z-index:-1;
  height:clamp(180px,30vh,380px);
  background:url('../img/canopy.svg') top center/cover no-repeat;
  /* Gemessen am 01.09.2026 im Browser, zuerst gegen das laufende
     Wald-Video: bei .30 ging die Ebene im Blattwerk des Videos unter,
     bei .45 wirkte sie wie ein weicher Rahmen aus Zweigen — .42 war der
     Wert dazwischen.

     Nach dem Wechsel auf das Foto am selben Tag neu bewertet und auf
     .32 zurueckgenommen: Der neue Hintergrund ist oben deutlich heller,
     und auf hellem Grund liest sich dieselbe Deckung als dunkler Fleck,
     nicht als Blattwerk. Die Zahl gehoert zum Hintergrund, nicht zur
     Ebene — wer den Hintergrund wechselt, muss sie neu ansehen.

     Genau das am 01.09.2026 dreimal getan: .32 gegen das Waldfoto, .18
     gegen den goldenen Klee, .14 gegen den gruenen (der bringt oben
     selbst ein dunkles Bokeh mit, zwei unscharfe dunkle Ebenen
     uebereinander geben Schlieren statt Tiefe).

     HIER steht wieder .42 — der urspruengliche Wert, gemessen gegen
     GENAU DIESES laufende Video. Das ist kein Rueckschritt, sondern die
     Konsequenz derselben Regel: die Zahl gehoert zum Hintergrund. Wer
     diese Fassung auf ein Foto umstellt, muss sie erneut ansehen.
     Der Zwilling v11 steht aus demselben Grund auf .14.

     14.09.2026, vierte Bewertung — jetzt .20: Das neue Video bringt am
     oberen Bildrand SELBST dichtes Laubdach mit (das alte zeigte dort
     offenen Nebelwald). Damit gilt hier genau der Fall, der beim gruenen
     Klee schon einmal auftrat: zwei unscharfe dunkle Ebenen uebereinander
     geben keine Tiefe, sondern Schlieren. Die gezeichnete Ebene bleibt
     drin, weil sie die Zweige beim Scrollen schneller wegziehen laesst als
     das Video dahinter — sie darf nur nicht mehr mitreden. */
  opacity:.20;
  pointer-events:none;
  /* max() statt clamp(): die Werte sind negativ, max() ist hier die
     UNTERE Schranke. Ohne sie liefe die Ebene bei langen Seiten hunderte
     Pixel weit ins Nichts. */
  transform:translate3d(0,max(-330px,calc(var(--sy,0) * -0.34px)),0);
  /* Die Zweige laufen nach unten aus, statt an einer Kante zu enden —
     sonst sieht man, dass es ein Rechteck ist. */
  -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 48%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(to bottom,#000 0%,#000 48%,rgba(0,0,0,0) 100%);
}

/* ---------------------------------------------------------------------
   4 · SLOW AMBIENT MOTION
   ---------------------------------------------------------------------
   Zwei Nebelbaenke und die Lichtatmung hinter Hero und Seitenkopf.
   Alle drei laufen ueber Minuten statt Sekunden und bewegen ausschliess-
   lich transform und opacity — beides braucht der Browser nicht neu zu
   zeichnen. Gedacht sind sie zum Uebersehen: wer die Bewegung bemerkt,
   sieht sie zum letzten Mal bewusst.
   --------------------------------------------------------------------- */
@keyframes nebelA{
  0%,100%{transform:translate3d(-2.5%,0,0)     scale(1.02);opacity:.82;}
  50%    {transform:translate3d(3.5%,-1.6%,0)  scale(1.09);opacity:1;}
}
@keyframes nebelB{
  0%,100%{transform:translate3d(2%,1.2%,0)     scale(1.05);opacity:.70;}
  50%    {transform:translate3d(-3%,-1%,0)     scale(1);   opacity:.96;}
}
/* SLOW IMAGE ZOOM (Vorgabe: 1–5 %, sehr langsam, kein aggressiver Zoom)
   ---------------------------------------------------------------------
   132 Sekunden fuer einen vollen Zug, 3,7 % Weg (1,005 -> 1,042). Das
   sind rund 0,03 % pro Sekunde: Wer eine Minute auf die Seite schaut,
   sieht ein anderes Bild als beim Ankommen, kann aber nicht sagen, wann
   es sich bewegt hat. Genau das ist gemeint.

   Der Ausgangswert ist 1,005 und nicht 1: Bei exakt 1 stuende das Bild
   an einem Ende der Bewegung fuer einen Moment still — bei einer so
   langsamen Kurve faellt das als Stocken auf.

   Der Bezugspunkt (transform-origin 52%/62%) liegt auf dem Zweig mit
   den Ahornblaettern. Ein Zoom auf die Bildmitte haette den Zweig aus
   dem Ausschnitt geschoben. */
/* NICHT IN GEBRAUCH in dieser Video-Fassung — es gibt kein #bgFoto,
   das die Regel aufrufen koennte. Sie bleibt stehen (Loesch-Schutz und
   weil der Zwilling v11 sie braucht): Wer diese Fassung je auf ein Foto
   umstellt, hat den langsamen Zoom damit sofort wieder. */
@keyframes bildAtmen{
  0%,100%{transform:scale(1.005);}
  50%    {transform:scale(1.042);}
}

/* Der helle Schein hinter den grossen Namenszuegen atmet: 84 Sekunden
   fuer einen Zug, 5,5 % Groessenaenderung. Er traegt die gruene Schrift
   ueber dem Foto — deshalb darf er nie so weit zurueckgehen, dass die
   Schrift auf einer dunklen Stelle steht. Untere Grenze: opacity .86. */
.hero::before,.page-head::before{
  animation:lichtAtmen 84s ease-in-out infinite;
}
@keyframes lichtAtmen{
  0%,100%{transform:translate(-50%,-50%) scale(1);      opacity:.86;}
  50%    {transform:translate(-50%,-51%) scale(1.055);  opacity:1;}
}

/* ---------------------------------------------------------------------
   3 · ORGANIC MASK REVEAL
   ---------------------------------------------------------------------
   Sechs Bilder treten nicht ein, sondern gehen auf: zwei weiche, gegen-
   einander versetzte Lichtflecken wachsen ueber das Bild, wie Licht, das
   zwischen Baeumen aufkommt. Zwei statt einem, weil ein einzelner Kreis
   als Kreis erkennbar bleibt; zwei versetzte ergeben eine unregelmaessige
   Form, die keine geometrische Figur mehr ist.

   ENTSCHEIDEND: Ausgeloest wird das NICHT von einem eigenen Beobachter
   auf dem Bild, sondern von der .in-Klasse der Kachel darueber. Damit
   gibt es weiterhin genau EINEN Ausloeser pro Kachel — die Maske geht
   in derselben Millisekunde auf, in der die Kachel sich hebt. Ein
   zweiter Beobachter haette Stagger erzeugt, und genau das soll die
   Seite nicht tun. `.reveal` bleibt deshalb ausschliesslich auf `.panel`.

   Ohne JavaScript fehlt `.js` — dann gibt es keine Maske und das Bild
   steht schlicht da. Dieselbe Absicherung wie beim Kachel-Reveal.
   --------------------------------------------------------------------- */
.js .reveal .mask-reveal{
  -webkit-mask-image:radial-gradient(closest-side,#000 55%,rgba(0,0,0,0) 100%),
                     radial-gradient(closest-side,#000 48%,rgba(0,0,0,0) 100%);
          mask-image:radial-gradient(closest-side,#000 55%,rgba(0,0,0,0) 100%),
                     radial-gradient(closest-side,#000 48%,rgba(0,0,0,0) 100%);
  -webkit-mask-position:36% 44%, 68% 60%;
          mask-position:36% 44%, 68% 60%;
  -webkit-mask-repeat:no-repeat;
          mask-repeat:no-repeat;
  -webkit-mask-size:0% 0%, 0% 0%;
          mask-size:0% 0%, 0% 0%;
  /* BLUR TO FOCUS (dazu am 01.09.2026): Das Bild kommt nicht nur auf,
     es stellt sich auch scharf — 9 px Unschaerfe laufen auf 0 zurueck.
     Beides teilt denselben Ausloeser und dieselbe Kurve, laeuft aber
     100 ms laenger: Die Form ist dann schon vollstaendig da, waehrend
     die Schaerfe noch ankommt. Umgekehrt saehe es aus wie ein Bild,
     das zu spaet geladen hat.
     saturate startet bei .90, weil ein weichgezeichnetes Bild sonst
     farbiger wirkt als das scharfe daneben. */
  filter:blur(9px) saturate(.90);
  transition:-webkit-mask-size 1.5s cubic-bezier(.22,.61,.36,1),
                     mask-size 1.5s cubic-bezier(.22,.61,.36,1),
                        filter 1.6s cubic-bezier(.22,.61,.36,1);
}
/* 360 % ist gerechnet, nicht geschaetzt: bei dieser Groesse liegt der
   voll deckende Kern (55 % von closest-side) in jedem Seitenverhaeltnis
   ueber der gesamten Bildflaeche. Kleinere Werte lassen je nach Format
   eine helle Ecke stehen. */
.js .reveal.in .mask-reveal{
  -webkit-mask-size:360% 360%, 300% 300%;
          mask-size:360% 360%, 300% 300%;
  filter:blur(0) saturate(1);
}

/* ---------------------------------------------------------------------
   5 · PREMIUM MICROINTERACTIONS
   ---------------------------------------------------------------------
   Die Regel dahinter: Bewegung nur so weit, dass die Hand sie spuert,
   nicht so weit, dass das Auge sie sucht. Drei Pixel Hub, kein Farb-
   sprung, kein Zoom auf Text.
   --------------------------------------------------------------------- */

/* Anheben nur dort, wo tatsaechlich ein Zeiger schwebt. Auf dem
   Touchgeraet bleibt ein :hover sonst nach dem Antippen haengen —
   die Kachel steht dann dauerhaft schief. */

/* ---------------------------------------------------------------------
   VORGABE RB 01.09.2026: „Die Kacheln, die kein Button sind => ohne
   Pop-up Effekt" und „keinen Pop-out-Effekt bei den Bildern, die sollen
   einfach immer bleiben, wo sie sind."

   Damit faellt die Trennlinie neu, und zwar nach FUNKTION statt nach
   Aussehen: Bewegung beim Darueberfahren bekommt nur noch, was auf
   einen Klick antwortet — Knoepfe, Routenlinks, der Karten-Knopf, die
   Galeriepfeile, die Fusszeilen-Links. Alles, was blosser Inhalt ist,
   steht still: die Karten (.card), die Honorarfelder (.fee), die
   Standortkacheln (.loc), die Hinweiskaesten (.note-soft) und saemtliche
   Bilder (Portraet, Praxisfotos, Zwei-Spalter).

   Das ist mehr als Geschmack. Ein Element, das sich beim Darueberfahren
   hebt, verspricht Klickbarkeit. Bei einer Kachel, die nirgendwohin
   fuehrt, ist dieses Versprechen falsch — der Besucher klickt und es
   passiert nichts.

   Bis v11 hoben sich diese Elemente um 3 px und bekamen einen tieferen
   Schatten. Die Regeln stehen unten auskommentiert, nicht geloescht.
   Was BLEIBT: die Uebergangsdauern. Sie kosten nichts, solange keine
   Zustandsregel sie ausloest, und muessten beim Wiedereinschalten
   sonst mitgesucht werden.
   --------------------------------------------------------------------- */
@media (hover:hover) and (pointer:fine){
  .card,.fee,.loc,.note-soft{
    transition:transform .5s cubic-bezier(.22,.61,.36,1),
               box-shadow .5s ease, border-color .5s ease,
               background-color .5s ease;
  }
  /* ENTFERNT am 01.09.2026 (Vorgabe RB) — Kacheln ohne Ziel stehen still:
  .card:hover,.fee:hover,.note-soft:hover{
    transform:translateY(-3px);
    box-shadow:0 14px 34px rgba(58,65,41,.13);
    border-color:rgba(76,85,57,.32);
    background-color:rgba(255,255,255,.72);
  }
  .loc:hover{
    transform:translateY(-3px);
    box-shadow:0 18px 44px rgba(58,65,41,.15);
    border-color:rgba(76,85,57,.30);
  }
  */
  .btn-solid:hover{box-shadow:0 12px 28px rgba(58,65,41,.26);}
  .btn-line:hover,.btn-ghost:hover{box-shadow:0 10px 24px rgba(58,65,41,.18);}
  .route-links a:hover{--mgl:-2px;box-shadow:0 10px 22px rgba(58,65,41,.16);}
  .map-ph button:hover{--mgl:-2px;box-shadow:0 12px 26px rgba(58,65,41,.24);}
  .gal-nav:hover{transform:translateY(-50%) scale(1.07);}
  /* War #fff und stammt aus der Zeit des gruenen Blocks — auf der hellen
     Auflage waere Weiss auf Creme unsichtbar (01.09.2026). */
  footer .f-links a:hover{color:var(--ink);}
  .bio-foto,.two-col img,.route img.house{
    transition:transform .6s cubic-bezier(.22,.61,.36,1), box-shadow .6s ease;
  }
  /* ENTFERNT am 01.09.2026 (Vorgabe RB) — Bilder bleiben, wo sie sind:
  .bio-foto:hover,.two-col img:hover,.route img.house:hover{
    transform:translateY(-3px);
    box-shadow:0 24px 60px rgba(58,65,41,.20);
  }
  */
}

/* Zweites Netz gegen das Wiederauftauchen: Der Knopf mit der Telefon-
   nummer traegt .btn und wuerde die .btn-line-Umkehr sonst erben. Er ist
   ausdruecklich KEIN Knopf (Vorgabe RB) — er zeigt nur die Nummer.
   Deshalb hier alles zurueckgenommen, was Klickbarkeit verspricht:
   Farbumkehr, Schatten, Hub, Zeigerhand. Die Magnetik nimmt ihm site.js
   ab (Selektor `.btn:not(.btn-static)`), denn sie ist JavaScript und
   liesse sich hier nicht abschalten. */
.btn-static{
  display:inline-flex;align-items:center;gap:11px;
  cursor:default;
  /* Ziffern brauchen weniger Sperrung als Versalien — .14em ist fuer die
     Wortknoepfe gerechnet und liesse eine Telefonnummer auseinanderfallen. */
  letter-spacing:.06em;
  font-variant-numeric:tabular-nums;
  --mgl:0px;--mgs:1;
}
.btn-static:hover,.btn-static:focus,.btn-static:focus-visible{
  background:transparent;color:var(--olive);border-color:var(--olive);
  box-shadow:none;
}
/* Die Linienstaerke ist so gewaehlt, dass der Hoerer neben der 700er
   Schrift gleich schwer wirkt — duenner sieht er nach Fremdkoerper aus. */
.btn-static .btn-ico{
  width:17px;height:17px;flex:0 0 auto;
  fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
}

/* Der Methode-Abschnitt hat seit dem 01.09.2026 keine Karten mehr und
   endet mit Fliesstext. Der Fussraum der Kachel ist aber fuer die
   Logo-Kachel gerechnet (siehe unten, .panel::after): clamp + 56 px.
   Ohne Karten steht davon zu viel als Leerflaeche da. .panel-schlank
   nimmt die Zugabe auf das Mass zurueck, das das Logo tatsaechlich
   braucht — 44 px hoch, 22 bis 32 px ueber der Unterkante. */
.panel-schlank{padding-bottom:calc(clamp(38px,6vw,74px) * .55 + 56px);}
.route-links a,.map-ph button,footer .f-links a{
  transition:transform .42s cubic-bezier(.22,.61,.36,1),
             background-color .42s ease, color .42s ease,
             border-color .42s ease, box-shadow .42s ease;
}

/* Der Druckpunkt gilt auf JEDEM Geraet — er ist die einzige Rueckmeldung,
   die ein Finger bekommt, und deshalb wichtiger als jeder Hover. */
/* Der Druckpunkt setzt den Hub zurueck und drueckt zusammen — beides
   ueber Variablen, damit die Magnetik daneben bestehen bleibt. */
.btn:active,.map-ph button:active,.route-links a:active{
  --mgl:0px;--mgs:.972;
}
#skipBtn:active{transform:translateX(-50%) scale(.972);}
.gal-nav:active{transform:translateY(-50%) scale(.92);}
.gal-dots button:active{transform:scale(.86);}
.p-btn:active{transform:scale(.9);}
.p-btn{transition:background .25s, transform .25s cubic-bezier(.22,.61,.36,1);}

/* Tastaturbedienung: ein sichtbarer, ruhiger Ring statt des Browser-
   Standards. Ohne :focus-visible saehe ihn auch jeder Mausklick. */
a:focus-visible,button:focus-visible,.btn:focus-visible,
.gal:focus-visible,summary:focus-visible{
  outline:2px solid var(--olive);
  outline-offset:3px;
}
/* Diese Ausnahme hat sich am 01.09.2026 erledigt und ist deshalb
   auskommentiert statt entfernt: Sie hat den olivgruenen Fokusrahmen
   gegen einen cremefarbenen getauscht, weil Oliv auf dem gruenen Block
   nicht zu sehen war. Die Fusszeile ist jetzt hell — damit ist der
   cremefarbene Rahmen der unsichtbare, und der Regelfall zwei Zeilen
   darueber ist wieder der richtige. Kehrt die dunkle Fusszeile je
   zurueck, gehoert diese Zeile mit ihr zurueck.
footer a:focus-visible{outline-color:#fdfbf9;} */

/* Die Unterstreichung im Kontaktblock sprang bisher hart an. Ueber die
   Farbe der Linie laesst sie sich weich einblenden — der Text bleibt
   dabei an derselben Stelle stehen. */
.contact-grid a{
  text-decoration:underline;
  text-decoration-color:transparent;
  text-decoration-thickness:1.5px;
  text-underline-offset:4px;
  transition:text-decoration-color .4s ease, color .4s ease;
}
.contact-grid a:hover{text-decoration-color:currentColor;}

/* Menue-Unterstreichung auf dieselbe ruhige Kurve wie alles andere.
   Dazu ein Farbwechsel: die Unterstreichung allein ist 1,5 px hoch und
   im Augenwinkel nicht zu sehen. */
nav a::after{transition:width .45s cubic-bezier(.22,.61,.36,1);}
nav a:hover,nav a:focus-visible{color:var(--olive-dark);}

/* =====================================================================
   12 · CURSOR-EFFEKTE  (nur Desktop, nur bei feinem Zeiger)
   ---------------------------------------------------------------------
   Drei Stueck, alle in der schwaechsten Stufe, die ueberhaupt noch
   wirkt — und alle drei ausschliesslich dort, wo es einen echten
   Mauszeiger gibt. Auf dem Touchgeraet entsteht KEIN einziges dieser
   Elemente: site.js legt sie nur an, wenn
   (hover:hover) and (pointer:fine) zutrifft und der Besucher keine
   ruhige Darstellung angefordert hat.

     · Cursor Spotlight ... weicher Lichtfleck, der ueber dem Waldfoto
                            mitgeht (Deckung 14 %, unter dem Inhalt)
     · Cursor Follow ...... ein einzelner weicher Punkt, der dem Zeiger
                            nachlaeuft und beim Stillstand verblasst
     · Magnetic Button .... Knoepfe neigen sich bis zu 4 px zum Zeiger

   Ausdruecklich NICHT gebaut: dauerhafte Cursor-Trails und Partikel.
   Beide standen als Verbot in der Vorgabe, und beide waeren auf einer
   Psychotherapie-Seite auch ohne Verbot falsch.

   Kostenseite: Alle drei bewegen ausschliesslich transform und opacity.
   Waehrend der Mausbewegung wird kein Layout gelesen — die Positionen
   der Knoepfe liegen zwischengespeichert und werden nur bei Scrollen
   und Groessenaenderung neu bestimmt. --------------------------------- */

/* Der Lichtfleck liegt zwischen Schleier und Inhalt: er hellt den Wald
   auf, aber niemals den Text darueber. Feste Groesse statt eines
   Verlaufs ueber das ganze Fenster — so wird bei jeder Bewegung nur
   verschoben und nichts neu gezeichnet. */
#spot{
  position:fixed;left:0;top:0;z-index:-1;pointer-events:none;
  width:44vmax;height:44vmax;margin:-22vmax 0 0 -22vmax;
  background:radial-gradient(closest-side,
    rgba(250,245,241,.14) 0%,
    rgba(250,245,241,.07) 46%,
    rgba(250,245,241,0)   100%);
  opacity:0;transition:opacity 1.1s ease;
  transform:translate3d(var(--zx,50vw),var(--zy,50vh),0);
  will-change:transform;
}
/* Der Punkt laeuft dem Zeiger nach — mit Absicht traege (Faktor 0,14 je
   Bild, also rund 12 Bilder Rueckstand). Er ist weich, ohne Rand und so
   schwach, dass er nicht als zweiter Zeiger gelesen wird. Ueber
   Knoepfen und Links waechst er auf das Anderthalbfache. */
#zeigerpunkt{
  position:fixed;left:0;top:0;z-index:400;pointer-events:none;
  width:26px;height:26px;margin:-13px 0 0 -13px;border-radius:50%;
  background:radial-gradient(closest-side,
    rgba(76,85,57,.20) 0%, rgba(76,85,57,.10) 60%, rgba(76,85,57,0) 100%);
  opacity:0;
  transform:translate3d(var(--px,-100px),var(--py,-100px),0) scale(var(--ps,1));
  transition:opacity .55s ease;
  will-change:transform;
}
/* Sichtbar nur, solange sich der Zeiger bewegt oder ruht — nach zwei
   Sekunden Stillstand verschwindet er. Ein Punkt, der dauerhaft auf dem
   Bildschirm steht, wird zum Fleck auf der Scheibe. */
body.zeiger-an #spot{opacity:1;}
body.zeiger-an #zeigerpunkt{opacity:1;}
body.zeiger-ruht #zeigerpunkt{opacity:0;}

/* MAGNETIC BUTTON — die Verschiebung kommt aus zwei eigenen Variablen,
   die site.js schreibt (--mgx/--mgy). Sie steht in DERSELBEN
   transform-Angabe wie der Hover-Hub (--mgl) und der Druckpunkt (--mgs).
   Das ist kein Stil, sondern Notwendigkeit: Ein Element kann nur EIN
   transform tragen. Wer hier spaeter ein zweites `transform:translateY()`
   in eine :hover-Regel schreibt, loescht die Magnetik still aus.
   Deshalb setzen alle Zustandsregeln unten Variablen statt transform. */
.btn,.route-links a,.map-ph button{
  transform:translate3d(var(--mgx,0px),calc(var(--mgy,0px) + var(--mgl,0px)),0)
            scale(var(--mgs,1));
}
/* Kuerzere Dauer nur fuer die Bewegung: 0,42 s waren richtig, solange
   sich der Knopf erst beim Hover hob. Ein Knopf, der dem Zeiger mit
   0,42 s Verzoegerung entgegenkommt, wirkt defekt. Die Farben behalten
   ihre ruhigen 0,42 s. */
.btn,.route-links a,.map-ph button{
  transition:transform .22s cubic-bezier(.22,.61,.36,1),
             background-color .42s ease,
             color .42s ease,
             border-color .42s ease,
             box-shadow .42s ease;
}

/* =====================================================================
   RUHIGE DARSTELLUNG (prefers-reduced-motion)
   ---------------------------------------------------------------------
   Dieser Block MUSS der letzte der Datei bleiben. Jede Regel, die
   danach kaeme, wuerde ihn bei gleicher Spezifitaet schlagen und den
   Fallback still aushebeln — genau die Falle, die in v8 schon einmal
   zugeschnappt ist (.reveal gegen .js .reveal).

   Abgeschaltet wird hier alles, was sich von selbst bewegt. Was bleibt:
   die Seite, vollstaendig sichtbar, mit allen Bildern.
   ===================================================================== */
@media (prefers-reduced-motion:reduce){
  /* Kachel-Reveal und Masken: alles sofort da. filter:none MUSS hier
     stehen — ohne die Zeile bliebe das Bild bei ruhiger Darstellung
     dauerhaft mit 9 px Unschaerfe liegen, weil der Uebergang, der sie
     wegnimmt, hier abgeschaltet ist. */
  .reveal,.js .reveal{opacity:1;transform:none;transition:none;}
  .js .reveal .mask-reveal,.js .reveal.in .mask-reveal{
    -webkit-mask-image:none;mask-image:none;transition:none;
    filter:none;
  }

  /* Dauerbewegungen aus. Der langsame Bildzoom (#bgFoto>i) steht hier
     bewusst NICHT: in dieser Fassung gibt es kein Bild, das zoomen
     koennte — das Video wird weiter unten ganz ausgeblendet. */
  #fogA>i,#fogB>i,.hero::before,.page-head::before,
  #player.playing #pLogo,.scroll-hint{animation:none;}

  /* Parallax aus — die Ebenen stehen still, bleiben aber sichtbar */
  #fogA{transform:none;}
  #bgVideo{transform:translate(-50%,-50%) scale(1.08) translateZ(0);}
  /* Das Blattwerk wird von fixed auf absolute gestellt: es bewegt sich
     dann relativ zur Seite ueberhaupt nicht mehr, scrollt aber oben
     natuerlich weg, statt ueber allem stehen zu bleiben. */
  #canopy{position:absolute;transform:none;}

  /* Ein laufendes Hintergrund-Video ist Dauerbewegung. Statt seiner das
     Standbild, das ohnehin im Paket liegt — der Wald bleibt, die
     Bewegung geht. site.js holt das Video in diesem Fall gar nicht
     erst, das spart nebenbei 4,8 MB.
     (In der Foto-Fassung v11 stehen diese beiden Zeilen nicht: dort ist
     der Hintergrund ohnehin ein Standbild.)

     Das Standbild ist seit 14.09.2026 ein Einzelbild AUS DEM LAUFENDEN
     VIDEO (Sekunde 298 der Quelle, also die Mitte des Loops) statt des
     alten wald.jpg. Grund: Wer die Seite mit ruhiger Darstellung oeffnet,
     soll denselben Ort sehen wie alle anderen — vorher zeigte dieser Zweig
     einen anderen Wald als das Video. wald.jpg bleibt im Paket, es steht
     weiterhin als Bild im Waldbaden-Abschnitt. */
  #bgVideo{display:none;}
  #bgWrap{background:url('../img/waldweg-standbild.jpg') center/cover no-repeat;}

  /* Die drei Cursor-Effekte werden von site.js in diesem Fall gar nicht
     erst angelegt; die Regeln hier sind das zweite Netz, falls jemand
     die Einstellung bei geoeffneter Seite umstellt. */
  #spot,#zeigerpunkt{display:none !important;}

  /* Mikro-Interaktionen: Farbe und Schatten duerfen bleiben, Bewegung nicht.
     transform:none allein genuegt seit v10 nicht mehr — Hub, Druckpunkt
     und Magnetik laufen ueber Variablen, die zurueckgesetzt werden
     muessen, sonst blieben sie in der zusammengesetzten Angabe stehen. */
  .card,.fee,.loc,.note-soft,.btn,.gal-nav,.route-links a,
  .map-ph button,.p-btn,footer .f-links a,.bio-foto,.two-col img,
  .route img.house{transition:none;}
  .btn,.route-links a,.map-ph button{--mgx:0px;--mgy:0px;--mgl:0px;--mgs:1;}
  .card:hover,.fee:hover,.loc:hover,.note-soft:hover,.btn:hover,
  .route-links a:hover,.map-ph button:hover,.bio-foto:hover,
  .two-col img:hover,.route img.house:hover,
  .btn:active,.map-ph button:active,.route-links a:active,
  .gal-dots button:active,.p-btn:active{transform:none;}
  #skipBtn:hover,#skipBtn:active{transform:translateX(-50%);}
  .gal-nav:hover,.gal-nav:active{transform:translateY(-50%);}
  .gal-stage img{transition:none;}
}
