/* ══════════════════════════════════════════════════════════ SCHRIFT ══ */
/* Beide Schriften liegen als Datei im Projekt (assets/fonts/) und werden
   NICHT von Google geladen. Beim Laden von fonts.gstatic.com erfährt Google
   die IP-Adresse jedes Besuchers; deutsche Gerichte haben das mehrfach als
   Verstoß gegen die DSGVO gewertet (LG München I, 20.01.2022, 3 O 17493/20).
   Selbst ausgeliefert entsteht die Übertragung gar nicht erst — deshalb
   steht dazu auch nichts mehr in der Datenschutzerklärung.

   Beides sind Variable Fonts: eine Datei je Zeichensatz deckt den ganzen
   Gewichtsbereich ab, es gibt also nicht je Schnitt einen eigenen Download.

   Die unicode-range trennt latin von latin-ext. Deutsch (ä, ö, ü, ß) steckt
   vollständig in latin; latin-ext wird nur geholt, wenn tatsächlich ein
   Zeichen daraus vorkommt — etwa in einem polnischen oder tschechischen
   Namen. Für den Regelfall kostet die zweite Datei also nichts.

   font-display:swap zeigt den Text sofort in der Ersatzschrift und tauscht
   nach. Lieber ein kurzer Sprung als eine Sekunde leere Seite.

   Lizenz: beide unter der SIL Open Font License 1.1 — das Ausliefern von
   eigenem Server ist ausdrücklich erlaubt. Siehe assets/fonts/LIZENZ.txt. */

@font-face{
  font-family:'Cormorant Garamond';
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url('fonts/cormorant-garamond-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face{
  font-family:'Cormorant Garamond';
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url('fonts/cormorant-garamond-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('fonts/inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ═══════════════════════════════════════════════════════════ TOKENS ══ */

:root{
  /* ── Farbe ────────────────────────────────────────────────────────────
     Die Seite läuft auf warmem Beige. Das Hero-Video ist aber Kerzenlicht
     im Dunkeln — cremefarbene Schrift darüber ist die einzige, die trägt.
     Deshalb zwei vollständige Sets: ein helles für die Seite und ein
     dunkles für die „dunklen Inseln“ (Hero-Bühne, Header über dem Video).
     Die Rollen-Token unten zeigen jeweils auf eines der beiden Sets — jede
     Regel im Stylesheet benutzt nur die Rolle und funktioniert dadurch in
     beiden Zusammenhängen unverändert.

     Namenshinweis: --ink meint die Fläche, --cream den Text darauf. Die
     Namen stammen aus der dunklen Fassung; die Rolle ist gleich geblieben,
     nur der Wert hat sich gedreht.

     HELLES SET — Kontraste gegen --l-ink / --l-ink-raise geprüft */
  --l-ink:         #F2EADD;   /* Seite — warmes Beige                    */
  --l-ink-raise:   #EAE0D0;   /* abgesetzte Bänder                       */
  --l-ink-card:    #FAF5EC;   /* Karten, Formularfelder                  */
  --l-cream:       #241C14;   /* Überschriften, Text      14.1:1         */
  --l-cream-mute:  rgba(36,28,20,.78);   /* Fließtext      7.4:1         */
  --l-cream-faint: rgba(36,28,20,.66);   /* Meta           5.0:1         */
  --l-brass:       #7F5C22;   /* Akzent, CTA-Fläche        5.1:1         */
  --l-brass-lift:  #5E4116;   /* Hover, Fokusring          7.8:1         */
  --l-line:        rgba(36,28,20,.14);
  --l-line-strong: rgba(36,28,20,.28);

  /* DUNKLES SET — für Flächen, die über dem Video liegen, und für den
     Dark-Mode-Umschalter (unten). Werte aus der früheren rein dunklen
     Fassung übernommen, Kontraste also schon gegen --d-ink geprüft. */
  --d-ink:         #0E0B08;
  --d-ink-raise:   #15100B;
  --d-ink-card:    #1A140E;
  --d-cream:       #F4EDE3;
  --d-cream-mute:  rgba(244,237,227,.78);
  --d-cream-faint: rgba(244,237,227,.62);
  --d-brass:       #C8A464;
  --d-brass-lift:  #E3C68F;
  --d-line:        rgba(244,237,227,.14);
  --d-line-strong: rgba(244,237,227,.28);
  --d-danger:      #E8927C;
  --d-surface-hi:  #241C13;   /* Karten-Hover, fokussierte Formularfelder */

  --l-danger:      #A6371D;
  --l-surface-hi:  #FFFCF6;

  /* AKTIVE ROLLE — Grundzustand ist hell; der Schalter unten dreht diese
     Rollen auf das dunkle Set, ohne dass Regeln im Rest des Stylesheets
     etwas davon wissen müssen. */
  --ink:         var(--l-ink);
  --ink-raise:   var(--l-ink-raise);
  --ink-card:    var(--l-ink-card);
  --cream:       var(--l-cream);
  --cream-mute:  var(--l-cream-mute);
  --cream-faint: var(--l-cream-faint);
  --brass:       var(--l-brass);
  --brass-lift:  var(--l-brass-lift);
  --line:        var(--l-line);
  --line-strong: var(--l-line-strong);
  --danger:      var(--l-danger);
  --surface-hi:  var(--l-surface-hi);

  /* Bleibt außerhalb der .stage/.hdr-Inseln unangetastet — für Übergänge
     wie den Verlauf am Fuß des Hero-Videos, die wissen müssen, wie die
     Seite *als Ganzes* gerade eingefärbt ist, nicht nur die Insel. */
  --page-ink: var(--l-ink);

  --font-serif: 'Cormorant Garamond','Iowan Old Style','Palatino Linotype',Palatino,Georgia,serif;
  --font-sans:  'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;

  /* Abstände — eine einzige Skala, damit nichts „fast gleich“ ist */
  --s1:.5rem;  --s2:.75rem; --s3:1rem;   --s4:1.5rem;
  --s5:2rem;   --s6:3rem;   --s7:4.5rem; --s8:7rem;

  --radius:  2px;
  --radius-lg: 4px;
  --pill:  999px;

  /* Z-Index-Skala: alles darüber ist ein Fehler */
  --z-base:1; --z-sticky:20; --z-header:40; --z-drawer:50; --z-modal:60;

  --wrap: 72rem;
  --ease: cubic-bezier(.22,.61,.36,1);
  --hdr-h: 4.5rem;

  /* Sorgt dafür, dass native Bedienelemente — Datumswähler, Auswahllisten,
     Bildlaufleisten — in der hellen Variante gezeichnet werden. Ohne das
     bliebe das Kalendersymbol im Datumsfeld hell auf hell. */
  color-scheme:light;
}

/* ── Dark Mode ────────────────────────────────────────────────────────
   Der Umschalter in der Kopfzeile setzt data-theme am <html>-Element
   (Skript unten, noch vor dem ersten Rendern, damit nichts aufblitzt).
   Alle Rollen-Token drehen auf das dunkle Set — jede Regel im Stylesheet
   benutzt nur die Rolle und funktioniert dadurch unverändert weiter. */
:root[data-theme="dark"]{
  --ink:         var(--d-ink);
  --ink-raise:   var(--d-ink-raise);
  --ink-card:    var(--d-ink-card);
  --cream:       var(--d-cream);
  --cream-mute:  var(--d-cream-mute);
  --cream-faint: var(--d-cream-faint);
  --brass:       var(--d-brass);
  --brass-lift:  var(--d-brass-lift);
  --line:        var(--d-line);
  --line-strong: var(--d-line-strong);
  --danger:      var(--d-danger);
  --surface-hi:  var(--d-surface-hi);
  --page-ink:    var(--d-ink);
  color-scheme:dark;
}

/* ── Dunkle Inseln ──────────────────────────────────────────────────────
   Die Hero-Bühne und der Header, solange er noch über dem Video steht.
   Beide schalten die Rollen-Token auf das dunkle Set um; alles darin —
   Überschriften, Buttons, Ränder, Fortschrittsbalken — folgt automatisch,
   ohne dass es dafür eigene Regeln braucht. Im Dark Mode ist das ohnehin
   schon die aktive Rolle — die Insel-Regel dupliziert dort nur denselben
   Wert. */
.stage,
.hdr{
  --ink:         var(--d-ink);
  --ink-raise:   var(--d-ink-raise);
  --ink-card:    var(--d-ink-card);
  --cream:       var(--d-cream);
  --cream-mute:  var(--d-cream-mute);
  --cream-faint: var(--d-cream-faint);
  --brass:       var(--d-brass);
  --brass-lift:  var(--d-brass-lift);
  --line:        var(--d-line);
  --line-strong: var(--d-line-strong);
  color:var(--cream);
}

/* Umgeschaltet wird nicht beim ersten Scroll, sondern erst, wenn der beige
   Inhalt tatsächlich hinter der Kopfzeile steht — der Hero scrollt über
   mehrere Bildschirmhöhen, ein beiger Balken läge sonst die ganze Zeit über
   dem dunklen Video. Gesetzt wird die Klasse in syncHeader(). Im Dark Mode
   ist "die Seite dahinter" selbst dunkel, also bleibt die Kopfzeile bei der
   dunklen Insel-Fassung — deshalb greift diese Regel nur im Light Mode. */
:root:not([data-theme="dark"]) .hdr.is-light{
  --ink:         var(--l-ink);
  --ink-raise:   var(--l-ink-raise);
  --ink-card:    var(--l-ink-card);
  --cream:       var(--l-cream);
  --cream-mute:  var(--l-cream-mute);
  --cream-faint: var(--l-cream-faint);
  --brass:       var(--l-brass);
  --brass-lift:  var(--l-brass-lift);
  --line:        var(--l-line);
  --line-strong: var(--l-line-strong);
}

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

html{
  scroll-behavior:smooth;
  /* Anker landen unter dem fixierten Header statt dahinter */
  scroll-padding-top:calc(var(--hdr-h) + 1.5rem);
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--ink);
  color:var(--cream);
  font-family:var(--font-sans);
  font-size:1.0625rem;      /* 17px — über dem 16px-Minimum für Mobil */
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;

  /* Bewusst „clip“ statt „hidden“: overflow-x:hidden macht den body zu einem
     eigenen Scroll-Container, window.scrollY bliebe auf 0 und das komplette
     Scroll-Scrubbing wäre tot. „clip“ schneidet ab, ohne das zu tun. */
  overflow-x:clip;
}

body.is-locked{ overflow:hidden; }

img,video,svg{ display:block; max-width:100%; }

/* Ein einziger, überall sichtbarer Fokusstil — hell genug für dunkle Flächen
   und für die messingfarbene CTA. */
:focus-visible{
  outline:2px solid var(--brass-lift);
  outline-offset:3px;
  border-radius:var(--radius);
}
:focus:not(:focus-visible){ outline:none; }

::selection{ background:var(--brass); color:var(--ink); }

.sr-only{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

.skip{
  position:fixed; top:var(--s3); left:var(--s3); z-index:var(--z-modal);
  transform:translateY(-160%);
  padding:.75rem 1.25rem;
  background:var(--brass); color:var(--ink);
  font-size:.8rem; letter-spacing:.12em; text-transform:uppercase;
  text-decoration:none; border-radius:var(--pill);
  transition:transform .2s var(--ease);
}
.skip:focus{ transform:none; }

/* ═══════════════════════════════════════════════════════ BAUSTEINE ══ */

.wrap{
  max-width:var(--wrap);
  margin-inline:auto;
  padding-inline:clamp(1.25rem,5vw,3.5rem);
}

.section{ padding-block:clamp(4.5rem,11vw,var(--s8)); }
.section--raise{ background:var(--ink-raise); }
.section[id]{ scroll-margin-top:calc(var(--hdr-h) + 1rem); }

.eyebrow{
  margin:0 0 var(--s4);
  display:flex; align-items:center; gap:.75rem;
  font-size:.68rem; font-weight:500;
  letter-spacing:.34em; text-transform:uppercase;
  color:var(--brass);
}
.eyebrow::before{
  content:''; width:1.75rem; height:1px;
  background:currentColor; opacity:.6; flex:none;
}
.eyebrow--center{ justify-content:center; }

h1,h2,h3{ font-family:var(--font-serif); font-weight:400; margin:0; }

.h2{
  font-size:clamp(1.9rem,4.4vw,3rem);
  line-height:1.15;
  letter-spacing:.005em;
  text-wrap:balance;
  margin:0 0 var(--s4);
}
.h3{
  font-size:clamp(1.3rem,2.4vw,1.55rem);
  line-height:1.25;
}

.lede{
  margin:0;
  max-width:42rem;             /* ~68 Zeichen pro Zeile */
  font-size:clamp(1.02rem,1.8vw,1.15rem);
  color:var(--cream-mute);
  text-wrap:pretty;
}
.section--center{ text-align:center; }
.section--center .lede{ margin-inline:auto; }

.divider{ height:1px; background:var(--line); border:0; margin:0; }

/* Platzhalter, die vor dem Livegang ersetzt werden müssen.
   Bewusst sichtbar markiert, damit nichts davon versehentlich online geht. */
.todo{
  color:var(--brass);
  border-bottom:1px dotted rgba(127,92,34,.55);
  font-style:normal;
}

/* ═════════════════════════════════════════════════════════ BUTTONS ══ */

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.6rem;
  min-height:48px;                       /* > 44px Touch-Ziel */
  padding:.9rem 2rem;
  border:1px solid var(--line-strong);
  border-radius:var(--pill);
  /* Leichte Tönung aus der jeweiligen Textfarbe — funktioniert dadurch auf
     hellem Grund wie auf der dunklen Hero-Bühne. Fallback für Browser ohne
     color-mix: schlicht kein Füllton, der Rand trägt den Button allein. */
  background:transparent;
  background:color-mix(in srgb,var(--cream) 5%,transparent);
  color:var(--cream);
  font-family:var(--font-sans);
  font-size:.74rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase;
  text-decoration:none; cursor:pointer;
  /* Nur Farbe/Rahmen animieren — kein Scale, das das Layout verschiebt */
  transition:background .25s var(--ease),border-color .25s var(--ease),color .25s var(--ease);
}
.btn:hover{ background:var(--cream); border-color:var(--cream); color:var(--ink); }

.btn--solid{ background:var(--brass); border-color:var(--brass); color:var(--ink); }
.btn--solid:hover{ background:var(--brass-lift); border-color:var(--brass-lift); color:var(--ink); }

.btn--ghost{ background:transparent; }
/* 48 px, nicht 44: MASTER.md ("Umsetzungsentscheidungen") schreibt fuer
   Touch-Ziele mindestens 44 px vor, fuer BUTTONS aber 48 px. Das galt fuer
   .theme-toggle, .swipe__arrow und .icon-btn genauso — alle waren auf 44 px
   gebaut und verfehlten damit die eigene Vorgabe. */
.btn--sm{ min-height:48px; padding:.7rem 1.4rem; font-size:.7rem; }

.btn[disabled],.btn[aria-busy="true"]{ opacity:.6; pointer-events:none; }

.btn__spin{
  width:14px; height:14px; flex:none;
  border:2px solid currentColor; border-top-color:transparent;
  border-radius:50%;
  animation:spin .7s linear infinite;
  display:none;
}
.btn[aria-busy="true"] .btn__spin{ display:block; }
@keyframes spin{ to{ transform:rotate(360deg); } }

/* Textlink mit Unterstreichung, die beim Hover wächst */
.link{
  color:var(--cream); text-decoration:none;
  background-image:linear-gradient(var(--brass),var(--brass));
  background-repeat:no-repeat;
  background-size:100% 1px;
  background-position:0 100%;
  padding-bottom:2px;
  transition:background-size .25s var(--ease),color .25s var(--ease);
}
.link:hover{ color:var(--brass-lift); background-size:100% 2px; }

/* ══════════════════════════════════════════════════════════ HEADER ══ */

/* Kein mix-blend-mode mehr: über hellen Videobildern wurde die Navigation
   damit unlesbar. Stattdessen ein eigener Verlauf hinter der Leiste und
   ab dem ersten Scroll eine deckende Fläche. */
.hdr{
  position:fixed; inset:0 0 auto 0; z-index:var(--z-header);
  height:var(--hdr-h);
  display:flex; align-items:center;
  transition:background .3s var(--ease),backdrop-filter .3s var(--ease),border-color .3s var(--ease);
  border-bottom:1px solid transparent;
}
.hdr::before{
  content:''; position:absolute; inset:0; z-index:-1;
  background:linear-gradient(to bottom,rgba(14,11,8,.72),rgba(14,11,8,0));
  transition:opacity .3s var(--ease);
}
.hdr.is-stuck{
  /* Über dem Video: dunkel, damit die Leiste mit dem Bild verschmilzt */
  background:rgba(20,16,11,.86);
  backdrop-filter:blur(14px) saturate(1.2);
  -webkit-backdrop-filter:blur(14px) saturate(1.2);
  border-bottom-color:var(--line);
}
/* Über der beigen Seite (nur Light Mode, siehe .hdr.is-light oben) */
:root:not([data-theme="dark"]) .hdr.is-stuck.is-light{ background:rgba(242,234,221,.86); }
.hdr.is-stuck::before{ opacity:0; }
/* Der Verlauf oben ist nur dafür da, die Beschriftung über dem Hero-Video
   lesbar zu halten. Auf den Unterseiten liegt die Kopfzeile von der ersten
   Bildzeile an über Beige — dort sähe er wie ein Schatten am oberen
   Fensterrand aus. */
.hdr.is-light::before{ opacity:0; }

/* Harter Schnitt beim Farbwechsel der Kopfzeile — gesetzt von syncHeader()
   fuer genau einen Frame. Siehe Begruendung dort. */
.hdr--instant,
.hdr--instant *{ transition:none !important; }

.hdr__inner{
  width:100%;
  display:flex; align-items:center; justify-content:space-between; gap:var(--s4);
}

.hdr__mark{
  font-family:var(--font-serif);
  font-size:.92rem; letter-spacing:.34em; text-transform:uppercase;
  color:var(--cream); text-decoration:none; white-space:nowrap;
  /* Der Schriftzug ist nur 25 px hoch — als Tippziel zu wenig. Das Polster
     bringt ihn auf 44 px, ohne die Kopfzeile zu vergroessern: der
     Theme-Schalter daneben ist ohnehin schon 44 px hoch. */
  display:inline-flex; align-items:center; min-height:44px;
}

.hdr__nav{ display:flex; align-items:center; gap:clamp(1rem,2.4vw,2rem); }

.hdr__link{
  position:relative;
  color:var(--cream-mute); text-decoration:none;
  font-size:.72rem; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase;
  padding-block:.35rem;
  transition:color .25s var(--ease);
}
/* Die Navigationspunkte sind nur 30 px hoch. Polster wuerde die Unterstreichung
   (::after, bottom:0) vom Text wegschieben — deshalb wie bei .swipe__dot eine
   unsichtbare Trefferflaeche ueber ::before: 30 + 2x7 = 44 px, ohne dass sich
   optisch etwas aendert. Seitlich bleibt der Nav-Abstand (min. 1rem) frei,
   die Zonen zweier Nachbarn beruehren sich also nicht. */
.hdr__link::before{
  content:''; position:absolute; left:0; right:0;
  top:-7px; bottom:-7px;
}
.hdr__link::after{
  content:''; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--brass);
  transform:scaleX(0); transform-origin:0 50%;
  transition:transform .25s var(--ease);
}
/* aria-current ohne Wertprüfung: die Startseite markiert beim Scrollen mit
   "true", der Seitengenerator schreibt bei mehreren Seiten "page". Beide
   sollen gleich aussehen. */
.hdr__link:hover,.hdr__link[aria-current]{ color:var(--cream); }
.hdr__link:hover::after,.hdr__link[aria-current]::after{ transform:scaleX(1); }
.drawer__link[aria-current]{ color:var(--brass); }

/* Bedienelemente rechts — Schalter und Burger als eine Gruppe. Damit hat die
   Kopfzeile drei Anker statt vier: Wortmarke links, Navigation mittig,
   Werkzeuge rechts. */
.hdr__tools{ display:flex; align-items:center; gap:.25rem; flex:none; }

/* Dark-/Light-Mode-Schalter */
.theme-toggle{
  display:flex; align-items:center; justify-content:center;
  width:48px; height:48px; flex:none;             /* volles Touch-Ziel */
  background:none; border:0; cursor:pointer; color:var(--cream-mute);
  border-radius:var(--pill);
  transition:background .2s var(--ease), color .2s var(--ease);
}
.theme-toggle:hover{ background:var(--line); color:var(--cream); }
.theme-toggle__icon{
  width:19px; height:19px;
  stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
  fill:none;
}
.theme-toggle__icon--moon{ fill:currentColor; stroke:none; }
.theme-toggle__icon--sun{ display:none; }
:root[data-theme="dark"] .theme-toggle__icon--sun{ display:block; }
:root[data-theme="dark"] .theme-toggle__icon--moon{ display:none; }

/* Hamburger */
.burger{
  display:none;
  width:48px; height:48px;                /* volles Touch-Ziel */
  align-items:center; justify-content:center;
  background:none; border:0; cursor:pointer; color:var(--cream);
  border-radius:var(--pill);
}
.burger__box{ width:22px; height:14px; position:relative; }
.burger__box span{
  position:absolute; left:0; right:0; height:1.5px;
  background:currentColor; border-radius:2px;
  transition:transform .3s var(--ease),opacity .2s var(--ease);
}
.burger__box span:nth-child(1){ top:0; }
.burger__box span:nth-child(2){ top:50%; margin-top:-.75px; }
.burger__box span:nth-child(3){ bottom:0; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(6.25px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-6.25px) rotate(-45deg); }

/* Schublade — die alte Seite hatte unter 640px schlicht keine Navigation */
.drawer{
  position:fixed; inset:0; z-index:var(--z-drawer);
  background:color-mix(in srgb, var(--ink) 97%, transparent);
  backdrop-filter:blur(20px);
  -webkit-backdrop-filter:blur(20px);
  display:flex; flex-direction:column;
  padding:calc(var(--hdr-h) + var(--s5)) clamp(1.25rem,6vw,3rem) var(--s6);
  opacity:0;
  transition:opacity .3s var(--ease);
}
.drawer.is-open{ opacity:1; }

/* Der geschlossene Zustand läuft bewusst allein über das hidden-Attribut,
   nicht über visibility. Mit einer visibility-Transition ist das Element im
   Moment des Öffnens noch als unsichtbar berechnet — focus() greift dann
   nicht, und die Schublade öffnet ohne Tastaturfokus.
   Muss die display:flex-Regel oben schlagen. */
.drawer[hidden]{ display:none; }

.drawer__nav{ display:flex; flex-direction:column; gap:.25rem; }
.drawer__link{
  display:block;
  padding:var(--s3) 0;
  border-bottom:1px solid var(--line);
  color:var(--cream); text-decoration:none;
  font-family:var(--font-serif);
  font-size:1.6rem; line-height:1.2;
  transition:color .25s var(--ease),padding-left .25s var(--ease);
}
.drawer__link:hover{ color:var(--brass-lift); padding-left:.5rem; }
.drawer__foot{ margin-top:auto; padding-top:var(--s5); display:grid; gap:var(--s3); }
.drawer__meta{ font-size:.85rem; color:var(--cream-faint); }

@media (max-width:860px){
  .hdr__nav{ display:none; }
  .burger{ display:flex; }
}

/* ═══════════════════════════════════════════════ HERO / SCROLLYTELLING ══ */

/* Die Höhe bestimmt, wie weit gescrollt wird, bis das Video durch ist.
   Von 480vh auf 380vh gekürzt: die alte Fassung ließ Besucher fast fünf
   Bildschirmhöhen scrollen, bevor überhaupt Inhalt kam. */
.scrolly{ position:relative; height:380vh; }

/* Übergang in die helle Seite.

   Die Bühne bleibt dunkel — das Video ist Kerzenlicht, alles andere trüge
   nicht. Der Schnitt zur beigen Seite darunter wäre aber eine harte Kante.
   Dieser Verlauf sitzt am unteren Ende des Scrollbereichs, also genau dort,
   wo die Bühne ihren Halt verliert: das Bild löst sich beim Weiterscrollen
   nach unten ins Beige auf. Solange die Bühne klebt, ist davon nichts zu
   sehen — die untere, blumenreiche Bildhälfte bleibt unangetastet. */
.scrolly::after{
  content:''; position:absolute; left:0; right:0; bottom:0;
  height:18vh;
  background:linear-gradient(to bottom,
    color-mix(in srgb, var(--page-ink) 0%, transparent) 0%,
    color-mix(in srgb, var(--page-ink) 65%, transparent) 62%,
    var(--page-ink) 100%);
  pointer-events:none;
}

.stage{
  position:sticky; top:0;
  height:100svh;
  overflow:hidden;
  background:var(--ink);
}

.stage__video{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  transform:scale(1.04);     /* verdeckt Ränder beim Skalieren */
}

/* Das Hochformat-Video (hero-9x16.mp4) zeigt den Tisch nur in der unteren
   Bildhälfte, darüber viel leerer Raum mit den Lichterketten. Auf schmalen
   Scheiben (dieselbe Bedingung wie beim Quellenwechsel in site.js) schneidet
   object-fit:cover dort nichts weg — bei diesem Seitenverhältnis passt die
   volle Videohöhe ohnehin in den Rahmen. Der Tisch bliebe also im unteren
   Drittel hängen, nicht mittig. Deshalb hier stärker hineinzoomen und der
   Ursprung nach unten verschieben: das schneidet überproportional oben ab
   (leere Decke) und lässt den Tisch optisch nach oben in die Bildmitte
   rücken, ohne die horizontale Zentrierung zu verändern. */
@media (max-aspect-ratio: 3/4){
  .stage__video{
    transform:scale(1.3);
    transform-origin:50% 70%;
  }
}

/* Vignette.

   Die Werte sind am Videomaterial gemessen, nicht geschätzt: die hellsten
   Stellen (Kerzenlicht, Leinenläufer) erreichen RGB ~230. Cremeweiße Schrift
   käme darüber ungedämpft auf 1,3:1. In der oberen Bildhälfte sind gemessen
   40 % Deckkraft für AA und 59 % für AAA nötig — der Verlauf hält dort ~72 %.

   Bewusst ein Verlauf von oben statt eines dunklen Flecks in der Mitte: das
   liest sich wie eine Farbkorrektur, und die blumenreiche untere Bildhälfte
   bleibt unangetastet. */
.stage__veil{
  position:absolute; inset:0;
  background:
    linear-gradient(to bottom,
      rgba(14,11,8,.80)  0%,
      rgba(14,11,8,.74) 44%,
      rgba(14,11,8,.48) 54%,
      rgba(14,11,8,0)   68%),
    linear-gradient(to top, rgba(14,11,8,.84) 0%, rgba(14,11,8,0) 20%),
    radial-gradient(130% 96% at 50% 50%, rgba(14,11,8,0) 46%, rgba(14,11,8,.44) 100%);
  pointer-events:none;
}

/* Der Textbereich belegt die oberen 58 % der Bühne und zentriert darin.
   So landet er zuverlässig in der abgedunkelten Zone — auch auf flachen
   Fenstern, wo eine reine vh-Verschiebung kippen würde. */
.captions{
  position:absolute; inset:0 0 auto 0;
  height:58%;
  display:grid; place-items:center;
  padding:calc(var(--hdr-h) + 1.5rem) clamp(1.5rem,5vw,4rem) 0;
  pointer-events:none;
}

.caption{
  grid-area:1/1;
  max-width:34rem;
  text-align:center;
  will-change:opacity,transform;
}
/* Grundzustand ohne JavaScript: nur die erste Karte steht — die Seite hat
   damit immer eine sichtbare H1, statt alle vier Karten übereinanderzulegen.
   Mit JavaScript setzt paintCaptions() sofort Inline-Deckkraft auf alle
   Karten; Inline schlägt diese Regeln, ein Klassen-Umschalter ist unnötig. */
.caption{ opacity:0; }
.caption:first-child{ opacity:1; }
.caption--wide{ max-width:44rem; }
.caption > *{ margin:0; }
.caption a{ pointer-events:auto; }

/* ── Swipe-Leiste (Leistungen) ───────────────────────────────────────────

   Gebaut mit CSS scroll-snap statt einer Karussell-Bibliothek. Das bringt
   von Haus aus das native Wischen mit Schwung auf dem Handy, funktioniert
   auch ohne JavaScript und ist für Tastatur und Screenreader nur ein
   scrollbarer Bereich — also nichts, was man erst zugänglich machen müsste.

   Auf breiten Fenstern stehen alle drei Karten nebeneinander und es gibt
   nichts zu wischen. Das ist Absicht: Inhalte dort hinter eine Geste zu
   legen, wäre eine Verschlechterung. Die Bedienelemente blenden sich in
   dem Fall selbst aus. */

.swipe{ margin-top:clamp(2.5rem,5vw,3.5rem); }

.swipe__track{
  display:flex;
  gap:clamp(1rem,2.5vw,1.75rem);
  overflow-x:auto;
  overscroll-behavior-x:contain;   /* kein versehentliches Zurück-Wischen */
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;

  /* Eigene Fortschrittsanzeige unten, deshalb keine Systemleiste */
  scrollbar-width:none;
  padding-bottom:.25rem;
}
.swipe__track::-webkit-scrollbar{ display:none; }

.swipe__track:focus-visible{
  outline:2px solid var(--brass);
  outline-offset:6px;
  border-radius:4px;
}

.swipe__track > .card{
  flex:0 0 auto;
  /* Etwas schmaler als das Fenster, damit die nächste Karte angeschnitten
     hervorschaut. Ohne diesen Anschnitt merkt niemand, dass es weitergeht. */
  width:min(78vw,21rem);
  scroll-snap-align:start;
}

@media (min-width:900px){
  /* Drei nebeneinander, exakt wie im bisherigen Raster */
  .swipe__track > .card{
    width:calc((100% - 2 * clamp(1rem,2.5vw,1.75rem)) / 3);
  }
}

/* ── Bedienzeile ──────────────────────────────────────────────────────── */

.swipe__ui{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem;
  margin-top:1.5rem;
}
.swipe__ui[hidden]{ display:none; }

.swipe__dots{ display:flex; gap:1rem; }

.swipe__dot{
  width:1.75rem; height:2px;
  background:rgba(36,28,20,.20);
  border:0; padding:0;
  cursor:pointer;
  transition:background .3s ease;
  /* Die sichtbare Linie ist dünn, die Trefferfläche darf es nicht sein:
     unsichtbares Polster bringt sie auf die geforderten 44 px — in beide
     Richtungen. Seitlich fehlten vorher 16 px (nur 28 px breit); der
     Abstand der Punkte ist deshalb auf 1rem erhöht, damit sich die
     Trefferzonen zweier Nachbarn nicht überlappen. */
  position:relative;
}
.swipe__dot::before{
  content:''; position:absolute;
  left:-8px; right:-8px;
  top:-21px; bottom:-21px;
}
.swipe__dot:hover{ background:rgba(36,28,20,.42); }
.swipe__dot[aria-current="true"]{ background:var(--brass); }
.swipe__dot:focus-visible{ outline:2px solid var(--brass); outline-offset:6px; }

.swipe__arrows{ display:flex; gap:.5rem; }

.swipe__arrow{
  width:48px; height:48px;              /* Mindestgröße für Finger */
  display:grid; place-items:center;
  border:1px solid rgba(36,28,20,.22);
  border-radius:50%;
  background:transparent;
  color:var(--cream);
  cursor:pointer;
  transition:border-color .3s ease, background .3s ease, opacity .3s ease;
}
.swipe__arrow svg{ width:18px; height:18px; fill:none;
  stroke:currentColor; stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round; }
.swipe__arrow:hover:not(:disabled){
  border-color:var(--brass); background:rgba(127,92,34,.10);
}
.swipe__arrow:focus-visible{ outline:2px solid var(--brass); outline-offset:3px; }
.swipe__arrow:disabled{ opacity:.25; cursor:default; }

@media (prefers-reduced-motion:reduce){
  .swipe__track{ scroll-behavior:auto; }
}

/* ── Brautstrauß ─────────────────────────────────────────────────────────
   Ein Foto neben dem Text. Rahmen und Zuschnitt folgen bewusst der Galerie
   (4:5, --radius-lg, cover) — dasselbe Bildformat wie überall sonst, damit
   der Abschnitt nicht als Fremdkörper zwischen den Kacheln steht. */
.bouquet__wrap{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(2rem,6vw,5rem);
  align-items:center;
}
@media (max-width:820px){
  .bouquet__wrap{ grid-template-columns:1fr; }
  .bouquet__copy{ order:-1; }          /* Text zuerst, Foto darunter */
}

.bouquet__figure{
  margin:0; padding:0;
  aspect-ratio:4/5;
  overflow:hidden;
  border-radius:var(--radius-lg);
  background:var(--ink-card);
  border:1px solid var(--line);
  /* Platz ist über aspect-ratio reserviert — kein Springen beim Nachladen */
}

.bouquet__img{
  width:100%; height:100%;
  object-fit:cover;
  /* Dieselbe leichte Zurücknahme wie bei den Galeriekacheln: auf Beige
     wirken volle Sättigungen sonst hart. */
  filter:saturate(.92);
}

/* ── Zeilen-Reveal ───────────────────────────────────────────────────────
   Überschriften werden per JS in Zeilen zerlegt. Jede Zeile bekommt eine
   Maske, hinter der sie hervorschiebt — leicht versetzt nacheinander.

   Das padding/margin-Paar ist nicht kosmetisch: ohne den Puffer schneidet
   overflow:hidden die Unterlängen von g, p und y ab und kappt den weichen
   Schatten hinter der Schrift mit einer sichtbaren Kante. */
.ln{
  display:block; overflow:hidden;
  padding-block:.16em; margin-block:-.16em;
}
.ln__i{ display:block; will-change:transform,opacity; }

/* Fließtext und Button steigen nach den Zeilen nach, ohne Maske */
.rise{ will-change:transform,opacity; }

/* Nur zwei Elementgruppen bewegen sich pro Karte — Überschrift und
   Nachzügler. Mehr wäre Unruhe statt Wirkung. */
@media (prefers-reduced-motion:reduce){
  .ln{ overflow:visible; padding-block:0; margin-block:0; }
  .ln__i,.rise{
    transform:none !important; opacity:1 !important; will-change:auto;
  }
}

/* .wordmark ist jetzt nur noch die Klammer um Name + Aussage (beides in der
   H1). Die Optik haengt an den beiden Spans darunter — dadurch bleibt das
   Bild exakt wie vorher. */
.wordmark{ display:block; }
.wordmark__name{
  display:block;
  font-size:clamp(2.6rem,9vw,6rem);
  font-weight:300;
  line-height:.95;
  letter-spacing:.16em;
  text-transform:uppercase;
  text-indent:.16em;                    /* gleicht das Tracking rechts aus */
  text-shadow:0 2px 40px rgba(0,0,0,.65);
}
.wordmark__sub{
  display:block;
  margin-top:1.5rem;
  font-size:clamp(.64rem,1.6vw,.8rem);
  letter-spacing:.42em; text-transform:uppercase;
  text-indent:.42em;
  /* Auf schmalen Geraeten bricht die Zeile um. balance verteilt die Woerter
     gleichmaessig auf beide Zeilen, statt ein einzelnes Wort haengen zu
     lassen. Aeltere Browser ignorieren die Angabe und brechen wie bisher. */
  text-wrap:balance;
  color:rgba(244,237,227,.86);
  text-shadow:0 1px 18px rgba(0,0,0,.9);
}
/* Das weite Tracking ist der Hauptgrund, warum die Zeile auf kleinen Geraeten
   umbricht — es macht rund 44 % der Zeilenbreite aus. Etwas enger passt
   "Dekoration · Floristik · Nahetal" ab 360 px in eine Zeile; der Unterschied
   ist bei dieser Schriftgroesse kaum zu sehen, ein Umbruch dagegen schon.
   Darunter (<=340 px) faengt das text-wrap:balance oben den Umbruch ab. */
@media (max-width:420px){
  .wordmark__sub{ letter-spacing:.3em; text-indent:.3em; }
}
/* Bei 320 px (iPhone SE 1. Gen.) fehlten zuletzt genau 5 px. Noch eine Stufe
   enger — darunter greift weiterhin das text-wrap:balance oben. */
@media (max-width:340px){
  .wordmark__sub{ letter-spacing:.24em; text-indent:.24em; }
}

.caption__title{
  font-size:clamp(1.85rem,5vw,3.2rem);
  line-height:1.15;
  text-shadow:0 2px 40px rgba(0,0,0,.7);
  text-wrap:balance;
}
.caption__text{
  margin-top:1.35rem;
  font-size:clamp(.98rem,1.8vw,1.1rem);
  line-height:1.7;
  color:rgba(244,237,227,.8);
  text-shadow:0 1px 24px rgba(0,0,0,.75);
  text-wrap:pretty;
}
.caption__rule{
  width:2.5rem; height:1px; margin:0 auto 1.6rem;
  background:var(--brass);
}
.caption .btn{ margin-top:2.2rem; }

/* Scroll-Hinweis + Fortschritt */
/* Kennzeichnung KI-erzeugter Inhalte. Sie muss unter JEDEM Videobild lesbar
   bleiben — der Filminhalt wechselt beim Scrollen, eine rein oertliche
   Abstimmung auf einen dunklen Bildbereich haelt also nicht. Deshalb ein
   eigener dunkler Grund, wie ihn die Galerie-Bildunterschriften
   (.gallery__cap) aus demselben Grund schon tragen. Ohne ihn lag der
   Kontrast auf dem Handy bei 1.71:1 und damit weit unter AA. */
.ki-hinweis{
  position:absolute; left:clamp(1.25rem,4vw,3rem); bottom:2.2rem;
  margin:0; max-width:16rem;
  padding:.45rem .7rem;
  border-radius:var(--radius-lg);
  background:rgba(14,11,8,.62);
  -webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);
  font-size:.62rem; letter-spacing:.16em; text-transform:uppercase;
  color:rgba(244,237,227,.92);
  pointer-events:none;
}
/* Unter 700 px liegt der Scroll-Hinweis mittig unten. Die Kennzeichnung
   rueckt darueber, damit sich beide nicht ueberlappen. */
@media (max-width:700px){
  .ki-hinweis{
    left:50%; transform:translateX(-50%);
    bottom:7.75rem; max-width:none; text-align:center;
  }
}

.hint{
  position:absolute; left:50%; bottom:2.2rem;
  transform:translateX(-50%);
  display:grid; justify-items:center; gap:.85rem;
  font-size:.62rem; letter-spacing:.34em; text-transform:uppercase;
  text-indent:.34em;
  color:rgba(244,237,227,.78);
  text-shadow:0 1px 16px rgba(0,0,0,.9);
  pointer-events:none;
}
.hint__line{
  width:1px; height:2.6rem;
  background:linear-gradient(to bottom,var(--line-strong),transparent);
  position:relative; overflow:hidden;
}
.hint__line::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(to bottom,transparent,var(--brass),transparent);
  animation:drift 2.4s ease-in-out infinite;
}
@keyframes drift{
  0%{ transform:translateY(-100%); }
  60%,100%{ transform:translateY(100%); }
}

.progress{
  position:absolute; left:0; bottom:0; height:2px; width:100%;
  transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(to right,transparent,var(--brass));
  opacity:.8;
}

/* ═════════════════════════════════════════════════════════ REVEALS ══ */

.reveal{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .7s var(--ease),transform .7s var(--ease);
}
.reveal.is-in{ opacity:1; transform:none; }
/* Gestaffelt, aber gedeckelt — nichts wartet länger als 240 ms */
.reveal[data-delay="1"]{ transition-delay:80ms; }
.reveal[data-delay="2"]{ transition-delay:160ms; }
.reveal[data-delay="3"]{ transition-delay:240ms; }

/* ════════════════════════════════════════════════════════ LEISTUNGEN ══ */

.grid{ display:grid; gap:clamp(1.25rem,2.5vw,1.75rem); }
.grid--3{ grid-template-columns:repeat(auto-fit,minmax(17rem,1fr)); }
.grid--4{ grid-template-columns:repeat(auto-fit,minmax(13rem,1fr)); }
.grid--top{ margin-top:clamp(2.5rem,5vw,var(--s7)); }

.card{
  padding:clamp(1.75rem,3vw,2.25rem);
  background:var(--ink-card);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  transition:border-color .3s var(--ease),background .3s var(--ease);
}
.card:hover{ border-color:var(--line-strong); background:var(--surface-hi); }

.card__icon{
  width:2rem; height:2rem;
  color:var(--brass);
  margin-bottom:var(--s4);
  stroke:currentColor; fill:none;
  stroke-width:1.25; stroke-linecap:round; stroke-linejoin:round;
}
.card__no{
  display:block;
  font-family:var(--font-serif);
  font-size:.85rem; letter-spacing:.24em;
  color:var(--brass);
  margin-bottom:.6rem;
}
.card__title{ margin:0 0 .8rem; }
.card__text{ margin:0; color:var(--cream-mute); font-size:.98rem; }

.card__list{
  margin:var(--s4) 0 0; padding:0; list-style:none;
  display:grid; gap:.5rem;
  font-size:.9rem; color:var(--cream-faint);
}
.card__list li{ display:flex; gap:.6rem; align-items:flex-start; }
.card__list li::before{
  content:''; flex:none;
  width:5px; height:5px; margin-top:.62rem;
  border-radius:50%; background:var(--brass); opacity:.8;
}

/* ═══════════════════════════════════════════════════════════ GALERIE ══ */

.gallery{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));
  gap:clamp(.75rem,1.5vw,1rem);
  margin-top:clamp(2.5rem,5vw,var(--s7));
}
.gallery__item{
  position:relative;
  margin:0; padding:0;
  aspect-ratio:4/5;
  overflow:hidden;
  border-radius:var(--radius-lg);
  background:var(--ink-card);
  border:1px solid var(--line);
  cursor:pointer;
  /* Platz ist über aspect-ratio reserviert — kein Springen beim Nachladen */
}

.gallery__btn{
  position:absolute; inset:0;
  width:100%; height:100%; padding:0;
  border:0; background:none; cursor:pointer;
  color:inherit; text-align:left;
}
/* Auf dem dunklen Grund waren die Kacheln im Ruhezustand abgedunkelt. Auf
   Beige liest sich das als „ausgeblichen“ — die Zurückhaltung läuft hier
   deshalb über die Sättigung, nicht über die Deckkraft. */
.gallery__img{
  width:100%; height:100%;
  object-fit:cover;
  transition:opacity .5s var(--ease),filter .5s var(--ease);
  filter:saturate(.92);
}
.gallery__item:hover .gallery__img,
.gallery__btn:focus-visible .gallery__img{ filter:saturate(1.04) brightness(1.02); }

.gallery__cap{
  position:absolute; inset:auto 0 0 0;
  padding:2.5rem 1.1rem .95rem;
  /* Liegt auf dem Foto, nicht auf der Seite — hier bleibt es dunkel mit
     heller Schrift, sonst trägt die Bildunterschrift über hellen Motiven
     nicht. */
  background:linear-gradient(to top,rgba(14,11,8,.92),rgba(14,11,8,0));
  font-size:.72rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--d-cream);
  pointer-events:none;
}

/* Fällt ein Bild aus (oder liegt noch keins im Ordner), zeigt die Kachel
   eine ruhige Platzhalterfläche statt eines kaputten Bildsymbols. */
.gallery__item.is-empty .gallery__img{ display:none; }
.gallery__item.is-empty{ cursor:default; }
.gallery__item.is-empty .gallery__btn{ cursor:default; }
.gallery__item.is-empty::after{
  content:attr(data-empty);
  position:absolute; inset:0;
  display:grid; place-items:center;
  padding:1.5rem; text-align:center;
  background:
    radial-gradient(120% 90% at 50% 0%,rgba(127,92,34,.10),transparent 70%),
    var(--ink-card);
  font-size:.7rem; letter-spacing:.24em; text-transform:uppercase;
  color:var(--cream-faint);
}

/* Lightbox */
.lightbox{
  width:min(94vw,72rem);
  max-width:none;
  max-height:92vh;
  padding:0; border:0;
  background:transparent;
  overflow:visible;
}
.lightbox::backdrop{ background:color-mix(in srgb, var(--ink) 96%, transparent); backdrop-filter:blur(6px); }
.lightbox__img{
  width:100%; max-height:82vh;
  object-fit:contain;
  border-radius:var(--radius-lg);
  /* Auf dem hellen Grund verlieren Fotos mit hellem Rand sonst ihre Kante */
  border:1px solid var(--line);
}
.lightbox__bar{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
  margin-top:var(--s3);
  font-size:.75rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--cream-faint);
}
.lightbox__nav{ display:flex; gap:.5rem; }
.icon-btn{
  width:48px; height:48px;
  display:grid; place-items:center;
  border:1px solid var(--line-strong); border-radius:var(--pill);
  background:rgba(36,28,20,.04); color:var(--cream);
  cursor:pointer;
  transition:background .25s var(--ease),color .25s var(--ease);
}
.icon-btn:hover{ background:var(--cream); color:var(--ink); }
.icon-btn svg{ width:18px; height:18px; stroke:currentColor; fill:none; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; }

/* Ladeanzeige. Das Raster zeigt kleine Dateien, die Lightbox holt die große
   Fassung erst beim Öffnen nach — ohne Anzeige stünde dort kurz nichts.
   Die Bühne begrenzt die Anzeige aufs Bild; über dem ganzen Dialog läge
   der Kreisel sonst auch über der Bedienzeile. */
.lightbox__buehne{ position:relative; display:grid; }
.lightbox__lade{
  position:absolute; inset:0;
  display:grid; place-items:center;
  pointer-events:none;
}
.lightbox__lade::after{
  content:'';
  width:34px; height:34px;
  border:2px solid rgba(244,237,227,.28);
  border-top-color:rgba(244,237,227,.9);
  border-radius:50%;
  animation:spin .8s linear infinite;
}
.lightbox__lade[hidden]{ display:none; }

/* ══════════════════════════════════════════════════════ SEITENKOPF ══ */

/* Seiten ohne Hero-Video brauchen einen eigenen Auftakt. Die Kopfzeile ist
   fixiert und liegt über dem Inhalt — ohne diesen Abstand stünde die
   Überschrift darunter. */
.page-head{
  padding-block:calc(var(--hdr-h) + clamp(3rem,7vw,5rem)) clamp(2rem,4vw,3rem);
}
.page-head .h1{
  font-family:var(--font-serif);
  font-weight:300;
  font-size:clamp(2.4rem,6vw,4rem);
  line-height:1.06;
  letter-spacing:-.01em;
  margin:.6rem 0 0;
  color:var(--cream);
  text-wrap:balance;
}
.page-head .lede{ margin-top:clamp(1.1rem,2vw,1.6rem); }

/* Zurück-Link über der Album-Überschrift */
.crumb{
  display:inline-flex; align-items:center; gap:.5rem;
  font-size:.72rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--cream-faint); text-decoration:none;
  min-height:44px;
  transition:color .25s var(--ease);
}
.crumb:hover{ color:var(--brass-lift); }
.crumb svg{ width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }

/* ══════════════════════════════════════════════════════ RECHTSTEXT ══ */

/* Impressum und Datenschutz. Schmalere Spalte als der Rest der Seite:
   Fließtext über die volle Breite eines großen Bildschirms zwingt das Auge,
   beim Zeilenwechsel den Anschluss zu suchen. */
.rechtstext{ max-width:44rem; }
.rechtstext p{
  margin:0 0 1.1rem;
  color:var(--cream-mute);
  line-height:1.75;
  text-wrap:pretty;
}
.rechtstext .h3{ margin:2.2rem 0 .7rem; }
.rechtstext .h3:first-child{ margin-top:0; }
.rechtstext p.todo{
  display:block;
  padding:1rem 1.2rem;
  border:1px dashed rgba(127,92,34,.55);
  border-radius:var(--radius-lg);
  background:color-mix(in srgb, var(--brass) 8%, transparent);
}

/* ═════════════════════════════════════════════════════════ ALBEN ══ */

/* Übersicht: ein Coverbild je Anlass. Bei vielen Fotos ist das der einzige
   Aufbau, der noch überschaubar bleibt — ein einziges Raster mit
   dreihundert Bildern liest niemand zu Ende. */
.albums{
  display:grid;
  /* Genau zwei Spalten ab Tablet — bei vier Alben ergibt das ein volles 2x2
     statt einer Zeile mit 3 und einer einsamen Karte daneben; die Cover werden
     dabei doppelt so gross, was der Fotografie zusteht.
     Bewusst KEIN auto-fill/minmax: damit laesst sich "genau zwei" nicht
     ausdruecken. Ein festes Minimum von 26rem haette am Handy (416 px > 375 px)
     die Seite seitlich scrollen lassen und auf dem Tablet nur EINE 691-px-Karte
     ergeben. Die eine Spalte darunter kommt ohne Mindestbreite aus. */
  grid-template-columns:1fr;
  gap:clamp(1rem,2.2vw,1.6rem);
  margin-top:clamp(2.5rem,5vw,var(--s7));
  list-style:none; padding:0;
}
@media (min-width:700px){
  .albums{ grid-template-columns:repeat(2,1fr); }
}
.album-card{ margin:0; }
.album-card__link{
  display:block;
  text-decoration:none; color:inherit;
  border-radius:var(--radius-lg);
}
/* display:block ist hier nicht kosmetisch: die Kachel steckt in einem <a>,
   ihre Bestandteile sind deshalb <span> — und auf einem inline-Element
   greifen weder aspect-ratio noch overflow. Ohne das fällt der Bildrahmen
   auf wenige Pixel Höhe zusammen. */
.album-card__frame{
  display:block;
  position:relative;
  aspect-ratio:4/3;
  overflow:hidden;
  border-radius:var(--radius-lg);
  background:var(--ink-card);
  border:1px solid var(--line);
}
.album-card__img{
  width:100%; height:100%;
  object-fit:cover;
  filter:saturate(.92);
  transition:transform .6s var(--ease),filter .5s var(--ease);
}
.album-card__link:hover .album-card__img,
.album-card__link:focus-visible .album-card__img{
  transform:scale(1.035); filter:saturate(1.04);
}
/* Zahl der Fotos direkt auf dem Bild — sie beantwortet die erste Frage
   („lohnt sich der Klick?“), bevor jemand klickt. */
.album-card__zahl{
  position:absolute; top:.85rem; right:.85rem;
  padding:.34rem .7rem;
  border-radius:var(--pill);
  background:rgba(14,11,8,.72);
  backdrop-filter:blur(6px);
  -webkit-backdrop-filter:blur(6px);
  font-size:.66rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--d-cream);
}
.album-card__titel{
  display:block;
  font-family:var(--font-serif);
  font-size:clamp(1.25rem,2.2vw,1.5rem);
  font-weight:400; line-height:1.2;
  color:var(--cream);
  margin:.9rem 0 0;
}
.album-card__meta{
  display:block;
  margin:.35rem 0 0;
  font-size:.74rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--cream-faint);
}
.album-card__leer{
  display:grid; place-items:center;
  height:100%; padding:1.5rem; text-align:center;
  font-size:.7rem; letter-spacing:.24em; text-transform:uppercase;
  color:var(--cream-faint);
}

/* ── Album-Seite ─────────────────────────────────────────────────────── */

/* Engere Spalten als im Ausschnitt auf der Startseite: hier geht es um
   Menge, nicht um einzelne Schaustücke. grid-auto-flow:dense füllt die
   Lücken, die querformatige Bilder sonst hinterlassen. */
/* Startseiten-Ausschnitt: sechs gleich grosse Kacheln gaben jedem Bild
   dasselbe Gewicht — bei einem Betrieb, dessen Produkt die Fotografie ist,
   verschenkt das die Wirkung. Die erste Kachel nimmt jetzt 2x2 Felder ein und
   traegt die Section; die uebrigen fuenf fuellen Spalte 3 und die untere
   Zeile. 3x3 Felder, 4 davon fuer die grosse — geht genau auf.
   Das Seitenverhaeltnis bleibt bei allen 4:5, weil die Zeilenhoehe von den
   kleinen Kacheln kommt: die grosse ist schlicht viermal so gross.
   Unter 900 px bleibt es beim gleichmaessigen Raster — dort steht ohnehin
   nur eine Kachel je Zeile, eine Hierarchie waere nicht sichtbar. */
/* Unter 900 px steht das Raster ein- bis zweispaltig. Eine doppelte Breite
   gibt es dort nicht, also bekommt das Querformat eine eigene Zeile ueber die
   volle Breite und sein eigenes Seitenverhaeltnis. Weil es allein in der Zeile
   steht, gibt es keinen hoeheren Nachbarn, an den es sich strecken muesste —
   sonst waere es ueber align-self:stretch doch wieder auf 4:5 gezogen worden
   und der Anschnitt laege weiter bei 47 %. */
.gallery--teaser > .gallery__item--quer{
  grid-column:1 / -1;
  aspect-ratio:3/2;
}

@media (min-width:900px){
  .gallery--teaser{
    grid-template-columns:repeat(3,1fr);
    /* dense: das doppelt breite Querformat passt nur dort, wo zwei Spalten
       nebeneinander frei sind (untere Zeile). Ohne dense bliebe davor ein
       Loch stehen, das kein spaeteres Bild mehr auffuellen darf. */
    grid-auto-flow:dense;
  }
  .gallery--teaser > .gallery__item:first-child{
    grid-column:span 2;
    grid-row:span 2;
  }
  /* Querformate ueber zwei Spalten. Die Hoehe kommt aus der Zeile (also von
     den hochformatigen Nachbarn) — daraus ergibt sich rund 1.6:1 statt der
     4:5 des Rasters, was einem 3:2-Foto deutlich naeher kommt: der Anschnitt
     faellt von rund 46 % auf unter 10 %. Ein eigenes aspect-ratio wuerde die
     Zeile stattdessen ausfransen lassen. */
  .gallery--teaser > .gallery__item--quer{
    grid-column:span 2;
    aspect-ratio:auto;
  }
}

.gallery--album{
  grid-template-columns:repeat(auto-fill,minmax(min(14rem,100%),1fr));
  grid-auto-flow:dense;
}
@media (min-width:600px){
  .gallery--album .gallery__item--quer{
    grid-column:span 2;
    /* Bewusst KEIN eigenes Seitenverhältnis: die Kachel soll die Höhe ihrer
       Zeile annehmen. Mit aspect-ratio:3/2 stünde sie rund 30 px tiefer als
       ihre Nachbarn und die Zeile liefe unten ausgefranst aus. */
    aspect-ratio:auto;
    /* Notnagel: besteht eine Zeile ausschließlich aus Querformaten, gibt es
       nichts, woraus eine Zeilenhöhe entstehen könnte — ohne diesen Wert
       fällt sie auf zwei Pixel zusammen. Im Normalfall greift er nie, dort
       ist die Zeile durch die hochformatigen Kacheln immer höher. */
    min-height:17rem;
  }
}

.album-fuss{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--s3);
  margin-top:clamp(2.5rem,5vw,var(--s7));
  padding-top:var(--s5);
  border-top:1px solid var(--line);
}
.album-fuss__text{ margin:0; color:var(--cream-mute); flex:1 1 18rem; }

/* ═══════════════════════════════════════════════════════════ ABLAUF ══ */

.steps{
  list-style:none; margin:clamp(2.5rem,5vw,var(--s7)) 0 0; padding:0;
  display:grid; gap:var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));
  counter-reset:step;
}
.step{ position:relative; padding-top:var(--s4); }
.step::before{
  content:''; position:absolute; inset:0 0 auto 0; height:1px;
  background:var(--line);
}
.step::after{
  content:''; position:absolute; top:0; left:0; width:2.5rem; height:1px;
  background:var(--brass);
}
.step__no{
  display:block;
  font-family:var(--font-serif); font-size:.85rem; letter-spacing:.24em;
  color:var(--brass); margin-bottom:.5rem;
}
.step__title{ font-size:1.2rem; margin:0 0 .5rem; }
.step__text{ margin:0; font-size:.94rem; color:var(--cream-mute); }

/* ══════════════════════════════════════════════════════════ ÜBER UNS ══ */

.about{
  display:grid; gap:clamp(2.5rem,5vw,4rem);
  grid-template-columns:minmax(0,1fr);
  align-items:center;
}
@media (min-width:900px){
  .about{ grid-template-columns:1.1fr .9fr; }
}
.about__media{
  border-radius:var(--radius-lg);
  overflow:hidden;
  border:1px solid var(--line);
  aspect-ratio:4/5;
  background:var(--ink-card);
}
.about__media img{ width:100%; height:100%; object-fit:cover; }

/* Abschluss-Knopf einer Section. Ersetzt zwei <div class="wrap"
   style="margin-top:-2rem"> direkt hinter </section>: die standen ausserhalb
   ihrer Section, mussten den Section-Abstand per Negativ-Margin zurueckziehen
   und liessen den Knopf in der Ueber-uns-Spalte rund 200 px unter dem Absatz
   schweben. Jetzt gehoert er zum Inhalt und haelt einen normalen Abstand. */
.section__cta{ margin-top:clamp(2rem,4vw,3rem); }
.about .section__cta{ margin-top:clamp(1.5rem,3vw,2.25rem); }

.stats{
  list-style:none; margin:var(--s6) 0 0; padding:0;
  display:grid; gap:var(--s4);
  grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));
}
.stat{ border-left:1px solid var(--line); padding-left:var(--s3); }
.stat__no{
  display:block;
  font-family:var(--font-serif);
  font-size:clamp(1.9rem,4vw,2.5rem); line-height:1;
  color:var(--cream);
}
.stat__label{
  display:block; margin-top:.5rem;
  font-size:.7rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--cream-faint);
}

/* ═════════════════════════════════════════════════════════ STIMMEN ══ */

.quotes{
  display:grid; gap:clamp(1.25rem,2.5vw,1.75rem);
  grid-template-columns:repeat(auto-fit,minmax(18rem,1fr));
  margin-top:clamp(2.5rem,5vw,var(--s7));
}
.quote{
  margin:0;
  padding:clamp(1.75rem,3vw,2.25rem);
  background:var(--ink-card);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  display:flex; flex-direction:column; gap:var(--s4);
}
.quote__stars{ display:flex; gap:.25rem; color:var(--brass); }
.quote__stars svg{ width:14px; height:14px; fill:currentColor; }
.quote__text{
  margin:0;
  font-family:var(--font-serif);
  font-size:clamp(1.15rem,2vw,1.35rem);
  line-height:1.45;
  color:var(--cream);
  text-wrap:pretty;
}
.quote__by{
  margin-top:auto;
  font-size:.78rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--cream-faint);
  font-style:normal;
}

/* ═════════════════════════════════════════════════════════════ FAQ ══ */

.faq{ margin-top:clamp(2.5rem,5vw,var(--s7)); max-width:48rem; }
.faq__item{ border-bottom:1px solid var(--line); }
.faq__q{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
  padding:1.35rem 0;
  min-height:56px;
  cursor:pointer;
  list-style:none;
  font-family:var(--font-serif);
  font-size:clamp(1.08rem,2vw,1.25rem);
  line-height:1.3;
  color:var(--cream);
  transition:color .25s var(--ease);
}
.faq__q::-webkit-details-marker{ display:none; }
.faq__q:hover{ color:var(--brass-lift); }
.faq__sign{
  flex:none; width:16px; height:16px; position:relative;
  color:var(--brass);
}
.faq__sign::before,.faq__sign::after{
  content:''; position:absolute; inset:50% 0 auto 0;
  height:1.5px; background:currentColor; border-radius:2px;
  transition:transform .3s var(--ease);
}
.faq__sign::after{ transform:rotate(90deg); }
.faq__item[open] .faq__sign::after{ transform:rotate(0); }
.faq__a{
  margin:0; padding:0 0 1.5rem;
  max-width:40rem;
  color:var(--cream-mute); font-size:.98rem;
  text-wrap:pretty;
}

/* ═════════════════════════════════════════════════════════ KONTAKT ══ */

.contact{
  display:grid; gap:clamp(2.5rem,5vw,4rem);
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:900px){
  .contact{ grid-template-columns:.85fr 1.15fr; align-items:start; }
}

.contact__aside{ display:grid; gap:var(--s5); align-content:start; }
.contact__list{ list-style:none; margin:0; padding:0; display:grid; gap:var(--s4); }
.contact__row{ display:flex; gap:var(--s3); align-items:flex-start; }
.contact__ico{
  width:20px; height:20px; flex:none; margin-top:.28rem;
  color:var(--brass);
  stroke:currentColor; fill:none; stroke-width:1.4; stroke-linecap:round; stroke-linejoin:round;
}
.contact__label{
  display:block;
  font-size:.66rem; letter-spacing:.24em; text-transform:uppercase;
  color:var(--cream-faint); margin-bottom:.2rem;
}
.contact__val{ color:var(--cream); font-size:1rem; }
.contact__val a{ min-height:auto; }

/* Formular */
.form{ display:grid; gap:var(--s4); }
.form__row{
  display:grid; gap:var(--s4);
  grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));
}
.field{ display:grid; gap:.45rem; }
.field__label{
  font-size:.7rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--cream-faint);
}
.field__req{ color:var(--brass); }

.field input,.field select,.field textarea{
  width:100%;
  min-height:48px;
  padding:.85rem 1rem;
  background:var(--ink-card);
  border:1px solid var(--line-strong);
  border-radius:var(--radius);
  color:var(--cream);
  font-family:var(--font-sans);
  font-size:1rem;                 /* 16px — verhindert iOS-Zoom beim Fokus */
  line-height:1.5;
  transition:border-color .25s var(--ease),background .25s var(--ease);
  -webkit-appearance:none; appearance:none;
}
.field textarea{ min-height:8.5rem; resize:vertical; }
.field input::placeholder,.field textarea::placeholder{ color:color-mix(in srgb, var(--cream) 56%, transparent); }
.field input:hover,.field select:hover,.field textarea:hover{ border-color:color-mix(in srgb, var(--cream) 40%, transparent); }
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--brass); background:var(--surface-hi);
}

.field select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237F5C22' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 1rem center;
  background-size:18px;
  padding-right:2.75rem;
  cursor:pointer;
}
:root[data-theme="dark"] .field select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C8A464' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.field select option{ background:var(--ink-card); color:var(--cream); }

/* Fehler stehen direkt am Feld, nicht gesammelt am Formularende, und sind
   nicht nur über Farbe erkennbar — es gibt Symbol und Text dazu. */
.field.has-error input,.field.has-error select,.field.has-error textarea{
  border-color:var(--danger);
}
.field__err{
  display:none;
  margin:0;
  align-items:center; gap:.4rem;
  font-size:.82rem; color:var(--danger);
}
.field.has-error .field__err,
.consent-block.has-error .field__err{ display:flex; }
.field__err svg{ width:14px; height:14px; flex:none; stroke:currentColor; fill:none; stroke-width:1.6; }

/* Einwilligung */
.consent{
  display:flex; gap:.85rem; align-items:flex-start;
  font-size:.88rem; color:var(--cream-mute);
  cursor:pointer;
}
.consent input{
  flex:none;
  width:22px; height:22px; margin:.18rem 0 0;
  min-height:0;
  accent-color:var(--brass);
  cursor:pointer;
}
.consent-block{ display:grid; gap:.4rem; }
.consent-block.has-error .consent{ color:var(--danger); }
.consent__aside{ margin:0; padding-left:2.85rem; font-size:.82rem; color:var(--cream-faint); }

.form__note{
  margin:0;
  font-size:.82rem; color:var(--cream-faint);
}

.form__status{
  display:none;
  margin:0;
  padding:1rem 1.15rem;
  border:1px solid var(--brass);
  border-radius:var(--radius);
  background:rgba(127,92,34,.10);
  color:var(--cream);
  font-size:.95rem;
}
.form__status.is-on{ display:block; }

/* ══════════════════════════════════════════════════════════ FOOTER ══ */

.footer{
  border-top:1px solid var(--line);
  padding-block:var(--s6) var(--s5);
}
.footer__grid{
  display:grid; gap:var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));
  margin-bottom:var(--s6);
}
.footer__mark{
  font-family:var(--font-serif);
  font-size:1rem; letter-spacing:.3em; text-transform:uppercase;
  color:var(--cream); margin:0 0 .75rem;
}
.footer__text{ margin:0; font-size:.9rem; color:var(--cream-mute); max-width:22rem; }
.footer__head{
  margin:0 0 var(--s3);
  font-size:.66rem; letter-spacing:.24em; text-transform:uppercase;
  color:var(--brass);
}
.footer__list{ list-style:none; margin:0; padding:0; display:grid; gap:.6rem; }
.footer__list a{
  color:var(--cream-mute); text-decoration:none; font-size:.9rem;
  transition:color .25s var(--ease);
}
.footer__list a:hover{ color:var(--cream); }

.footer__bar{
  display:flex; flex-wrap:wrap; gap:var(--s3) var(--s5);
  justify-content:space-between; align-items:center;
  padding-top:var(--s4);
  border-top:1px solid var(--line);
  font-size:.75rem; letter-spacing:.1em;
  /* Alt: rgba(...,.35) → 2.7:1 und damit unter AA. Jetzt 5.1:1. */
  color:var(--cream-faint);
}

/* ═══════════════════════════════════════════════════ MOBILE CTA-LEISTE ══ */

/* Auf dem Telefon ist der Anfrage-Button sonst 6 Bildschirme entfernt. */
.cta-bar{
  position:fixed; inset:auto 0 0 0; z-index:var(--z-sticky);
  display:none;
  padding:.75rem clamp(1rem,4vw,1.5rem) calc(.75rem + env(safe-area-inset-bottom));
  background:color-mix(in srgb, var(--ink) 94%, transparent);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border-top:1px solid var(--line);
  transform:translateY(110%);
  transition:transform .35s var(--ease);
}
.cta-bar.is-on{ transform:none; }
.cta-bar .btn{ width:100%; }

@media (max-width:860px){
  .cta-bar{ display:block; }
  /* Platz, damit die Leiste nichts am Seitenende verdeckt */
  .footer{ padding-bottom:6rem; }
}

/* ═══════════════════════════════════════════════ REDUZIERTE BEWEGUNG ══ */

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .reveal{ opacity:1; transform:none; }
  .stage__video{ transform:none; }
  .hint__line::after{ animation:none; opacity:.5; }
}

/* ═════════════════════════════════════════════════════════ PRINT ══ */

@media print{
  .hdr,.drawer,.cta-bar,.scrolly,.hint,.progress,.skip{ display:none !important; }
  body{ background:#fff; color:#000; }
  .card,.quote{ border-color:#ccc; }
}
