@charset "utf-8";
/* ==========================================================================
   Haar Atelier Jever
   Eine Marke, eine Idee: der Übergang.
   ========================================================================== */

/* ---- Schriften, selbst gehostet, kein externer Aufruf ------------------- */
@font-face{font-family:'HAJ Display';src:url(../fonts/hj-display-regular.woff) format('woff');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'HAJ Display';src:url(../fonts/hj-display-italic.woff) format('woff');font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'HAJ Text';src:url(../fonts/hj-text-regular.woff) format('woff');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'HAJ Text';src:url(../fonts/hj-text-bold.woff) format('woff');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'HAJ Mono';src:url(../fonts/hj-mono-regular.woff) format('woff');font-weight:400;font-style:normal;font-display:swap}

/* ---- Tokens ------------------------------------------------------------- */
:root{
  --canvas:#EBEAE6;
  --canvas-2:#E2E0D9;
  --panel:#F6F5F1;
  --ink:#15171A;
  --ink-2:#3B3E43;
  --text-2:#5E5D57;
  --line:#D3CFC6;
  --line-strong:#7A756B;
  --accent:#8A5A2B;
  --accent-hover:#6E4620;
  --accent-soft:#C6A275;
  --dark:#0E1013;
  --dark-2:#171B20;
  --on-dark:#F3F0E9;
  --on-dark-2:#B9B4A9;

  --display:'HAJ Display',Georgia,'Times New Roman',serif;
  --text:'HAJ Text',system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:'HAJ Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;

  --e-out:cubic-bezier(.22,.61,.36,1);
  --e-soft:cubic-bezier(.33,.02,.15,1);

  --pad:clamp(1.25rem,5vw,5.5rem);
  --maxw:1360px;
  --tshadow:0 1px 2px rgba(5,5,10,.95),0 3px 12px rgba(5,5,10,.78),0 10px 44px rgba(5,5,10,.8);
}

/* ---- Grundgerüst -------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html,body{overflow-x:hidden;overflow-x:clip}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--canvas);color:var(--ink);
  font:400 1.0625rem/1.62 var(--text);
  font-feature-settings:"kern" 1;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,video,svg{max-width:100%;height:auto;display:block}
a{color:inherit}
button{font:inherit;color:inherit}
h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}
/* Sicherheitsnetz für sehr schmale Geräte: ein einzelnes langes Wort bricht
   notfalls um, statt aus seinem Kasten zu laufen. Greift nur dort, wo es
   sonst wirklich nicht passt. */
h1,h2,h3,h4,p,li,dt,dd,summary,blockquote,cite{overflow-wrap:break-word}
/* Hält ein Wortpaar zusammen, ohne den Wortabstand zu verändern. Ein
   geschütztes Leerzeichen täte dasselbe, läuft in der Display-Schrift aber
   sichtbar breiter als ein normales — und genau in den Überschriften, in
   denen es gebraucht wird, fällt das auf. */
.nb{white-space:nowrap}
ul,ol{margin:0;padding:0;list-style:none}

:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
.on-dark :focus-visible,.hero :focus-visible{outline-color:#E8C79A}

::selection{background:#E3CBA4;color:#15171A}

/* Sprungziele landen unterhalb der festen Navigation, nie dahinter. */
[id]{scroll-margin-top:5.25rem}

.skip{
  position:fixed;left:1rem;top:-4rem;z-index:200;
  background:var(--ink);color:var(--canvas);padding:.7rem 1.1rem;border-radius:2px;
  font:400 .875rem var(--text);transition:top .25s var(--e-out)
}
.skip:focus{top:1rem}

.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---- Die Umgebung: ein Ort, keine gestapelten Abschnitte ---------------- */
.env{position:fixed;inset:0;z-index:0;pointer-events:none}
.env .halo{
  position:absolute;left:50%;top:38%;width:min(140vw,1500px);aspect-ratio:1;
  transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(198,162,117,.16) 0%,rgba(198,162,117,.06) 38%,rgba(198,162,117,0) 68%);
  animation:haloDrift 96s var(--e-soft) -22s infinite alternate;
}
@keyframes haloDrift{
  0%{transform:translate(-52%,-54%) scale(1)}
  100%{transform:translate(-46%,-44%) scale(1.14)}
}
.env .grain{
  position:absolute;inset:-40px;opacity:.4;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}
main,header,footer{position:relative;z-index:1}

/* ---- Navigation --------------------------------------------------------- */
.nav{
  position:fixed;inset:0 0 auto;z-index:60;
  display:flex;align-items:center;gap:1.5rem;
  padding:1.05rem var(--pad);
  transition:background .45s var(--e-out),backdrop-filter .45s var(--e-out),
             padding .45s var(--e-out),border-color .45s var(--e-out);
  border-bottom:1px solid transparent;
}
.nav.solid{
  background:rgba(235,234,230,.86);backdrop-filter:blur(14px) saturate(1.2);
  border-bottom-color:var(--line);padding-top:.7rem;padding-bottom:.7rem;
}
.brand{display:flex;align-items:center;gap:.65rem;text-decoration:none;flex:0 0 auto}
.brand svg{width:30px;height:30px;flex:0 0 auto;transition:transform .5s var(--e-out)}
.brand:hover svg{transform:rotate(-8deg)}
.brand b{font:400 1.0625rem/1 var(--display);letter-spacing:.03em;display:block}
.brand span{font:400 .5625rem/1 var(--mono);letter-spacing:.24em;text-transform:uppercase;color:var(--text-2);display:block;margin-top:.28rem}
.nav .links{display:flex;gap:1.65rem;margin-left:auto;align-items:baseline}
.nav .links a{
  font:400 .875rem var(--text);text-decoration:none;color:var(--ink-2);
  position:relative;padding-bottom:2px;transition:color .3s var(--e-out)
}
.nav .links a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--accent);
  transform:scaleX(0);transform-origin:left;transition:transform .42s var(--e-out)
}
.nav .links a:hover{color:var(--ink)}
.nav .links a:hover::after{transform:scaleX(1)}
.nav .links a[aria-current="true"]{color:var(--ink)}
.nav .links a[aria-current="true"]::after{transform:scaleX(1)}
.nav:not(.solid) .links a[aria-current="true"]{color:#fff}
/* Auf den Rechtstexten gibt es keine Linkleiste; ohne diese Regel klebte
   der Knopf dort direkt an der Marke, statt rechts außen zu stehen. */
.nav .cta{margin-left:auto}
.nav .links + .cta{margin-left:1.4rem}

/* ---- Menü für schmale Fenster ------------------------------------------
   Unterhalb von 900 Pixeln weicht die Linkleiste einem Knopf. Ohne ihn
   stünde die Seite auf dem Telefon ganz ohne Navigation da: ein Besucher
   käme nur durch Scrollen an die Preise oder den Standort.
   ------------------------------------------------------------------------ */
.navtoggle{
  display:none;margin-left:.55rem;flex:0 0 auto;
  width:44px;height:44px;padding:0;border:1px solid transparent;border-radius:999px;
  background:transparent;cursor:pointer;place-items:center;
  transition:background .3s var(--e-out),border-color .3s var(--e-out)
}
.navtoggle .bars{display:block;width:20px;height:12px;position:relative}
.navtoggle .bars i{
  position:absolute;left:0;right:0;height:1.5px;background:currentColor;border-radius:2px;
  transition:transform .38s var(--e-out),opacity .2s var(--e-out)
}
.navtoggle .bars i:first-child{top:0}
.navtoggle .bars i:last-child{bottom:0}
.navtoggle[aria-expanded="true"] .bars i:first-child{transform:translateY(5.25px) rotate(45deg)}
.navtoggle[aria-expanded="true"] .bars i:last-child{transform:translateY(-5.25px) rotate(-45deg)}
.nav:not(.solid) .navtoggle{color:var(--on-dark)}
.nav.solid .navtoggle{color:var(--ink)}
.navtoggle:hover{border-color:currentColor}

.mobilmenu{
  position:fixed;inset:0;z-index:55;display:flex;flex-direction:column;
  justify-content:center;gap:clamp(1.5rem,5vh,3rem);
  padding:max(5.5rem,calc(env(safe-area-inset-top) + 5rem)) var(--pad)
          max(2rem,calc(env(safe-area-inset-bottom) + 1.5rem));
  background:rgba(14,16,19,.97);color:var(--on-dark);
  opacity:0;transition:opacity .34s var(--e-out);overscroll-behavior:contain;
  overflow-y:auto
}
@supports (backdrop-filter:blur(1px)){
  .mobilmenu{background:rgba(14,16,19,.9);backdrop-filter:blur(18px) saturate(1.1)}
}
/* Das hidden-Attribut muss die Klassenregel schlagen, sonst bliebe das
   geschlossene Menü als unsichtbare Fläche über der ganzen Seite liegen. */
.mobilmenu[hidden]{display:none}
.mobilmenu.open{opacity:1}
/* Der klebende Knopf liegt über allem; bei offenem Menü tritt er ab. */
body.menu-open .sticky-cta{transform:translateY(110%)}
.mobilmenu nav{display:flex;flex-direction:column}
.mobilmenu nav a{
  display:flex;align-items:baseline;gap:.9rem;
  padding:.42rem 0;min-height:44px;text-decoration:none;color:var(--on-dark);
  font:400 clamp(1.4rem,5.6vw,2rem)/1.22 var(--display);letter-spacing:-.015em;
  opacity:0;transform:translateY(14px)
}
.mobilmenu.open nav a{opacity:1;transform:none;
  transition:opacity .5s var(--e-out),transform .5s var(--e-out)}
.mobilmenu.open nav a:nth-child(1){transition-delay:.06s}
.mobilmenu.open nav a:nth-child(2){transition-delay:.11s}
.mobilmenu.open nav a:nth-child(3){transition-delay:.16s}
.mobilmenu.open nav a:nth-child(4){transition-delay:.21s}
.mobilmenu.open nav a:nth-child(5){transition-delay:.26s}
.mobilmenu.open nav a:nth-child(6){transition-delay:.31s}
.mobilmenu.open nav a:nth-child(7){transition-delay:.36s}
.mobilmenu.open nav a:nth-child(8){transition-delay:.41s}
.mobilmenu nav a .n{
  font:400 .625rem var(--mono);letter-spacing:.2em;color:var(--accent-soft);
  flex:0 0 auto;width:1.9em
}
.mobilmenu nav a[aria-current="true"]{color:#fff}
.mobilmenu nav a[aria-current="true"] .n{color:var(--on-dark)}
.mobilmenu .foot{
  border-top:1px solid rgba(243,240,233,.16);padding-top:clamp(1.25rem,3.5vh,2rem);
  opacity:0;transform:translateY(14px)
}
.mobilmenu.open .foot{opacity:1;transform:none;
  transition:opacity .5s var(--e-out) .44s,transform .5s var(--e-out) .44s}
.mobilmenu .foot .btn{width:100%;max-width:24rem}
.mobilmenu .ruf{
  display:inline-flex;align-items:center;min-height:44px;margin-top:.9rem;
  color:var(--on-dark-2);text-decoration:none;font-size:.9375rem;
  border-bottom:1px solid rgba(243,240,233,.28)
}
.mobilmenu .ort{
  margin-top:1.1rem;font:400 .625rem var(--mono);letter-spacing:.18em;
  text-transform:uppercase;color:rgba(185,180,169,.72)
}
body.menu-open{overflow:hidden}

/* Navigation über dem dunklen Hero */
.nav:not(.solid){color:var(--on-dark)}
.nav:not(.solid) .brand b{color:var(--on-dark);text-shadow:0 2px 14px rgba(0,0,0,.6)}
.nav:not(.solid) .brand span,.nav:not(.solid) .links a{color:rgba(243,240,233,.82);text-shadow:0 2px 12px rgba(0,0,0,.7)}
.nav:not(.solid) .links a:hover{color:#fff}
.nav:not(.solid) .brand svg{color:var(--on-dark)}

/* ---- Knöpfe ------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  padding:.82rem 1.35rem;border:1px solid transparent;border-radius:999px;
  font:400 .9375rem/1 var(--text);text-decoration:none;cursor:pointer;
  background:var(--accent);color:#fff;
  transition:background .32s var(--e-out),transform .32s var(--e-out),box-shadow .32s var(--e-out);
  box-shadow:0 1px 0 rgba(0,0,0,.05)
}
.btn:hover{background:var(--accent-hover);transform:translateY(-1px);box-shadow:0 8px 24px rgba(110,70,32,.24)}
.btn:active{transform:translateY(0)}
.btn svg{width:17px;height:17px;flex:0 0 auto}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line-strong)}
.btn-ghost:hover{background:var(--ink);color:var(--canvas);border-color:var(--ink);box-shadow:none}
.on-dark .btn-ghost{color:var(--on-dark);border-color:rgba(243,240,233,.44)}
.on-dark .btn-ghost:hover{background:var(--on-dark);color:var(--dark);border-color:var(--on-dark)}
.band .btn{text-shadow:none}

/* ==========================================================================
   HERO
   ========================================================================== */
/* 600vh statt ursprünglich 820. Zwei Dinge müssen hier gleichzeitig
   stimmen, und sie ziehen in verschiedene Richtungen: das Bild soll sofort
   reagieren, der Text sich über mehrere Scrollbewegungen entwickeln.
   Auflösen lässt sich das nur über die Form der Kurven, nicht über die
   Länge. Weil der Spiegel einer Wurzelkurve folgt (Exponent 0,32), kostet
   eine um ein Fünftel längere Strecke nur ein Prozent seiner Reaktion nach
   der ersten Mausradstufe — dem Text aber gibt sie rund achthundert Pixel
   je Phase. Auf jedes der fünf Textbänder entfällt so gut eine
   Bildschirmhöhe. */
.hero{position:relative;height:600vh;background:var(--dark)}
.stage{
  position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;
  background:var(--dark);isolation:isolate
}
/* Poster und Video sind dieselbe Quelle (das Poster ist der erste Frame des
   Films, 1600 x 900) und laufen durch dieselbe Wiedergabekette: beide sind
   ersetzte Elemente mit identischem object-fit und identischem Anker. So
   gibt es weder einen Größen- noch einen Schärfesprung beim Wechsel. */
.stage>.poster{position:absolute;inset:0;display:block}
.stage>.poster img{
  width:100%;height:100%;object-fit:cover;object-position:65% 42%
}
.stage>video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:65% 42%;
  opacity:0;transition:opacity .35s var(--e-out);will-change:transform;transform:translateZ(0)
}
.stage.video-ready>video{opacity:1}
.stage.video-failed>video{display:none}
.stage.video-failed .poster{will-change:transform;transform-origin:64% 44%}

.scrim{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 120% 90% at 62% 42%,rgba(10,10,18,0) 34%,rgba(10,10,18,.60) 100%)
}

/* ---- Das Leben im Stillstand -------------------------------------------
   Das Bild selbst wird nicht bewegt — ein driftender oder atmender
   Bildausschnitt wirkt wie ein Fehler. Bewegt wird, was sich auch in
   Wirklichkeit bewegt: das Licht ist nie ganz ruhig, und vor der Linse
   treiben immer ein paar lose Haare.
   Beide Schichten liegen im Modus "screen". Sie hellen also nur dort auf,
   wo ohnehin Licht ist, und verschwinden über den dunklen Partien von
   selbst — auch über der Textspalte, die deshalb ruhig bleibt.
   ------------------------------------------------------------------------ */
/* Kein z-index: die Schichten liegen nach Reihenfolge im Markup über dem
   Scrim und unter den Textbändern. Über dem Text hätten sie nichts zu
   suchen — dessen dunkler Grund soll ruhig bleiben.
   Und bewusst kein mix-blend-mode: der Mischmodus sieht über der ganzen
   Bildfläche minimal schöner aus, kostet aber jedes Bild ein Zurücklesen
   des Untergrunds — gemessen 20 statt 60 Bilder pro Sekunde. Auf dunklem
   Grund ist normale Deckkraft davon kaum zu unterscheiden. */
.glimmer,.flyaways{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none
}
/* Der Schimmer sitzt dort, wo der Film sein Licht hat: erst die warme
   rechte Partie, später der Lichtring. Beide liegen fast an derselben
   Stelle, deshalb genügt eine feste Position ohne jedes Skript. */
.glimmer::before,.glimmer::after{content:"";position:absolute;inset:0}
.glimmer::before{
  background:radial-gradient(circle at 58% 43%,
    rgba(255,236,205,.15) 0%,rgba(255,230,196,.075) 26%,rgba(255,226,188,0) 54%);
  opacity:.45
}
.glimmer::after{
  background:radial-gradient(circle at 64% 34%,
    rgba(255,246,228,.09) 0%,rgba(255,238,214,0) 32%);
  opacity:.3
}
/* Zwei Takte, deren Längen kein gemeinsames Vielfaches haben: das Licht
   wiederholt sich dadurch nie erkennbar.
   Die erste Fassung hatte zwölf Stützstellen auf 7,4 Sekunden und einen
   Hub von 0,3 bis 0,92 — das war Flackern, kein Licht. Jetzt sind es
   wenige Stützstellen auf mehr als der doppelten Länge und ein Hub von
   knapp einem Drittel. Man sieht nicht mehr, dass sich etwas bewegt; man
   merkt nur, dass das Bild nicht tot ist. Genau das ist der Unterschied
   zwischen einer Leuchtreklame und einem Raum mit Licht darin. */
.stage.video-ready .glimmer::before,.mhero .glimmer::before{animation:glimmerA 17s ease-in-out infinite}
.stage.video-ready .glimmer::after,.mhero .glimmer::after{animation:glimmerB 26s ease-in-out infinite -9s}
@keyframes glimmerA{
  0%{opacity:.5}  27%{opacity:.66}  52%{opacity:.44}  78%{opacity:.6}  100%{opacity:.5}
}
@keyframes glimmerB{
  0%{opacity:.3}  34%{opacity:.44}  67%{opacity:.26}  100%{opacity:.3}
}

/* Die Strähnen kommen mit dem Licht, nicht davor. Der Film beginnt dunkel;
   in dieser Phase standen die hellen Strähnen als drei helle Linien über
   einem fast schwarzen Bild und sahen aus wie ein fremder Layer. Jetzt
   blenden sie erst auf, wenn der Lichtdurchgang läuft — die Verzögerung
   entspricht dem Ruhemoment plus der ersten Filmsekunde. */
.flyaways{opacity:0;transition:opacity 2.8s var(--e-out) 1.5s}
.stage.video-ready .flyaways,.mhero.film-on .flyaways{opacity:.6}
/* Jede Strähne wird zweimal gezeichnet: zuerst als dunkle Silhouette,
   darüber der helle Lichtfang. Ein Haar vor Gegenlicht ist dunkel, kein
   Leuchten — ohne die Silhouette verschwände die Strähne ausgerechnet
   über dem hellen Lichtring. Beide Pfade liegen in derselben Gruppe und
   in derselben Ebene: sie bewegen sich zwangsläufig gemeinsam, und der
   Browser muss nur eine Fläche neu zeichnen statt zweier. */
.flyaways path{stroke:url(#flyhair);opacity:.72}
.flyaways path.schatten{stroke:url(#flyschatten);opacity:1}
.flyaways g[class]{opacity:0}
.stage.video-ready .flyaways g[class]{animation-iteration-count:infinite;animation-timing-function:linear}
.stage.video-ready .flyaways .f1{animation-name:flyA;animation-duration:31s;animation-delay:-4s}
.stage.video-ready .flyaways .f3{animation-name:flyC;animation-duration:26s;animation-delay:-11s}
.stage.video-ready .flyaways .f5{animation-name:flyB;animation-duration:29s;animation-delay:-7s}
.stage.video-ready .flyaways .f6{animation-name:flyC;animation-duration:41s;animation-delay:-33s}
.stage.video-ready .flyaways .f7{animation-name:flyA;animation-duration:34s;animation-delay:-22s}
/* Die Strähnen treiben herein und wieder hinaus. Weil sie an beiden Enden
   bei opacity:0 stehen, gibt es keine Nahtstelle in der Schleife. */
@keyframes flyA{
  0%{transform:translate(0,0);opacity:0}
  16%{opacity:.55}
  50%{transform:translate(-13px,30px);opacity:.7}
  84%{opacity:.4}
  100%{transform:translate(7px,62px);opacity:0}
}
@keyframes flyB{
  0%{transform:translate(0,26px);opacity:0}
  18%{opacity:.42}
  52%{transform:translate(15px,-8px);opacity:.62}
  86%{opacity:.3}
  100%{transform:translate(-6px,-44px);opacity:0}
}
@keyframes flyC{
  0%{transform:translate(6px,0);opacity:0}
  20%{opacity:.5}
  55%{transform:translate(-18px,-22px);opacity:.75}
  88%{opacity:.35}
  100%{transform:translate(9px,-56px);opacity:0}
}
/* Im Hochformat sitzt der Ring mittig und etwas höher; der Schimmer folgt.
   Der Verlauf über dem Text liegt darüber und bleibt unberührt. */
/* Im Hochformat sitzt der Ring mittig und etwas höher; der Schimmer folgt. */
.mhero .glimmer::before{
  background:radial-gradient(circle at 50% 38%,
    rgba(255,236,205,.16) 0%,rgba(255,230,196,.08) 28%,rgba(255,226,188,0) 54%)
}
.mhero .glimmer::after{
  background:radial-gradient(circle at 50% 30%,
    rgba(255,246,228,.09) 0%,rgba(255,238,214,0) 30%)
}
/* Läuft der Film nicht (Datensparmodus, verweigerte Autowiedergabe), gibt
   es kein .film-on — dann blenden die Strähnen nach kurzer Zeit trotzdem
   auf, damit das Standbild nicht völlig regungslos bleibt. */
.mhero .flyaways{transition-delay:3.4s}
.mhero.film-on .flyaways,.stage.video-ready .flyaways{transition-delay:1.5s}
.mhero .flyaways{opacity:.6}
.mhero .flyaways g[class]{animation-iteration-count:infinite;animation-timing-function:linear}
.mhero .flyaways .f1{animation-name:flyA;animation-duration:33s;animation-delay:-6s}
.mhero .flyaways .f2{animation-name:flyB;animation-duration:41s;animation-delay:-24s}
.mhero .flyaways .f3{animation-name:flyC;animation-duration:28s;animation-delay:-13s}
.mhero .flyaways .f5{animation-name:flyB;animation-duration:36s;animation-delay:-9s}
.mhero .flyaways .f7{animation-name:flyA;animation-duration:45s;animation-delay:-30s}

/* Strichbreiten. Die Strähnen skalieren mit dem Bild, statt den Strich in
   jedem Einzelbild neu in Gerätepixel zu rechnen — ein nicht mitskalierender
   Strich (vector-effect) kostete auf großen Flächen gemessen 39 statt 60
   Bilder pro Sekunde. Der Preis dafür: auf einem Tablet deckt derselbe
   Hochformat-Hero fast die doppelte Fläche eines Telefons ab, das Haar
   stünde dort doppelt so dick. Zwei Staffelungen halten es überall bei
   rund einem Pixel. */
@media (min-width:721px){
  .mhero .flyaways .f1 path{stroke-width:.66}
  .mhero .flyaways .f2 path{stroke-width:.48}
  .mhero .flyaways .f3 path{stroke-width:.78}
  .mhero .flyaways .f5 path{stroke-width:.54}
  .mhero .flyaways .f7 path{stroke-width:.72}
}
@media (min-width:1700px){
  .stage .flyaways .f1 path{stroke-width:.53}
  .stage .flyaways .f3 path{stroke-width:.63}
  .stage .flyaways .f5 path{stroke-width:.53}
  .stage .flyaways .f6 path{stroke-width:.44}
  .stage .flyaways .f7 path{stroke-width:.58}
}

/* Außerhalb des Bildes, bei verstecktem Tab und bei reduzierter Bewegung
   steht alles still. Der Hero ist dann wieder das, was er vorher war. */
.hero:not(.inview) .glimmer::before,
.hero:not(.inview) .glimmer::after,
.hero:not(.inview) .flyaways g[class]{animation-play-state:paused}
body.motion-off .glimmer,body.motion-off .flyaways{display:none}
@media (prefers-reduced-motion:reduce){
  .glimmer,.flyaways{display:none}
}

/* Scroll-Aufforderung: erscheint, sobald das Poster steht. Einen Ladering
   gibt es nicht mehr, das sofort scharfe Poster ist der Ladezustand. */
.cue{
  position:absolute;left:var(--pad);bottom:2.4rem;display:flex;align-items:center;gap:.7rem;
  font:400 .625rem var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:rgba(243,240,233,.66);opacity:0;
  transition:opacity 1.1s var(--e-out) .25s
}
.stage.poster-ready .cue,.stage.video-ready .cue,.stage.video-failed .cue{opacity:1}
/* Während der Selbstläufer läuft, hält sich die Aufforderung zurück: erst
   spielt der Film seine Geste zu Ende, dann kommt sie ins Bild und übergibt.
   Genau deshalb hat der Auftritt eine kleine Verzögerung: sie erscheint
   einen Wimpernschlag nach dem letzten Bild, nicht gleichzeitig mit ihm. */
.stage.intro-running .cue{opacity:0;transition:opacity .3s var(--e-out)}
/* Sobald die Reise begonnen hat, zieht sich die Aufforderung zurück. */
.stage.cue-off .cue{opacity:0;transition:opacity .5s var(--e-out)}
.cue .stem{display:block;width:1px;height:34px;background:linear-gradient(rgba(243,240,233,.7),rgba(243,240,233,0));animation:cueDrop 2.6s var(--e-soft) -.4s infinite}
@keyframes cueDrop{0%,100%{transform:scaleY(.4);transform-origin:top}50%{transform:scaleY(1);transform-origin:top}}

/* Bänder */
.bands{position:absolute;inset:0;pointer-events:none}
.band{
  position:absolute;left:var(--pad);top:50%;transform:translateY(-50%);
  width:min(46vw,620px);opacity:0;text-shadow:var(--tshadow);color:var(--on-dark);
  pointer-events:none
}
.band.live{pointer-events:auto}
/* Der Band-Scrim folgt der Komposition des Films: dunkel in der Textspalte,
   nach rechts vollständig ausgelaufen, damit die Lichtseite hell bleibt. */
.band::before{
  content:"";position:absolute;inset:-26% -55% -30% -50%;pointer-events:none;z-index:-1;
  opacity:calc(.30 + .70*var(--k,1));
  background:linear-gradient(96deg,rgba(6,7,11,.74) 0%,rgba(6,7,11,.68) 46%,rgba(6,7,11,.38) 74%,rgba(6,7,11,0) 100%);
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 20%,#000 80%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0%,#000 20%,#000 80%,transparent 100%)
}
/* Band 2 liegt genau dort, wo das Streiflicht durchs Bild wandert, und
   bekommt deshalb den tiefsten Scrim. Gemessen, nicht geschätzt. */
.band:nth-of-type(2)::before{
  background:linear-gradient(96deg,rgba(6,7,11,.82) 0%,rgba(6,7,11,.76) 48%,rgba(6,7,11,.50) 76%,rgba(6,7,11,0) 100%)
}
.band .kicker{
  display:inline-flex;align-items:center;gap:.6rem;margin-bottom:1.5rem;
  font:400 .625rem var(--mono);letter-spacing:.24em;text-transform:uppercase;
  color:#EFE7D8;
  background:rgba(8,8,15,.55);border:1px solid rgba(206,196,176,.30);border-radius:999px;
  padding:.45rem .85rem;backdrop-filter:blur(10px);text-shadow:0 1px 3px rgba(5,5,10,.85)
}
.band p.lead{
  font:400 clamp(2.35rem,5vw,4.25rem)/1.02 var(--display);
  letter-spacing:-.018em;margin:0
}
.band .sub{
  font:400 clamp(1rem,1.5vw,1.1875rem)/1.55 var(--text);
  color:rgba(243,240,233,.9);margin-top:1.15rem;max-width:36ch
}
.band .row{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:1.9rem}

/* Zeichen- und Wortanimationen, nur transform und opacity */
.w{display:inline-block;white-space:pre}
.c{display:inline-block;will-change:transform,opacity}
.e-scatter .c,.e-weave .c,.e-grid .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.6,1);opacity:var(--kc);
  transform:translate(calc((1 - var(--kc))*var(--jx,0px)),calc((1 - var(--kc))*var(--jy,0px)))
            rotate(calc((1 - var(--kc))*var(--jr,0deg)))
}
.e-drift .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc))*-26px))
}
.e-depth .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.4,1);opacity:var(--kc);
  transform:scale(calc(.86 + .14*var(--kc)))
}
.e-rise .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.9,1);opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc))*22px))
}
.band .sub{--ks:clamp(0,(var(--k,0) - .60)*3.6,1);opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks))*14px))}
.band .row{--kb:clamp(0,(var(--k,0) - .74)*4.4,1);opacity:var(--kb);
  transform:translateY(calc((1 - var(--kb))*16px))}

/* Mobiler Hero: eigenständige filmische Komposition.
   Schicht 1: das Standbild mit sehr langsamer Tiefenbewegung (sofort da).
   Schicht 2: eine leise Lichtatmung auf dem Ring.
   Schicht 3: der eigene Hochkant-Film, der einmal durchläuft und auf dem
   hellen Ring stehen bleibt. Fällt irgendetwas aus, bleibt Schicht 1. */
.mhero{display:none;position:absolute;inset:0}
.mhero .pic{position:absolute;inset:0;overflow:hidden;transform:translateZ(0)}
.mhero picture{position:absolute;inset:0;display:block}
/* Standbild und Film sind zwei Ebenen desselben Bildes und müssen deshalb
   dieselbe Geometrie haben — sonst überblendet die Seite nicht von einem
   Bild auf dasselbe Bild, sondern von einem Ausschnitt auf einen anderen.
   Vorher lagen drei Unterschiede übereinander: das Bild hatte
   object-position 50% 30%, das Video den Vorgabewert 50% 50%; das Bild stand
   auf scale(1.06), das Video auf 1; und der Zoom lief 14 Sekunden lang, die
   Überblendung aber schon nach knapp einer — das Bild war also mitten in der
   Bewegung, während der Film stillstand. Beide Ebenen teilen sich jetzt
   Ausschnitt, Maßstab und Zoom. Da beide von Anfang an im Dokument stehen,
   starten ihre Animationen im selben Augenblick und laufen synchron. */
.mhero img,.mhero .mvid{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 30%;
  transform:scale(1.06);animation:mheroSettle 14s var(--e-soft) .1s forwards
}
@keyframes mheroSettle{to{transform:scale(1)}}
/* Kurze Blende, weil beide Ebenen dasselbe Bild zeigen: sie muss nur noch
   Reste ausgleichen — Kompressionsrauschen, minimale Farbunterschiede
   zwischen Video- und Bilddekodierung. Sie läuft ab, bevor der Film
   losläuft, deshalb darf sie kurz sein. */
.mhero .mvid{opacity:0;transition:opacity .3s var(--e-out)}
.mhero.film-on .mvid{opacity:1}
.mhero .shade{
  position:absolute;left:0;right:0;bottom:0;height:52%;pointer-events:none;
  background:linear-gradient(180deg,rgba(8,9,12,0),rgba(8,9,12,.32) 55%,rgba(8,9,12,.5))
}
.mhero .copy{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(2rem,7vh,4.5rem);
  color:var(--on-dark);text-shadow:var(--tshadow)
}
/* Ruhiger, gestaffelter Auftritt der Textzeilen, läuft genau einmal. */
.mhero .copy>*{opacity:0;transform:translateY(14px);animation:mheroRise .95s var(--e-out) forwards}
.mhero .copy>.kicker{animation-delay:.12s}
.mhero .copy>.mh1{animation-delay:.26s}
.mhero .copy>.sub{animation-delay:.42s}
.mhero .copy>.row{animation-delay:.58s}
@keyframes mheroRise{to{opacity:1;transform:none}}
.mhero .mh1{font:400 clamp(2.1rem,8.4vw,3.1rem)/1.04 var(--display);letter-spacing:-.018em;margin:.9rem 0 0}
.mhero .sub{font:400 1rem/1.55 var(--text);color:rgba(243,240,233,.92);margin-top:.9rem;max-width:30ch}
.mhero .row{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.6rem}
.mhero .kicker{
  display:inline-block;font:400 .625rem var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:#EFE7D8;background:rgba(8,8,15,.55);border:1px solid rgba(206,196,176,.30);
  border-radius:999px;padding:.42rem .8rem;backdrop-filter:blur(10px)
}

/* ==========================================================================
   Der Auslauf: das Filmbild löst sich auf seinen letzten ~180 Pixeln in die
   Canvas-Farbe des folgenden Abschnitts auf. Kein eigener Zwischenraum, kein
   Balken: der Verlauf liegt im Hero selbst und beginnt transparent. Einige
   feine Haarlinien laufen über die Grenze hinaus und übergeben an den Faden.
   Nur ein Verlauf, keine Zeichnung: das Haar im Film löst sich darin auf,
   und der nächste Abschnitt beginnt auf einer sauberen Kante.
   ========================================================================== */
.hero-exit{
  position:absolute;left:0;right:0;bottom:0;height:210px;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(235,234,230,0) 0%,rgba(235,234,230,.05) 26%,rgba(235,234,230,.2) 48%,
    rgba(235,234,230,.52) 70%,rgba(235,234,230,.9) 86%,var(--canvas) 94%,var(--canvas) 100%)
}
/* Und hier lag der dunkle Strich an der Kante zum ersten Abschnitt.
   Der Verlauf endet in der reinen Canvas-Farbe. Die Abschnitte darunter
   haben keinen eigenen Hintergrund — dort scheint dieselbe Farbe durch das
   Korn der Umgebung hindurch und wirkt dadurch rund drei Prozent dunkler.
   Gemessen: 233 über der Kante gegen 226 darunter, quer über die ganze
   Breite. Das liest das Auge als Linie.
   Der Auslauf bekommt deshalb dasselbe Korn, maskiert auf den Bereich, in
   dem der Verlauf bereits deckt. Damit endet er in genau dem Ton, in dem
   der nächste Abschnitt beginnt — ohne festen Zahlenwert, der beim nächsten
   Eingriff ins Korn wieder auseinanderliefe. */
.hero-exit::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  opacity:.46;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
  -webkit-mask-image:linear-gradient(180deg,transparent 56%,#000 88%);
  mask-image:linear-gradient(180deg,transparent 56%,#000 88%)
}
/* Beim statischen Hero sitzt der Text unten im Bild: der Auslauf beginnt
   deshalb später und bleibt kürzer, damit er nicht in die Knöpfe greift.
   Diese Regel steht im selben Gate wie der statische Hero selbst. */
@media (max-width:720px),
       (orientation:portrait) and (max-width:1024px),
       (orientation:portrait) and (pointer:coarse),
       (orientation:landscape) and (pointer:coarse) and (max-height:560px),
       (prefers-reduced-motion:reduce){
  .hero-exit{
    height:150px;bottom:0;
    background:linear-gradient(180deg,
      rgba(235,234,230,0) 0%,rgba(235,234,230,.05) 40%,rgba(235,234,230,.18) 62%,
      rgba(235,234,230,.52) 80%,rgba(235,234,230,.9) 91%,var(--canvas) 96%,var(--canvas) 100%)
  }
}

/* ==========================================================================
   Der Faden: das Signaturelement
   ========================================================================== */
/* Der Faden. Zusätzlich zum Verlauf im SVG bekommt er eine Maske: sie
   nimmt die letzten Prozente an beiden Enden weg, damit weder oben noch
   unten ein abgeschnittener Stummel stehen bleibt. Verlauf und Maske
   zusammen ergeben ein Element, das auftaucht und wieder verschwindet,
   statt an zwei willkürlichen Stellen zu beginnen und aufzuhören. */
.thread{
  position:absolute;left:clamp(.55rem,2.4vw,3.05rem);top:0;width:26px;height:100%;
  z-index:0;pointer-events:none;overflow:visible;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 7%,#000 90%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 7%,#000 90%,transparent 100%)
}
.thread path{fill:none;stroke-width:1.4;stroke-linecap:round;
  stroke-dasharray:var(--len,4000);stroke-dashoffset:var(--dash,4000)}

/* ==========================================================================
   Abschnitte
   ========================================================================== */
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad)}
section{position:relative}
.sec{padding-block:clamp(4.5rem,11vh,9rem)}
.sec--tint{background:var(--canvas-2)}
.sec--dark{background:var(--dark);color:var(--on-dark)}

.eyebrow{
  display:flex;align-items:center;gap:.85rem;
  font:400 .6875rem var(--mono);letter-spacing:.22em;text-transform:uppercase;color:var(--text-2)
}
.sec--dark .eyebrow{color:var(--on-dark-2)}
.eyebrow .num{
  position:relative;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;
  border:1px solid var(--line-strong);font-size:.625rem;letter-spacing:0;flex:0 0 auto
}
/* Ein lebendes Element pro Abschnitt, auf Flüsterstärke: der Lichtring
   des Salons atmet leise weiter. Läuft nur, solange der Abschnitt im Bild ist. */
.eyebrow .num::after{
  content:"";position:absolute;inset:-5px;border-radius:50%;
  border:1px solid var(--accent-soft);opacity:0;transform:scale(.84);pointer-events:none
}
section.inview .eyebrow .num::after{animation:numRing 7.5s var(--e-soft) -2.4s infinite}
@keyframes numRing{
  0%,100%{opacity:0;transform:scale(.84)}
  46%{opacity:.55;transform:scale(1.02)}
}
.sec--dark .eyebrow .num{border-color:rgba(243,240,233,.4)}

h2.big{
  font:400 clamp(2.1rem,4.6vw,3.5rem)/1.05 var(--display);
  letter-spacing:-.018em;margin:1.5rem 0 0;max-width:19ch
}
.lede{font-size:1.0625rem;line-height:1.62;color:var(--text-2);margin-top:1.15rem;max-width:56ch}
.sec--dark .lede{color:var(--on-dark-2)}

/* Auftritte. Verstecken nur, wenn JavaScript wirklich läuft: ohne JS ist
   alles sofort sichtbar, kein Inhalt hängt dauerhaft auf opacity:0. */
.js .rise{opacity:0;transform:translateY(26px)}
.js .rise.in{opacity:1;transform:none;transition:opacity .85s var(--e-out),transform .85s var(--e-out)}
.js .stag>*{opacity:0;transform:translateY(24px)}
.js .stag.in>*{opacity:1;transform:none;transition:opacity .8s var(--e-out),transform .8s var(--e-out)}
.js .stag.in>*:nth-child(1){transition-delay:0ms}
.js .stag.in>*:nth-child(2){transition-delay:90ms}
.js .stag.in>*:nth-child(3){transition-delay:180ms}
.js .stag.in>*:nth-child(4){transition-delay:270ms}
.js .stag.in>*:nth-child(5){transition-delay:360ms}
.js .stag.in>*:nth-child(6){transition-delay:450ms}
.stag.done>*:nth-child(1),.stag.done>*:nth-child(2),.stag.done>*:nth-child(3),
.stag.done>*:nth-child(4),.stag.done>*:nth-child(5),.stag.done>*:nth-child(6){transition-delay:0ms!important}

/* ---- 01 Arbeiten: Vorher / Ergebnis ------------------------------------ */
#arbeiten .head{display:grid;grid-template-columns:1fr;gap:0}
.compare-grid{
  display:grid;gap:clamp(2rem,4vw,3.4rem);margin-top:clamp(2.75rem,6vw,4.5rem);
  grid-template-columns:minmax(0,1fr)
}
@media (min-width:820px){.compare-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
.cmp figure{margin:0}
.cmp .stagebox{
  position:relative;aspect-ratio:3/4;overflow:hidden;border-radius:2px;
  background:var(--canvas-2);box-shadow:0 1px 0 rgba(0,0,0,.06),0 26px 60px -34px rgba(20,16,10,.55);
  cursor:ew-resize;touch-action:pan-y;isolation:isolate;user-select:none;-webkit-user-select:none;
  -webkit-tap-highlight-color:transparent
}
/* Beide Bild-Ebenen füllen die komplette Karte. Das <picture> selbst trägt
   die Fläche, damit der clip-path auf .after eine echte Geometrie hat und
   Lazy Loading die Ergebnisbilder zuverlässig als sichtbar erkennt. */
.cmp .stagebox picture{
  position:absolute;inset:0;display:block;width:100%;height:100%;pointer-events:none
}
.cmp img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  pointer-events:none;-webkit-user-drag:none;user-select:none}
.cmp .after{clip-path:inset(0 0 0 var(--p,50%))}

/* ---- Feinausrichtung der Paare -----------------------------------------
   Beide Aufnahmen eines Paares stammen aus derselben Sitzung, aber nicht vom
   exakt selben Kamerastandpunkt. Ohne Korrektur sitzt der Kopf links und
   rechts der Trennlinie unterschiedlich hoch und unterschiedlich weit
   innen — beim Ziehen springt er.

   Warum nicht object-position? Die Bilder sind 640x853, die Karte ist 3:4.
   Beides ist praktisch dasselbe Seitenverhältnis, object-fit:cover schneidet
   also nichts weg. Ohne Überstand hat object-position nichts zu verschieben
   und bleibt wirkungslos. Spielraum entsteht erst durch eine Vergrößerung.

   Mit transform-origin 0 0 landet ein Punkt bei Anteil u der Bildkante auf
   Anteil  z*u + q  der Karte. Damit keine Kante frei wird, muss  q <= 0  und
   z + q >= 1  gelten. Die Werte unten sind daraus je Bild ausgerechnet,
   nicht geschätzt; die Vergrößerung bleibt überall bei höchstens 12 %.

   Die Originaldateien sind unangetastet — verschoben wird nur die
   Darstellung. */
.cmp img{
  transform-origin:0 0;
  transform:translate(var(--quer,0%),var(--hoch,0%)) scale(var(--zoom,1))
}
/* Waagerecht haben alle acht Bilder dasselbe Ziel: die Mitte der Frisur in
   der Mitte der Karte. Nur die Paare aufeinander auszurichten genügt nicht —
   dann liegen zwar beide Hälften übereinander, das Paar als Ganzes kann aber
   trotzdem sichtbar außermittig stehen. Gemessen ist die Frisurmitte über die
   Farbigkeit: die Wand ist neutral hell, der Stuhl neutral dunkel, das Haar
   warm und mitteldunkel. Senkrecht liegt der Kopf jedes Paares auf einer
   gemeinsamen Höhe, die nahe an der ursprünglichen Bildaufteilung bleibt. */
/* Paar 1 */
.cmp-1 picture:not(.after) img{--zoom:1.075;--quer:-1.28%;--hoch:-7.05%}
.cmp-1 .after img{--zoom:1.137;--quer:-13.44%;--hoch:-0.70%}
/* Paar 2 */
.cmp-2 picture:not(.after) img{--zoom:1.048;--quer:-1.46%;--hoch:-4.36%}
.cmp-2 .after img{--zoom:1.106;--quer:-3.86%;--hoch:-0.10%}
/* Paar 3: Das Ergebnis ist rund ein Sechstel näher aufgenommen. Das
   Vorher-Bild steht deshalb ohnehin größer — das gleicht einen Teil des
   Unterschieds aus. Ganz ausgleichen ließe sich er nur mit einem sehr
   starken Beschnitt. */
.cmp-3 picture:not(.after) img{--zoom:1.115;--quer:-0.29%;--hoch:-11.01%}
.cmp-3 .after img{--zoom:1.067;--quer:-1.75%;--hoch:-0.11%}
/* Paar 4 */
.cmp-4 picture:not(.after) img{--zoom:1.142;--quer:-0.25%;--hoch:-3.41%}
.cmp-4 .after img{--zoom:1.122;--quer:-0.27%;--hoch:-2.93%}
/* Etiketten und Griff kommen ohne backdrop-filter aus. Der Filter braucht
   einen Hintergrundschnappschuss der ganzen Karte, und WebKit beschneidet
   diesen Schnappschuss innerhalb eines eigenen Stapelkontexts (.stagebox
   hat isolation:isolate und overflow:hidden) nicht zuverlässig auf die
   Elementform. Auf dem iPhone stand deshalb ein milchiges Rechteck über
   dem Foto statt einer runden Milchglasfläche. Eine etwas dichtere
   Grundfarbe sieht auf dem Bild praktisch gleich aus, malt aber nur dort,
   wo das Element wirklich liegt — und spart beim Ziehen den Schnappschuss
   in jedem Einzelbild. */
.cmp .lbl{
  position:absolute;top:.85rem;z-index:2;font:400 .5625rem var(--mono);letter-spacing:.2em;text-transform:uppercase;
  background:rgba(8,8,15,.72);color:#F2EDE2;border:1px solid rgba(206,196,176,.28);
  padding:.36rem .62rem;border-radius:999px;pointer-events:none;
  transition:opacity .4s var(--e-out)
}
.cmp .lbl-b{left:.85rem}
.cmp .lbl-a{right:.85rem}
/* Am Anschlag verschwindet das Etikett der Seite, die nicht mehr zu sehen ist. */
.cmp .stagebox.at-end .lbl-a{opacity:0}
.cmp .stagebox.at-start .lbl-b{opacity:0}
/* Der Trenner braucht Kontrast gegen helle Bildstellen, aber keinen
   Schlagschatten: ein weicher Schatten über 18 Pixel zieht als grauer
   Schleier über die ganze Kartenhöhe und liegt sichtbar über dem Foto.
   Stattdessen eine harte Haarlinie beidseitig — ein Pixel, kein Weichzeichner. */
.cmp .divider{
  position:absolute;top:0;bottom:0;left:var(--p,50%);width:2px;margin-left:-1px;z-index:3;
  background:linear-gradient(rgba(255,252,246,0),rgba(255,252,246,.92) 12%,rgba(255,252,246,.92) 88%,rgba(255,252,246,0));
  pointer-events:none;box-shadow:0 0 0 1px rgba(18,16,12,.3);
  transition:box-shadow .3s var(--e-out)
}
.cmp .knob{
  position:absolute;top:50%;left:clamp(27px,var(--p,50%),calc(100% - 27px));
  width:52px;height:52px;margin:-26px 0 0 -26px;
  border-radius:50%;display:grid;place-items:center;pointer-events:none;z-index:3;
  background:rgba(14,16,19,.64);border:1.5px solid rgba(255,252,246,.9);
  color:#FFFCF6;
  transition:transform .4s var(--e-out),box-shadow .4s var(--e-out);
  box-shadow:0 0 0 0 rgba(255,252,246,.32)
}
.cmp .stagebox:hover .knob{transform:scale(1.07);box-shadow:0 0 0 9px rgba(255,252,246,.10)}
/* Rückmeldung beim Greifen: Griff wächst, Trennlinie leuchtet leicht auf. */
.cmp .stagebox.dragging .knob{transform:scale(1.12);box-shadow:0 0 0 12px rgba(255,252,246,.14);transition-duration:.18s}
/* Beim Greifen wird die Linie kräftiger, nicht breiter. */
.cmp .stagebox.dragging .divider{box-shadow:0 0 0 1px rgba(18,16,12,.42)}
.cmp .knob svg{width:22px;height:22px}

/* Der Regler ist ein echtes Range-Eingabefeld des Browsers. Dadurch hört er
   auf die Pfeiltasten, meldet Wert und Beschriftung an Vorlesegeräte und
   bleibt ein Bedienelement statt eines nachgebauten Bildes davon.
   Zeigereingaben übernimmt die eigene Pointer-Steuerung auf der ganzen Karte.

   Das Feld zeichnet nichts mehr. Vorher lag es sichtbar über dem Foto, und
   sein Daumen war 56 Pixel breit und bildhoch — fast genau die Breite des
   runden Griffs. Für diesen Daumen zeichnet WebKit trotz appearance:none und
   durchsichtigem Hintergrund eine eigene Fläche; auf dem iPhone stand deshalb
   ein senkrechter, halbdurchsichtiger Streifen über der vollen Bildhöhe.
   Ein Element mit opacity:0 zeichnet nichts, bleibt aber fokussierbar,
   bedienbar und für Vorlesegeräte vollständig vorhanden — die Ursache ist
   damit weg und nicht überdeckt.

   Ohne JavaScript gibt es keine eigene Zieh-Logik. Dann ist der Daumen die
   einzige Greiffläche, und das Feld bleibt sichtbar. */
.cmp .rng{
  position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;
  -webkit-appearance:none;-moz-appearance:none;appearance:none;
  background:transparent;color:transparent;opacity:0;
  cursor:ew-resize;touch-action:pan-y;z-index:4;
  -webkit-tap-highlight-color:transparent
}
html:not(.js) .cmp .rng{opacity:1}
/* Sobald die eigene Pointer-Steuerung übernommen hat, reicht der Range-Regler
   die Zeigereingaben durch und bleibt nur für Tastatur und Vorlesegeräte da. */
.stagebox.js-drag .rng{pointer-events:none}
.cmp .rng::-webkit-slider-runnable-track{height:100%;background:transparent;border:0;box-shadow:none}
.cmp .rng::-moz-range-track{height:100%;background:transparent;border:0}
.cmp .rng::-moz-range-progress{background:transparent}
/* Breiter Daumen für den Fall ohne JavaScript: dort ist er die einzige
   Greiffläche. Keine Farbe, kein Rand, kein Schatten. */
.cmp .rng::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;width:56px;height:100%;
  background:transparent;border:0;box-shadow:none;cursor:ew-resize
}
.cmp .rng::-moz-range-thumb{
  width:56px;height:100%;background:transparent;border:0;box-shadow:none;border-radius:0;cursor:ew-resize
}
.cmp .rng:focus{outline:none}
/* Der Tastaturfokus liegt jetzt auf der Karte, weil das Feld selbst nichts
   mehr zeichnet. Ohne JavaScript ist das Feld sichtbar und behält seinen
   eigenen Fokusrahmen. */
.cmp .stagebox.tastaturfokus{outline:2px solid #E8C79A;outline-offset:3px}
html:not(.js) .cmp .rng:focus-visible{outline:2px solid #E8C79A;outline-offset:3px;border-radius:2px}
.cmp figcaption{margin-top:1.15rem;display:flex;gap:1rem;align-items:baseline}
.cmp figcaption .n{font:400 .6875rem var(--mono);color:var(--accent);flex:0 0 auto}
.cmp figcaption p{font-size:.9375rem;line-height:1.55;color:var(--text-2)}
.hint{
  margin-top:2.6rem;display:inline-flex;align-items:center;gap:.6rem;
  font:400 .6875rem var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--text-2)
}
.hint svg{width:22px;height:14px;color:var(--accent)}

/* ---- 02 Galerie --------------------------------------------------------- */
/* Ruhiges, bündiges Editorial-Raster: einheitliche 4:5-Kacheln, ein großes
   Auftaktbild als Akzent, flushe Unterkante. Beschnitten wird nur die
   Rasteransicht; die Lightbox zeigt jedes Bild vollständig. */
.gal{
  margin-top:clamp(2.5rem,5vw,4rem);
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(.6rem,1.4vw,1.15rem);grid-auto-flow:dense
}
.gal button{
  position:relative;padding:0;border:0;background:var(--canvas-2);cursor:zoom-in;
  overflow:hidden;border-radius:2px;display:block;width:100%;
  aspect-ratio:4/5
}
.gal button:first-child{grid-column:span 2;grid-row:span 2}
@media (max-width:900px){
  .gal{grid-template-columns:repeat(2,minmax(0,1fr))}
  .gal button:first-child{grid-column:auto;grid-row:auto}
}
.gal picture{display:block;width:100%;height:100%}
.gal img{width:100%;height:100%;object-fit:cover;display:block;transition:transform 1.1s var(--e-out)}
.gal button:hover img,.gal button:focus-visible img{transform:scale(1.045)}
.gal button::after{
  content:"";position:absolute;inset:0;background:linear-gradient(rgba(14,16,19,0) 48%,rgba(14,16,19,.5));
  opacity:0;transition:opacity .5s var(--e-out)
}
.gal button:hover::after,.gal button:focus-visible::after{opacity:1}
/* Dezente Bildinformation beim Zeigen, nur dort, wo ein Cursor existiert. */
@media (hover:hover) and (pointer:fine){
  .gal button .cap{
    position:absolute;left:.9rem;right:.9rem;bottom:.8rem;z-index:1;
    font:400 .625rem var(--mono);letter-spacing:.16em;text-transform:uppercase;
    color:#F2EDE2;text-align:left;text-shadow:0 1px 6px rgba(5,5,10,.8);
    opacity:0;transform:translateY(6px);
    transition:opacity .45s var(--e-out),transform .45s var(--e-out);pointer-events:none
  }
  .gal button:hover .cap,.gal button:focus-visible .cap{opacity:1;transform:none}
}
@media not ((hover:hover) and (pointer:fine)){
  .gal button .cap{display:none}
}

.lightbox{
  position:fixed;inset:0;z-index:120;display:none;place-items:center;
  width:100vw;height:100vh;max-width:100vw;max-height:100vh;margin:0;border:0;
  background:rgba(10,11,13,.93);backdrop-filter:blur(6px);padding:clamp(1rem,4vw,3rem);
  overflow:hidden
}
.lightbox[open]{display:grid}
.lightbox::backdrop{background:rgba(10,11,13,.88);backdrop-filter:blur(4px)}
.lightbox figure{touch-action:pan-y}
/* In der Lightbox wird nichts markiert. Sie ist ein Bildbetrachter: es gibt
   hier nichts zu kopieren, was nicht auch auf der Seite selbst steht.
   Der Grund ist ein konkreter Bedienfehler. Wer beim Blättern zweimal kurz
   hintereinander auf einen Pfeil klickt, löst einen Doppelklick aus, und ein
   Doppelklick beginnt eine Wortauswahl — auch über einem Knopf, der selbst
   keinen Text hat: der Browser greift dann auf den umgebenden Text zu.
   Beim nächsten Weiterblättern tauscht renderLb() Bildunterschrift und
   Zählung aus. Liegt der Ankerpunkt der Auswahl in einem dieser Textknoten
   und verschwindet dieser, dehnt der Browser die Auswahl auf den nächsten
   gemeinsamen Vorfahren aus — daher die plötzlich riesigen Markierungen,
   die stehen bleiben. Ohne Auswahl gibt es keinen Anker, und der ganze
   Vorgang kann nicht mehr entstehen.
   Bewusst nur hier: außerhalb der Lightbox bleibt die Seite normal
   markierbar. */
.lightbox,.lightbox button,.lightbox svg,
.lightbox figure,.lightbox figcaption,.lightbox img{
  -webkit-user-select:none;user-select:none
}
/* Das große Bild ist kein Anfasser: ohne diese Zeile zieht der Browser es
   als Datei aus dem Fenster, sobald man mit gedrückter Maustaste darüber
   fährt — mitten im Blättern eine leicht auslösbare Fehlbedienung. */
.lightbox img{-webkit-user-drag:none}
.lightbox img{max-width:min(90vw,720px);max-height:78vh;width:auto;height:auto;object-fit:contain;border-radius:2px;margin:0 auto;
  transition:opacity .28s var(--e-out)}
.lightbox.switching img{opacity:0}
.lightbox figcaption{margin-top:1rem;text-align:center;color:var(--on-dark-2);font-size:.875rem;
  display:flex;flex-direction:column;gap:.3rem;align-items:center}
.lightbox .lb-count{font:400 .625rem var(--mono);letter-spacing:.22em;color:rgba(185,180,169,.7)}
body.lb-open{overflow:hidden}
.lb-close,.lb-prev,.lb-next{
  position:absolute;background:rgba(243,240,233,.10);border:1px solid rgba(243,240,233,.3);
  color:var(--on-dark);width:46px;height:46px;border-radius:50%;display:grid;place-items:center;cursor:pointer;
  transition:background .3s var(--e-out)
}
.lb-close:hover,.lb-prev:hover,.lb-next:hover{background:rgba(243,240,233,.22)}
.lb-close{top:clamp(1rem,3vw,2rem);right:clamp(1rem,3vw,2rem)}
.lb-prev{left:clamp(.6rem,3vw,2rem);top:50%;margin-top:-23px}
.lb-next{right:clamp(.6rem,3vw,2rem);top:50%;margin-top:-23px}
.lb-close svg,.lb-prev svg,.lb-next svg{width:18px;height:18px}

/* ---- 03 Leistungen ------------------------------------------------------ */
.svc{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2.5rem,5vw,4rem);margin-top:clamp(2.5rem,5vw,3.75rem)}
@media (min-width:900px){.svc{grid-template-columns:repeat(2,minmax(0,1fr))}}
.svc h3{
  font:400 1.5rem/1.2 var(--display);letter-spacing:-.01em;
  padding-bottom:.85rem;border-bottom:1px solid var(--line);margin-bottom:.35rem
}
.svc .kicker{font:400 .625rem var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--accent);display:block;margin-bottom:.7rem}
/* Ohne Spaltenabstand stoßen die beiden gepunkteten Kanten aneinander und
   ergeben eine durchgehende Linie. Mit einem Abstand risse sie genau vor
   dem Preis auf — der auffälligsten Stelle der ganzen Liste. Der Abstand
   sitzt deshalb im Innenabstand der Preisspalte. */
.svc dl{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:0}
.svc dt{padding:.72rem 0;border-bottom:1px dotted var(--line);font-size:.9375rem}
.svc dd{padding:.72rem 0 .72rem 1.25rem;border-bottom:1px dotted var(--line);text-align:right;
  font:400 .875rem var(--mono);white-space:nowrap;color:var(--ink-2)}
.svc dt small{display:block;font-size:.8125rem;color:var(--text-2);margin-top:.15rem;font-family:var(--text)}
.pricenote{
  margin-top:clamp(2.25rem,4vw,3rem);padding:1.35rem 1.5rem;border-left:2px solid var(--accent-soft);
  background:var(--panel);font-size:.9375rem;line-height:1.6;color:var(--text-2);max-width:64ch
}

/* ---- 04 Über Pia -------------------------------------------------------- */
.pia{display:grid;gap:clamp(2rem,4.5vw,4rem);align-items:start;grid-template-columns:minmax(0,1fr)}
@media (min-width:860px){.pia{grid-template-columns:minmax(260px,1fr) minmax(0,1.15fr)}}
@media (max-width:859px){.pia .portrait{max-width:420px}}
.pia .portrait{position:relative}
.pia .portrait img{width:100%;height:auto;border-radius:2px}
.pia .portrait::after{
  content:"";position:absolute;left:-34px;bottom:-30px;width:112px;height:112px;border-radius:50%;
  border:1px solid var(--accent-soft);pointer-events:none
}
.pia .quote{
  font:400 italic clamp(1.5rem,2.8vw,2.05rem)/1.28 var(--display);
  letter-spacing:-.012em;margin:0 0 1.75rem;max-width:22ch
}
.pia p+p{margin-top:1.05rem}
.pia .facts{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:2rem}
.pia .facts li{
  font:400 .6875rem var(--mono);letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--line);border-radius:999px;padding:.44rem .8rem;color:var(--text-2)
}

/* ---- 05 Ablauf ---------------------------------------------------------- */
.steps{display:grid;gap:clamp(1.5rem,3vw,2.25rem);margin-top:clamp(2.5rem,5vw,3.75rem);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,215px),1fr))}
.step{position:relative;padding-top:2.6rem}
.step::before{
  content:"";position:absolute;left:0;right:0;top:11px;height:1px;background:var(--line)
}
.step .dot{
  position:absolute;left:0;top:0;width:22px;height:22px;border-radius:50%;
  background:var(--canvas);border:1px solid var(--accent);display:grid;place-items:center;
  font:400 .5625rem var(--mono);color:var(--accent)
}
.sec--tint .step .dot{background:var(--canvas-2)}
.step h3{font:400 1.1875rem/1.25 var(--display);margin-bottom:.55rem}
.step p{font-size:.9375rem;line-height:1.58;color:var(--text-2)}

/* ---- 06 Bewertungen ----------------------------------------------------- */
.rating{display:flex;flex-wrap:wrap;align-items:baseline;gap:1rem 1.5rem;margin-top:2rem}
.rating .score{font:400 clamp(3rem,7vw,4.75rem)/1 var(--display);letter-spacing:-.02em}
.stars{display:flex;gap:.22rem;align-items:center}
.stars svg{width:19px;height:19px;color:var(--accent)}
.rating .meta{font:400 .8125rem var(--mono);color:var(--text-2)}
.quotes{display:grid;gap:clamp(1.25rem,2.6vw,2rem);margin-top:clamp(2.25rem,4.5vw,3.25rem);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,265px),1fr))}
.quotes blockquote{
  background:var(--panel);border:1px solid var(--line);border-radius:2px;
  padding:clamp(1.35rem,2.6vw,1.85rem);position:relative;overflow:hidden
}
.quotes blockquote::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:linear-gradient(var(--ink) 0%,var(--accent) 52%,var(--accent-soft) 100%)
}
.quotes p{font:400 1.0625rem/1.5 var(--display);letter-spacing:-.005em}
.quotes cite{display:block;margin-top:1.05rem;font:400 .6875rem var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--text-2);font-style:normal}

/* ---- 07 Fragen ---------------------------------------------------------- */
.faqwrap{display:grid;gap:clamp(2rem,4vw,3.5rem);margin-top:clamp(2.25rem,4.5vw,3.25rem);
  grid-template-columns:minmax(0,1fr)}
@media (min-width:960px){.faqwrap{grid-template-columns:minmax(0,1.55fr) minmax(0,.95fr)}}
.faq{max-width:70ch}
/* align-self:start ist hier nicht Kosmetik: als gestrecktes Rasterelement
   wäre die Karte so hoch wie die Fragenliste — unten mit einer großen
   leeren Fläche — und `position:sticky` bliebe wirkungslos. */
.askcard{background:var(--panel);border:1px solid var(--line);border-radius:2px;
  padding:clamp(1.5rem,3vw,2.1rem);position:sticky;top:6.5rem;align-self:start}
.askcard .ring{width:44px;height:44px;border-radius:50%;border:1px solid var(--accent-soft);
  display:grid;place-items:center;margin-bottom:1.2rem;color:var(--accent)}
.askcard .ring svg{width:19px;height:19px}
.askcard h3{font:400 1.375rem/1.25 var(--display);margin-bottom:.7rem}
.askcard p{font-size:.9375rem;line-height:1.6;color:var(--text-2);margin-bottom:1.5rem}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  list-style:none;cursor:pointer;padding:1.3rem 2.5rem 1.3rem 0;position:relative;
  font:400 1.125rem/1.35 var(--display);letter-spacing:-.005em;
  transition:color .3s var(--e-out)
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--accent)}
/* Der Pfeil sitzt in der Mitte der Zeile, nicht auf einer festen Höhe:
   sonst rutscht er bei zweizeiligen Fragen nach oben aus der Mitte. */
.faq summary::after{
  content:"";position:absolute;right:.35rem;top:50%;width:11px;height:11px;
  margin-top:-8px;
  border-right:1px solid currentColor;border-bottom:1px solid currentColor;
  transform:rotate(45deg);transition:transform .4s var(--e-out)
}
.faq details[open] summary::after{transform:rotate(225deg)}
.faq .a{padding:0 0 1.5rem;font-size:.9375rem;line-height:1.68;color:var(--text-2);max-width:62ch}
.faq .a p+p{margin-top:.85rem}

/* ---- 08 Kontakt --------------------------------------------------------- */
.contact{display:grid;gap:clamp(2rem,4.5vw,3.5rem);margin-top:clamp(2.25rem,4.5vw,3.25rem);
  grid-template-columns:minmax(0,1fr)}
@media (min-width:880px){.contact{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);align-items:start}}
.card{background:var(--panel);border:1px solid var(--line);border-radius:2px;padding:clamp(1.5rem,3vw,2.15rem)}
.card dl{display:grid;grid-template-columns:auto 1fr;gap:.9rem 1.35rem;align-items:baseline}
.card dt{font:400 .625rem var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--text-2)}
.card dd a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--line-strong);
  transition:border-color .3s var(--e-out),color .3s var(--e-out)}
.card dd a:hover{color:var(--accent);border-color:var(--accent)}
.card .row{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.85rem}
.mosaic{display:grid;grid-template-columns:1fr 1fr;gap:clamp(.55rem,1.2vw,.9rem);align-content:start}
.mosaic picture{display:block;overflow:hidden;border-radius:2px}
.mosaic img{width:100%;height:auto;display:block}

/* ---- Abschluss ---------------------------------------------------------- */
.final{position:relative;overflow:hidden;background:var(--dark);color:var(--on-dark);
  padding-block:clamp(5.5rem,15vh,11rem);text-align:left}
.final .bgimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:72% 42%;opacity:.78}
@media (max-width:720px){.final .bgimg{object-position:50% 26%;opacity:.7}}
.final .veil{position:absolute;inset:0;
  background:linear-gradient(100deg,rgba(10,11,13,.94) 0%,rgba(10,11,13,.72) 40%,rgba(10,11,13,.10) 100%)}
.final .wrap{position:relative}
.final h2{font:400 clamp(2.3rem,5.6vw,4.25rem)/1.02 var(--display);letter-spacing:-.02em;max-width:16ch}
.final p{margin-top:1.35rem;color:var(--on-dark-2);max-width:44ch;font-size:1.0625rem;line-height:1.6}
.final .row{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:2.4rem}
/* Der Lichtring antwortet: ein leiser Ringimpuls um den Buchungsknopf. */
.final .row .btn:not(.btn-ghost):hover,
.final .row .btn:not(.btn-ghost):focus-visible{
  box-shadow:0 0 0 7px rgba(232,199,154,.16),0 8px 24px rgba(0,0,0,.4)
}

/* ---- Fußzeile ----------------------------------------------------------- */
footer.site{background:var(--dark-2);color:var(--on-dark-2);padding-block:clamp(2.5rem,6vh,4rem);font-size:.875rem}
footer.site .grid{display:flex;flex-wrap:wrap;gap:1.5rem 3rem;align-items:flex-start;justify-content:space-between}
footer.site a{color:var(--on-dark-2);text-decoration:none;border-bottom:1px solid transparent;transition:color .3s var(--e-out),border-color .3s var(--e-out)}
footer.site a:hover{color:var(--on-dark);border-bottom-color:var(--accent-soft)}
footer.site .fbrand b{font:400 1.0625rem var(--display);color:var(--on-dark);display:block;letter-spacing:.03em}
footer.site nav{display:flex;flex-wrap:wrap;gap:1.35rem}
footer.site .fine{margin-top:2.25rem;padding-top:1.35rem;border-top:1px solid rgba(243,240,233,.14);
  font:400 .6875rem/1.7 var(--mono);letter-spacing:.04em;color:rgba(185,180,169,.72)}

/* ---- Klebender Handy-CTA ------------------------------------------------ */
.sticky-cta{
  position:fixed;left:0;right:0;bottom:0;z-index:70;display:none;
  padding:.7rem clamp(.75rem,4vw,1.25rem) calc(.7rem + env(safe-area-inset-bottom));
  background:rgba(235,234,230,.93);backdrop-filter:blur(14px);border-top:1px solid var(--line);
  transform:translateY(110%);transition:transform .5s var(--e-out)
}
.sticky-cta.show{transform:none}
.sticky-cta .btn{width:100%}

/* ---- Rechtstexte -------------------------------------------------------- */
.legal{padding-block:clamp(7rem,14vh,10rem) clamp(4rem,9vh,7rem);max-width:74ch}
/* Rechtstexte leben von langen deutschen Komposita. Sie dürfen trennen —
   im Fließtext der Startseite wäre das falsch, hier ist es richtig. */
.legal h1,.legal h2,.legal h3,.legal p,.legal li{hyphens:auto;-webkit-hyphens:auto}
.legal h1{font:400 clamp(1.85rem,7vw,3.1rem)/1.06 var(--display);letter-spacing:-.018em;margin-bottom:2rem}
.legal h2{font:400 1.375rem/1.3 var(--display);margin:2.5rem 0 .85rem}
.legal h3{font:700 .9375rem var(--text);margin:1.6rem 0 .5rem}
.legal p,.legal li{font-size:.9375rem;line-height:1.72;color:var(--ink-2)}
.legal p+p{margin-top:.9rem}
.legal ul{list-style:disc;padding-left:1.25rem;margin:.7rem 0}
.legal li{margin-bottom:.35rem}
.legal a{color:var(--accent)}
.legal .todo{background:#F7EFE2;border:1px dashed var(--accent);padding:.85rem 1.1rem;border-radius:2px;
  font-size:.875rem;color:var(--accent-hover);margin:.6rem 0}
/* Steht der Hinweis mitten in einem Satz, muss er als inline-block laufen.
   Als reines Inline-Element würde sein Innenabstand über die Zeile hinaus-
   wachsen und die Zeile darüber verdecken. */
.legal span.todo{display:inline-block;padding:.45rem .75rem;margin-block:.2rem;vertical-align:middle}
.legal .back{display:inline-flex;align-items:center;gap:.5rem;margin-top:3rem;
  font:400 .6875rem var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--text-2);text-decoration:none}
.legal .back:hover{color:var(--accent)}

/* ==========================================================================
   Der Static-Hero-Gate. Diese fünf Bedingungen stehen wortgleich im JS.
   ========================================================================== */
@media (max-width:720px),
       (orientation:portrait) and (max-width:1024px),
       (orientation:portrait) and (pointer:coarse),
       (orientation:landscape) and (pointer:coarse) and (max-height:560px),
       (prefers-reduced-motion:reduce){
  .hero{height:auto}
  .stage{position:relative;height:100svh;min-height:520px}
  .stage>video,.stage>.poster,.stage>.glimmer,.stage>.flyaways,.bands,.cue{display:none}
  .mhero{display:block}
  .sticky-cta{display:block}
}
/* Ohne JavaScript gibt es keinen Scrollfilm: der statische Hero übernimmt,
   nichts bleibt leer oder unsichtbar. */
html:not(.js) .hero{height:auto}
html:not(.js) .stage{position:relative;height:100svh;min-height:520px}
html:not(.js) .stage>video,html:not(.js) .stage>.poster,
html:not(.js) .stage>.glimmer,html:not(.js) .stage>.flyaways,
html:not(.js) .bands,html:not(.js) .cue{display:none}
html:not(.js) .mhero{display:block}
html:not(.js) .hero-exit{
  height:110px;
  background:linear-gradient(180deg,
    rgba(235,234,230,0) 0%,rgba(235,234,230,.06) 50%,rgba(235,234,230,.2) 70%,
    rgba(235,234,230,.55) 85%,rgba(235,234,230,.92) 96%,var(--canvas) 100%)
}
/* ---- Flache Fenster ----------------------------------------------------- */
@media (max-height:560px){.cue{display:none}}

/* ---- Handy-Feinschliff -------------------------------------------------- */
@media (max-width:900px){
  .nav .links{display:none}
  /* Der Menüknopf steht ganz außen, der Terminknopf davor. */
  .nav .cta{margin-left:auto;order:2}
  .navtoggle{display:grid;order:3;margin-left:.45rem;margin-right:-.5rem}
  .thread{display:none}
}
/* Bei geöffnetem Menü tritt die Kopfzeile in den Vordergrund: der
   Schließen-Knopf liegt über der Fläche und bekommt ihren dunklen Grund.
   Der Terminknopf verschwindet dabei, weil das Menü selbst einen führt —
   zwei gleiche Angebote nebeneinander sind ein Fehler, kein Angebot. */
body.menu-open .nav{z-index:60;background:transparent;backdrop-filter:none;border-bottom-color:transparent}
body.menu-open .nav .brand b,body.menu-open .navtoggle{color:var(--on-dark)}
body.menu-open .nav .brand span{color:rgba(243,240,233,.82)}
body.menu-open .nav .brand svg{color:var(--on-dark)}
body.menu-open .nav .cta{opacity:0;pointer-events:none;transition:opacity .2s var(--e-out)}
@media (max-width:520px){
  .nav .cta .lbl{display:none}
  .nav .cta{padding:.7rem .85rem}
  footer.site .grid{flex-direction:column}
}
/* Auf schmalen Geräten stehen die beiden Handlungsknöpfe untereinander und
   auf voller Breite: zwei unterschiedlich breite Knöpfe nebeneinander
   wirken zufällig, und der Daumen trifft eine ganze Zeile leichter. */
@media (max-width:560px){
  .card .row,.final .row{flex-direction:column;align-items:stretch}
  .card .row .btn,.final .row .btn{width:100%;max-width:26rem}
}
@media (pointer:coarse){
  /* Telefon- und Mailverweise mitten im Fließtext bekommen eine höhere
     Trefferfläche, ohne den Zeilenfall zu verändern: der Innenabstand
     wächst über die Zeile hinaus, das Textbild bleibt gleich. */
  .legal a[href^="tel:"],.legal a[href^="mailto:"]{padding-block:.55rem}
  .btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .brand{min-height:44px;padding-block:.3rem}
  .faq summary{padding-block:1.15rem;min-height:44px}
  .cmp .knob{width:58px;height:58px;margin:-29px 0 0 -29px}
  footer.site nav a,.card dd a,.legal .back{display:inline-flex;align-items:center;min-height:44px}
}

/* ==========================================================================
   Reduzierte Bewegung, vollständig und in beide Richtungen
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;transition-delay:0ms!important
  }
  .rise,.stag>*{opacity:1!important;transform:none!important}
  .thread path{stroke-dashoffset:0!important}
  .env .halo{animation:none;transform:translate(-50%,-50%)}
  section.inview .eyebrow .num::after{animation:none;opacity:0}
  .sticky-cta{transform:none}
}
body.motion-off .rise,body.motion-off .stag>*{opacity:1!important;transform:none!important}
body.motion-off .thread path{stroke-dashoffset:0!important}
body.motion-off .env .halo{animation:none}
body.motion-off .eyebrow .num::after{animation:none;opacity:0}
/* Beide Ebenen zusammen anhalten. Stünde hier nur das Bild, läge ein
   unbewegtes Standbild unter einem noch zoomenden Film. */
body.motion-off .mhero img,body.motion-off .mhero .mvid{animation:none;transform:none}
body.motion-off .mhero .copy>*{animation:none;opacity:1;transform:none}

/* Animationen anhalten, wenn der Tab versteckt ist */
body.paused *,body.paused *::before,body.paused *::after{animation-play-state:paused!important}
