/* ==========================================================================
   Portraits-Kehl — „Lichtsatz" (Neuaufbau 25.08.2026)
   Editorial × Licht/Fokus: weißer Grund, Plus Jakarta Sans × Fraunces
   (Schriftwechsel 27.08.2026, vorher Bodoni Moda × Instrument Sans),
   Sucher-Signatur am rechten Rand, Schärfe-Reveals, EXIF-Unterschriften.

   Regeln:
   - Der fertige Zustand ist der Standard. Alles Bewegte hängt an html.js
     und wird bei prefers-reduced-motion abgeschaltet.
   - Kein Inline-Style, keine Fremdschriften. Kontraste gemessen:
     #C8371F auf Weiß 5,22:1 · #5F5B55 auf Weiß 6,74:1 (auf --papier-warm
     6,19:1; vorher #6E6A64 mit 5,37:1 — zu schwach für 11–14-px-Zeilen) ·
     #E9E4DC auf #141412 14,6:1 (siehe memory/messwerte.md).
   ========================================================================== */

/* ---- Schriften (selbst gehostet, feste Schnitte) ------------------------
   Getauscht am 27.08.2026: Plus Jakarta Sans traegt Text UND Ueberschrift,
   Fraunces kursiv ist nur noch der Akzent in Ueberschriften. Quelle beider
   Familien: _schriften/ im Ordner-Wurzelverzeichnis (SIL OFL 1.1,
   Lizenztexte liegen dort).

   BEWUSST feste Schnitte statt der variablen Fassungen: Fraunces traegt
   wie Bodoni Moda eine opsz-Achse, und die duennt bei grossen Graden von
   selbst aus (der Fall vom 26.08.2026, memory/fallen_gestaltung.md). Ein
   fester Schnitt kann das nicht. Preis dafuer: Gewichte gibt es nur in
   Hunderterschritten — die frueheren Zwischenwerte (640, 660, 680) sind
   deshalb auf 500/600/700/800 abgebildet.

   Plus Jakarta Sans liegt NUR aufrecht vor. Jedes <em> haengt darum an
   Fraunces (Regel „kursiver Akzent" weiter unten); ohne sie wuerde der
   Browser eine schraeg gestellte Fassung erfinden.
   ------------------------------------------------------------------------ */

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-latin-600-normal.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-latin-800-normal.woff2") format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("../fonts/fraunces-latin-500-italic.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}

/* Playfair Display traegt seit dem 29.08.2026 die Titel der Paketkarten
   (Frederiks Wahl nach der beigeandwhite-Vorlage). Wie immer FESTE
   Schnitte, keine variable Fassung — Playfair Display traegt zwar keine
   opsz-Achse, aber die Regel bleibt: was der Browser nicht rechnen darf,
   kann er nicht faelschen (memory: lesbarkeit_portraits, 26./27.08.2026). */
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-latin-600-normal.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ---- Grundwerte --------------------------------------------------------- */

:root {
  --papier: #ffffff;
  --papier-warm: #f7f5f1;
  --tinte: #141412;
  --tinte-weich: #3a3833;
  --grau: #5f5b55;
  --linie: #e6e1d9;
  --akzent: #c8371f;
  /* Der Akzent eine Stufe tiefer — Hover-Ton der Signal-Knoepfe
     (29.08.2026). Als Variable, damit die drei Fundstellen (Kopf-CTA,
     Kopf-CTA mobil, .knopf--signal) nicht auseinanderlaufen. */
  --akzent-tief: color-mix(in srgb, var(--akzent) 78%, var(--tinte));
  --dunkel: #0f0e0d;
  --dunkel-text: #e9e4dc;
  --dunkel-grau: #c9c4bc;

  /* --display und --text zeigen seit dem 27.08.2026 auf DIESELBE Familie —
     so macht es die Vorlage. Beide Namen bleiben stehen, damit die 31
     Fundstellen im Stylesheet weiter sagen, welche ROLLE sie meinen; wer
     spaeter wieder zwei Familien will, tauscht eine Zeile statt 31. */
  --display: "Plus Jakarta Sans", -apple-system, "Segoe UI", sans-serif;
  --text: "Plus Jakarta Sans", -apple-system, "Segoe UI", sans-serif;
  /* Der kursive Akzent, und NUR er. Nie im Fliesstext. */
  --zier: "Fraunces", Georgia, "Times New Roman", serif;
  /* Serifentitel der Paketkarten (29.08.2026, beigeandwhite-Vorlage). */
  --serif: "Playfair Display", Georgia, "Times New Roman", serif;

  --breite: 76rem;
  --rand: clamp(1.1rem, 4vw, 3rem);
  --sucher-platz: clamp(0rem, 6vw, 5.5rem);

  /* Rundungs-Skala (28.08.2026, Auftrag Frederik): alle UI-Kaesten tragen
     die Rundung der Angebote-Klappe — 1,1 rem fuer grosse Karten, 0,7 rem
     fuer Knoepfe und Eintraege, 0,55 rem fuer kleine Kacheln und Chips.
     Fotos und reservierte Bildplaetze bleiben bewusst KANTIG (Frederiks
     Wahl 28.08.2026) — der harte Bildrahmen gehoert zur Fotografie. */
  --rund-gross: 1.1rem;
  --rund: 0.7rem;
  --rund-klein: 0.55rem;

  --lauf: 0; /* Seiten-Scrollfortschritt 0–1, gesetzt von seite.js */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

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

body {
  font-family: var(--text);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--tinte);
  background: var(--papier);
  text-rendering: optimizeLegibility;
  /* Bleibt stehen, obwohl seit dem 27.08.2026 keine Schrift dieser Seite
     mehr eine opsz-Achse traegt: Fraunces HAT eine, wir laden nur einen
     festen Schnitt daraus. Wer die variable Fassung einbaut, bekaeme ohne
     diese Zeile denselben Fehler wie am 26.08.2026 mit Bodoni Moda — der
     Browser stellt opsz automatisch auf die Schriftgroesse, und die
     Haarstriche verschwinden. Kein Fehler, keine Meldung, nur unlesbar
     (memory/fallen_gestaltung.md, 26.08.2026). Eine Zeile Vorsorge. */
  font-optical-sizing: none;
  /* Bewusst KEIN -webkit-font-smoothing: antialiased. Es duennt auf dem Mac
     jeden Strich aus. Bei Plus Jakarta Sans ist das weniger dramatisch als
     bei einer Didone, aber es bleibt eine Gewichtsreduktion, die niemand
     bestellt hat. */
}

::selection { background: var(--akzent); color: #fff; }

/* Lange deutsche Wörter („Datenschutzerklärung") laufen sonst über den
   Rand, ohne dass ein Element zu breit ist — der Überlauf steckt im Text,
   nicht in seiner Box, und ist nur an document.scrollWidth zu sehen
   (memory/fallen.md, WordPress-Theme 04.08.2026). */
h1, h2, h3, p, li, summary, dt, dd, figcaption, label, legend, .paket__name, .paket__preis {
  overflow-wrap: break-word;
  hyphens: auto;
}
/* Adressen und Links haben keine Trennstellen. `break-word` allein
   verkleinert die min-content-Breite NICHT — ein Rasterfeld bleibt dann so
   breit wie das längste Wort und schiebt die Seite über den Rand.
   Gemessen bei 320 px: die E-Mail-Adresse zog kontakt.html auf 331 px. */
a[href^="mailto:"], .fuss__orte, code, .exif {
  overflow-wrap: anywhere;
}
/* Rasterfelder dürfen schrumpfen — ohne `min-width: 0` gilt `auto`, und
   damit wird kein Feld kleiner als sein längster Inhalt. */
.zweispalt > *, .region > *, .block__kopf > *, .fragen-lage > *,
.formular__gitter > *, .fuss__spalten > *, .ueber > * { min-width: 0; }
h1, h2, h3 { font-family: var(--display); font-weight: 700; line-height: 1.06; }

/* ---- Der kursive Akzent -------------------------------------------------
   Fraunces 500 kursiv, und nur hier. Zwei Gruende, warum die Regel so weit
   greift (blankes `em`) statt nur an den bekannten Stellen zu haengen:
   Plus Jakarta Sans liegt NUR aufrecht vor — ein <em> ohne eigene Familie
   bekaeme eine vom Browser schraeg gestellte Fassung, und die sieht nach
   Darstellungsfehler aus; und jedes kuenftige <em> ist damit von selbst
   richtig, statt beim naechsten Mal vergessen zu werden.

   Die 1,04em sind eingemessen, nicht geschaetzt: Fraunces sitzt bei
   gleicher Punktgroesse optisch kleiner als Jakarta. `letter-spacing: 0`
   hebt das negative Tracking der Ueberschrift wieder auf — es ist fuer die
   Groteske gesetzt, die Serife braucht es nicht.

   ACHTUNG bei neuen Regeln: Wer an einer Klasse `font-weight` setzt, in
   der ein <em> steckt, schlaegt diese Regel (Klasse 0-1-0 gegen Typ
   0-0-1) — dieselbe Falle, die in diesem Ordner siebenmal steht. Dann
   gehoert `font-weight: 500` in die Ausnahme dazu.
   ------------------------------------------------------------------------ */
em {
  font-family: var(--zier);
  font-style: italic;
  font-weight: 500;
  font-size: 1.04em;
  letter-spacing: 0;
}
h1 em, h2 em, h3 em, .cta-band__zeile em { color: var(--akzent); }

/* Plus Jakarta Sans laeuft bei grossen Graden zu weit. Das negative
   Tracking waechst mit der Groesse — bei 16 px waere es zu viel. */
h1 { font-size: clamp(2.5rem, 5.6vw, 4.6rem); letter-spacing: -0.022em; text-wrap: balance; }
h2 { font-size: clamp(1.9rem, 3.6vw, 2.9rem); letter-spacing: -0.02em; text-wrap: balance; }
h3 { font-size: 1.28rem; font-weight: 700; letter-spacing: -0.015em; }

p, li { max-width: 62ch; }
a { color: inherit; text-decoration-color: var(--linie); text-underline-offset: 0.2em; }
a:hover { text-decoration-color: var(--akzent); }
img { display: block; max-width: 100%; height: auto; }

.unsichtbar {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.sprung {
  position: absolute; left: -200vw; top: 0; z-index: 60;
  background: var(--tinte); color: #fff; padding: 0.6rem 1rem;
}
.sprung:focus-visible { left: 0; }

:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---- Knöpfe ------------------------------------------------------------- */

.knopf {
  display: inline-block;
  font-family: var(--text);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--papier);
  background: var(--tinte);
  border: 1.5px solid var(--tinte);
  padding: 0.85rem 1.7rem;
  border-radius: var(--rund);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease,
              border-color 0.25s ease, transform 0.25s ease;
}
.knopf:hover { background: var(--akzent); border-color: var(--akzent); transform: translateY(-2px); }
.knopf--gross { padding: 1rem 2.2rem; font-size: 1rem; }
.knopf--linie { background: transparent; color: var(--tinte); }
.knopf--linie:hover { background: var(--tinte); color: var(--papier); }

/* ---- Signal-Knopf: „Verfuegbarkeit pruefen" -----------------------------
   Frederiks Ansage 29.08.2026: der Haupt-CTA traegt das „Kamera-Orange"
   der Startseite — also `--akzent`, dieselbe Farbe wie das kursive Wort
   „Kamera" in der H1. Er steht an DREI Stellen (Kopf jeder Seite, Hero
   und CTA-Band der Startseite) und ueberall gleich; die „Termin
   anfragen"-Baender der Unterseiten bleiben schwarz, sonst waere die
   Signalfarbe keine.
   Der Hover muss hier etwas ANDERES tun als sonst: `.knopf:hover` faerbt
   normalerweise NACH --akzent — auf einem bereits orangen Knopf waere das
   wirkungslos. Deshalb der tiefere Ton. Und er muss die allgemeine Regel
   wirklich schlagen: `.knopf.knopf--signal:hover` ist 0-3-0 gegen
   `.knopf:hover` 0-2-0 — die Ausnahme ist damit spezifischer als die
   Regel, die sie aufhebt, und ueberlebt auch ein spaeteres Umsortieren
   der Datei (dieselbe Falle steht achtmal in memory/fallen_gestaltung.md). */
.knopf--signal { background: var(--akzent); border-color: var(--akzent); }
.knopf.knopf--signal:hover {
  background: var(--akzent-tief); border-color: var(--akzent-tief);
}

.block--dunkel .knopf--linie { color: var(--dunkel-text); border-color: var(--dunkel-grau); }
.block--dunkel .knopf--linie:hover { background: var(--dunkel-text); color: var(--dunkel); }

/* ---- Kopf --------------------------------------------------------------- */

.kopf {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.9rem var(--rand);
  background: color-mix(in srgb, var(--papier) 86%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--linie);
}

.kopf__marke {
  font-family: var(--display);
  font-size: 1.45rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
}
.kopf__strich { color: var(--akzent); }

.kopf__nav ul { list-style: none; display: flex; align-items: center; gap: 1.6rem; }
.kopf__nav a {
  font-size: 0.95rem; font-weight: 500; text-decoration: none;
  /* mindestens 24 px hoch (WCAG 2.2 „Target Size"), gemessen mit
     build/abnahme.py — vorher 20 px */
  padding: 0.42rem 0;
  border-bottom: 2px solid transparent;
}
.kopf__nav a:hover { border-bottom-color: var(--akzent); }
.kopf__nav a[aria-current="page"] { border-bottom-color: var(--tinte); }

/* Die Hover-Fläche reicht bis an das Klappmenü heran. Vorher lag
   zwischen Menüpunkt und Klappe eine 0,55-rem-Lücke: Wer die Maus nach
   unten bewegte, verlor den Hover, und das Menü schloss sich, bevor ein
   Punkt anklickbar war (Frederik, 25.08.2026). */
.kopf__klapp {
  position: relative;
  padding-bottom: 0.9rem;
  margin-bottom: -0.9rem;
}
/* `ul.kopf__unter`, nicht nur `.kopf__unter`: die Sammelregel
   `.kopf__nav ul` ist Klasse PLUS Typ und damit spezifischer als eine
   Klasse allein. Sie setzte hier `align-items: center` und `gap: 1.6rem`
   durch — die Einträge standen zentriert und weit auseinander, obwohl
   unten `stretch` und `0` steht. Vierter Fall dieses Musters im Ordner
   (memory/fallen.md, 04.08. / 19.08.2026). */
/* Umbau 27.08.2026 (Frederik): Nummern 01–05 raus — sie erklärten nichts.
   Stattdessen je Bereich eine kleine Federzeichnung (.np, gezeichnet, nie
   Schriftzeichen — die Subsets haben keine Symbole) auf Haarlinien-Kachel,
   darunter ein Untersatz. Aufklappen 220 ms (Korridor 100–500 ms). */
.kopf__klapp > a::after {
  content: ""; display: inline-block;
  width: 0.34em; height: 0.34em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  margin-left: 0.5rem;
  transform: translateY(-0.18em) rotate(45deg);
  transition: transform 0.25s ease;
}
.kopf__klapp:hover > a::after,
.kopf__klapp:focus-within > a::after {
  transform: translateY(0.02em) rotate(-135deg);
}
/* Umbau 28.08.2026 (Frederik, nach Screenshot-Vorlage): abgerundete
   Karte, Hover als runde Pille — Muster der Vorlage, Farben vom Haus
   (papier-warm statt Mint), der rote Faden bleibt. Das Innenpolster
   ringsum schmälert den Textraum; min-width von 21,5 auf 22,5 rem
   nachgeführt (21,5 war an der Untersatz-Zeile „Portrait" eingemessen —
   nach der Änderung im Browser nachgemessen, nicht nur gerechnet).
   left = Kartenpolster 0,6 + Eintragspolster 0,85 rem, damit die
   Piktogramm-Kachel unter dem Wort „Angebote" fluchtet (gemessen:
   Kachelkante 779 px = Triggertext 778 px bei 1440 px Fenster). */
ul.kopf__unter {
  position: absolute; top: 100%; left: -1.45rem;
  min-width: 22.5rem;
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  box-shadow: 0 24px 50px rgba(20, 20, 18, 0.12);
  padding: 0.6rem 0.6rem 0.55rem;
  display: none !important;
  flex-direction: column; gap: 0;
  /* Ohne das erbt die Klappe das `align-items: center` der Menüleiste,
     und die Einträge stehen unterschiedlich weit eingerückt (im echten
     Chrome gesehen). `stretch` macht sie linksbündig und die Hover-Fläche
     so breit wie die Klappe. */
  align-items: stretch;
  animation: kopf-klappe 0.22s ease both;
}
/* Roter Faden auf der Oberkante — dieselbe Geste wie die Blendenmarke
   im Sucher: ein kurzes Akzentstück, kein Vollbalken. */
ul.kopf__unter::before {
  content: ""; position: absolute; top: -1px; left: 1.45rem;
  width: 2.4rem; height: 2px; background: var(--akzent);
}
@keyframes kopf-klappe {
  from { opacity: 0; transform: translateY(0.5rem); }
}
.kopf__klapp:hover .kopf__unter,
.kopf__klapp:focus-within .kopf__unter { display: flex !important; }
.kopf__unter li a {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.58rem 0.85rem;
  border-radius: var(--rund);
  border-bottom: none;
  transition: background-color 0.2s ease;
}
.kopf__unter li a:hover { background: var(--papier-warm); }
/* Muss `.kopf__nav a[aria-current="page"]` (0-2-1) schlagen, sonst kommt
   deren border-bottom durch — siebter Fall des Spezifitätsmusters. */
.kopf__unter li a[aria-current="page"] {
  border-bottom: none;
  box-shadow: inset 2px 0 0 var(--akzent);
}

.kopf__pikto {
  flex: none; display: grid; place-items: center;
  width: 2.35rem; height: 2.35rem;
  border: 1px solid var(--linie);
  border-radius: var(--rund-klein);
  background: var(--papier-warm);
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.kopf__unter li a:hover .kopf__pikto {
  background: var(--papier);
  border-color: color-mix(in srgb, var(--tinte) 26%, var(--linie));
}
.np { display: block; width: 1.45rem; height: 1.45rem; }
.np--klein { width: 0.95rem; height: 0.95rem; }
.np__z { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.np__z--fein { stroke-width: 1.1; opacity: 0.55; }
.np__z--rot { stroke: var(--akzent); }
.np__punkt { fill: var(--akzent); stroke: none; }

.kopf__wort { display: block; line-height: 1.25; }
.kopf__satz {
  display: block; font-size: 0.76rem; font-weight: 400;
  color: var(--tinte-weich); letter-spacing: 0.01em;
}

.kopf__mehr { margin-top: 0.55rem; padding-top: 0.3rem; border-top: 1px solid var(--linie); }
.kopf__mehr a {
  justify-content: space-between;
  padding: 0.62rem 0.85rem;
  border-radius: var(--rund);
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--tinte-weich);
}
.kopf__mehr a:hover { color: var(--tinte); background: var(--papier-warm); }
.kopf__mehr .np--klein { transition: transform 0.2s ease; }
.kopf__mehr a:hover .np--klein { transform: translateX(3px); }

/* Vollton statt Umriss seit dem 29.08.2026 (Frederiks Ansage): der
   Kopf-CTA traegt dasselbe Kamera-Orange wie die beiden grossen Knoepfe
   der Startseite. `border-bottom` der Nachbarpunkte wird hier
   ueberschrieben — sonst zoege der Hover eine zweite Linie unter den
   gefuellten Knopf. */
.kopf__cta a {
  background: var(--akzent);
  color: #fff;
  border: 1.5px solid var(--akzent);
  border-radius: var(--rund);
  padding: 0.55rem 1.1rem !important;
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.kopf__cta a:hover, .kopf__cta a:focus-visible {
  background: var(--akzent-tief); border-color: var(--akzent-tief); color: #fff;
  border-bottom-color: var(--akzent-tief);
}

.kopf__schalter { position: absolute; opacity: 0; pointer-events: none; }
.kopf__menueknopf {
  display: none;
  font-size: 0.9rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1.5px solid var(--tinte);
  border-radius: var(--rund);
  padding: 0.45rem 0.95rem; cursor: pointer;
}

@media (max-width: 920px) {
  /* backdrop-filter macht den Header zum Containing Block für fixe
     Nachfahren — das Menü-Overlay wäre nur headerhoch (gemessen).
     Auf Mobil deshalb Vollton statt Glas. */
  .kopf {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--papier);
  }
  .kopf__menueknopf { display: inline-block; }
  .kopf__nav {
    position: fixed; inset: 0; top: 3.6rem;
    background: var(--papier);
    padding: 2rem var(--rand);
    display: none;
    overflow: auto;
  }
  .kopf__schalter:checked ~ .kopf__nav { display: block; }
  .kopf__schalter:focus-visible ~ .kopf__menueknopf {
    outline: 2px solid var(--akzent); outline-offset: 3px;
  }
  .kopf__nav ul { flex-direction: column; align-items: flex-start; gap: 0.4rem; }
  .kopf__nav > ul > li > a { font-family: var(--display); font-size: 1.7rem; font-weight: 700; }
  ul.kopf__unter {
    position: static; display: flex !important; border: none; box-shadow: none;
    padding: 0.2rem 0 0.6rem 0.2rem;
    animation: none;
  }
  ul.kopf__unter::before { content: none; }
  .kopf__klapp > a::after { display: none; }
  .kopf__unter li a { font-family: var(--text); font-size: 1.05rem; padding: 0.4rem 0; gap: 0.75rem; }
  .kopf__unter li a:hover { background: transparent; }
  .kopf__unter li a:hover .kopf__pikto { background: var(--papier-warm); border-color: var(--linie); }
  .kopf__pikto { width: 2rem; height: 2rem; }
  .kopf__satz { display: none; }
  .kopf__mehr { display: none; }
  .kopf__cta { margin-top: 1rem; }
  .kopf__cta a { display: inline-block; background: var(--akzent); color: #fff; }
}

/* ---- Sucher-Signatur (rechter Rand) ------------------------------------- */

.sucher {
  position: fixed; top: 0; right: clamp(0.6rem, 2vw, 1.6rem);
  height: 100vh; width: 3.4rem;
  z-index: 30;
  pointer-events: none;
  display: flex; flex-direction: column; align-items: center;
}
.sucher__bahn {
  position: absolute; top: 6rem; bottom: 6rem; width: 1px;
  background: var(--linie);
}
.sucher__rahmen {
  position: absolute;
  top: calc(6rem + (100vh - 12rem - 3.2rem) * var(--lauf));
  width: 2.6rem; height: 3.2rem;
}
.sucher__ecke {
  position: absolute; width: 0.62rem; height: 0.62rem;
  border: 0 solid var(--akzent);
}
.sucher__ecke--lo { top: 0; left: 0; border-top-width: 2px; border-left-width: 2px; }
.sucher__ecke--ro { top: 0; right: 0; border-top-width: 2px; border-right-width: 2px; }
.sucher__ecke--lu { bottom: 0; left: 0; border-bottom-width: 2px; border-left-width: 2px; }
.sucher__ecke--ru { bottom: 0; right: 0; border-bottom-width: 2px; border-right-width: 2px; }
.sucher__punkt {
  position: absolute; top: 50%; left: 50%;
  width: 4px; height: 4px; margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: var(--akzent);
}
.sucher__stand {
  position: absolute; bottom: 2.6rem;
  writing-mode: vertical-rl;
  font-size: 0.68rem; letter-spacing: 0.14em;
  color: var(--grau);
  display: flex; gap: 0.6rem; align-items: center;
}
.sucher__blende { color: var(--akzent); font-weight: 600; font-variant-numeric: tabular-nums; }
.sucher__nr { font-variant-numeric: tabular-nums; }
.sucher__nr i { font-style: normal; color: var(--linie); }

/* Einrasten: kurzer AF-Puls beim Abschnittswechsel (Klasse aus seite.js) */
html.js .sucher--rast .sucher__rahmen { animation: af-rast 0.45s ease; }
html.js .sucher--rast .sucher__punkt { animation: af-punkt 0.45s ease; }
@keyframes af-rast {
  0% { transform: scale(1.35); }
  60% { transform: scale(0.94); }
  100% { transform: scale(1); }
}
@keyframes af-punkt {
  0%, 55% { background: var(--tinte); }
  100% { background: var(--akzent); }
}

@media (max-width: 1180px) { .sucher { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .sucher__rahmen { top: 6rem; }
  html.js .sucher--rast .sucher__rahmen,
  html.js .sucher--rast .sucher__punkt { animation: none; }
}

/* ---- Blendenskala (Trennstreifen) --------------------------------------- */

.skala {
  position: relative;
  display: flex; justify-content: space-between; align-items: center;
  max-width: min(var(--breite), calc(100% - 2 * var(--rand)));
  margin: 0 auto;
  padding: 0.55rem 0;
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
  font-size: 0.68rem; letter-spacing: 0.12em;
  color: var(--grau);
  font-variant-numeric: tabular-nums;
}
.skala span::before { content: "\2022"; color: var(--linie); margin-right: 1.2rem; }
.skala span:first-of-type::before { content: ""; margin: 0; }
.skala__index {
  position: absolute; left: 50%; top: -0.35rem; bottom: -0.35rem;
  width: 2px; background: var(--akzent);
}
/* Unter 460 px passen acht Blendenwerte nicht mehr nebeneinander — der
   letzte schob die Seite über den Rand (gemessen bei 320 px: 327 px).
   Jeder zweite Wert entfällt, die Reihe endet weiter bei 1.4. */
@media (max-width: 460px) {
  .skala span:nth-child(even) { display: none; }
  .skala { font-size: 0.64rem; }
}

/* ---- Blöcke ------------------------------------------------------------- */

/* Blockpolster = der Abstand ZWISCHEN zwei Abschnitten (unten + oben) und
   der Abstand des ersten Abschnitts zur Kopfleiste.

   Am 31.08.2026 auf Frederiks Ansage gekuerzt („teilweise ziemlich viel
   Platz zwischen den Abschnitten"), 7rem -> 4.5rem, seine Wahl aus drei
   vorgelegten Staerken. Gemessen vorher/nachher:

     Fensterbreite   zwischen Abschnitten   zur Kopfleiste
     1440 px         224 -> 144 px          112 -> 72 px
     1000 px         170 -> 110 px           85 -> 55 px
      375 px         115 ->  83 px           58 -> 42 px

   Das ist bewusst eine GLOBALE Aenderung — anders als am 26./27.08., wo
   dieselbe Meldung fuer je EINE Seite kam und `.block--knapp` bekam. Wer
   hier dreht, dreht alle 18 Seiten: das ist hier der Auftrag, sonst nie.
   Die vw-Stufe ist von 8.5 auf 5.5 mit heruntergezogen, sonst haette die
   Kuerzung nur oberhalb von 1320 px gewirkt (dort greift erst der Deckel)
   und die mittleren Breiten waeren unveraendert geblieben. */
.block {
  padding: clamp(2.6rem, 5.5vw, 4.5rem) var(--rand);
}
.block > * , .block__kopf > * { margin-inline: auto; }
.block > *, .cta-band { max-width: var(--breite); }
.block--warm { background: var(--papier-warm); }
/* Die Galerie traegt gar kein eigenes Polster mehr — weder oben noch unten.
   Was UNTER ihr steht (Preistafel, CTA-Band), gehoert zu den Bildern
   darueber; stossen zwei volle Polster aneinander, entsteht ein Loch, das
   wie ein Fehler aussieht. Oben galt das seit dem 26.08.2026, unten seit
   dem 31.08.2026 (Frederik zum Portfolio: „Packe das ‚Gefaellt dir…' naeher
   an das letzte Bild ran"). Gemessen bei 1512 px: vom Fuss des letzten
   Bildes bis zur CTA-Zeile 167 -> 95 px; den Rest tragen die 2 rem
   Kachelabstand und das Polster des Bandes selbst.
   Merksatz: Ein Abstand gehoert dem Nachbarn — zwei Nachbarn, die ihn beide
   mitbringen, ergeben keinen Rhythmus, sondern eine Luecke. */
.block--galerie { padding-block: 0; }
.block--galerie + .block--warm { padding-top: clamp(2rem, 4vw, 3.2rem); }
.block--dunkel { background: var(--dunkel); color: var(--dunkel-text); }
.block--dunkel a { color: inherit; }

.block__kopf { max-width: var(--breite); margin-inline: auto; }
.block__kopf > * { margin-inline: 0; }
.block__kopf h1, .block__kopf h2 { max-width: 18em; }
.block__satz { color: var(--grau); font-size: 1.12rem; margin-top: 1.1rem; }
.block__satz--hell { color: var(--dunkel-grau); }
.block__weiter { margin-top: 2rem; font-weight: 600; max-width: var(--breite); }
.block__weiter a { text-decoration: none; border-bottom: 2px solid var(--akzent); padding-bottom: 0.15rem; }

.vorzeile {
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--grau);
  margin-bottom: 1.3rem;
  display: flex; align-items: center; gap: 0.7rem;
}
.vorzeile::after { content: ""; height: 1px; width: 3.4rem; background: var(--akzent); }
/* Die Hauptvorzeile der Startseite. Sie ist nicht Etikett wie die anderen,
   sondern die einzige SACHLICHE Aussage über der Falz — Beruf und Ort im
   Klartext, während die H1 darunter eine Bildzeile ist. Nielsen Norman
   verlangt genau diese Zeile („explicitly summarizes what the company
   does"); dass sie hier nicht die H1 ist, ist eine bewusste Wahl zugunsten
   der Stimme. Dann muss sie aber wenigstens zu lesen sein: eine Stufe
   größer, eine Stufe dunkler, etwas enger gesperrt. Nicht mehr — sie soll
   die Schauzeile stützen, nicht mit ihr streiten. */
.held .vorzeile--haupt {
  font-size: 0.92rem;
  letter-spacing: 0.14em;
  color: var(--tinte-weich);
  margin-bottom: 1.05rem;
}

.vorzeile__nr {
  font-family: var(--zier); font-style: italic; font-weight: 500;
  font-size: 1.05rem; letter-spacing: 0; text-transform: none;
  color: var(--akzent);
}

.notiz { font-size: 0.86rem; color: var(--grau); margin-top: 0.9rem; }
.notiz--preis { max-width: var(--breite); margin-top: 2rem; }

/* ---- EXIF-Unterschriften ------------------------------------------------ */

.exif {
  display: block;
  margin-top: 0.55rem;
  /* 0.72rem waren gemessene 11,5 px fuer einen ganzen Satz — zu klein.
     0.8rem = 12,8 px; Versalien und Sperrsatz tragen den Rest. */
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: var(--grau);
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
}
.exif b { color: var(--akzent); font-weight: 600; }
.block--dunkel .exif { color: var(--dunkel-grau); }

/* ---- Schärfe-Reveal (unscharf → scharf) --------------------------------- */
/* Latent wird NUR unter html.js und außerhalb des Sichtfensters gesetzt
   (seite.js) — ohne JavaScript steht alles fertig und scharf da. */

html.js .zeige--latent {
  /* Bewusst dezent: 14 px Unschärfe ließ Bilder beim Scrollen wie
     „noch nicht geladen" aussehen (im echten Chrome gesehen). */
  filter: blur(8px);
  opacity: 0.55;
  /* Kein scale > 1: Das vergrößerte Element ragte im Anfangszustand über
     den rechten Rand, und die Seite ließ sich seitlich schieben — sichtbar
     nur VOR dem Auslösen der Reveals (gemessen an document.scrollWidth,
     375 px → 391 px). */
  transform: translateY(12px);
}
html.js .zeige--dran {
  filter: blur(0);
  opacity: 1;
  transform: none;
  /* 0,65 s liegt ÜBER dem Bewegungskorridor von 100-500 ms — absichtlich.
     Die Recherche (7.5) lässt genau eine Ausnahme zu: die Enthüllung eines
     BILDES aus der Fläche, 500-700 ms, „weil es Bildkomposition ist, nicht
     Interface-Feedback". Das ist diese Regel. Sie ist die einzige Stelle
     der Seite über 500 ms; wer eine zweite einführt, hat keine Ausnahme
     mehr, sondern eine langsame Seite. */
  transition: filter 0.65s ease, opacity 0.55s ease, transform 0.65s ease;
}
@media (prefers-reduced-motion: reduce) {
  html.js .zeige--latent { filter: none; opacity: 1; transform: none; }
}
/* Reißleine im Stylesheet: Wenn seite.js die Startlage gesetzt hat und der
   Beobachter nie feuert (Hintergrundtab — dort laufen IntersectionObserver
   und Übergänge NICHT, memory/fallen.md 04.08.2026), deckt seite.js nach
   4 s bedingungslos auf; diese Klasse ist die Gegenprobe dazu. */
html.js .zeige--frei {
  filter: none !important;
  opacity: 1 !important;
  transform: none !important;
}
/* Gedruckt wird der fertige Zustand — sonst kommen unscharfe, halb
   durchsichtige Bilder aus dem Drucker (dieselbe Fundstelle). */
@media print {
  html.js .zeige--latent { filter: none; opacity: 1; transform: none; }
  .kopf, .sucher, .cta-band__knoepfe { display: none; }
}

/* ---- Held (Startseite) -------------------------------------------------- */

.held {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  max-width: var(--breite);
  margin-inline: auto;
  padding-right: var(--sucher-platz);
  min-height: min(84vh, 52rem);
}
/* Eigenes, flacheres Polster als die übrigen Blöcke: mit deren 7 rem
   oben und unten rutschten die Knöpfe bei einem flachen Fenster
   (1300 × 719 px) unter die Falz (Frederik, 25.08.2026). */
.block.held { max-width: none; padding-block: clamp(1.2rem, 3.5vh, 3.5rem); }
.held > * { margin-inline: 0; }

.held__zeile {
  /* Auch an die FENSTERHÖHE gekoppelt: allein aus vw gerechnet wurde die
     Zeile in flachen Fenstern riesig und schob alles darunter hinaus. */
  font-size: min(clamp(2.7rem, 6.2vw, 5.4rem), 10vh);
  font-weight: 700;
  margin-top: 0.4rem;
}
.held__text { color: var(--grau); font-size: 1.15rem; margin-top: 1.4rem; }
.held__knoepfe { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.9rem; }

.held__bild {
  position: relative;
  align-self: stretch;
  display: flex; flex-direction: column; justify-content: center;
  overflow: clip; /* Garantie: nichts aus dem Kopfbereich ragt seitlich hinaus */
}
.held__bild picture { background: var(--papier-warm); }
/* Das Hochformat bestimmte die Höhe des ganzen Kopfbereichs: bei 1300 px
   Breite wurde es 735 px hoch und drückte die Knöpfe aus dem Bild.
   Jetzt begrenzt die Fensterhöhe das Bild, nicht das Bild das Fenster. */
.held__bild img {
  width: 100%;
  max-height: min(70vh, 44rem);
  object-fit: cover;
  object-position: center 28%;
}

/* Der Sucherrahmen liegt AUSSEN um das Bild — auf schmalen Schirmen ist
   dafür kein Platz, dort steht er innen. Sonst ragt er über den Rand und
   die Seite lässt sich seitlich schieben (gemessen: 375 px → 413 px). */
/* Der Sucherrahmen liegt INNEN im Bild. Außen (inset: -0.7rem) ragte er
   über den Seitenrand hinaus und machte die Seite seitlich schiebbar —
   bei 768 px um 64 px (gemessen an document.scrollWidth). */
.held__af { position: absolute; inset: 0.6rem; pointer-events: none; }
.held__af i { position: absolute; width: 1.15rem; height: 1.15rem; border: 0 solid var(--akzent); }
.held__af i:nth-child(1) { top: 0; left: 0; border-top-width: 2.5px; border-left-width: 2.5px; }
.held__af i:nth-child(2) { top: 0; right: 0; border-top-width: 2.5px; border-right-width: 2.5px; }
.held__af i:nth-child(3) { bottom: 0; left: 0; border-bottom-width: 2.5px; border-left-width: 2.5px; }
.held__af i:nth-child(4) { bottom: 0; right: 0; border-bottom-width: 2.5px; border-right-width: 2.5px; }

/* Eintritt: Zeile zieht scharf, Bild rastet ein — nur mit JS, einmalig.
   ---------------------------------------------------------------------
   Gekürzt am 26.08.2026. Vorher lief der Kopfbereich 0,8-1,1 s mit einer
   Staffelung von 0,15-0,5 s. Der Bewegungskorridor der Recherche (7.5,
   NN/G) ist 100-500 ms — „über 500 ms wird Animation lästig" —, und eine
   Staffelung über etwa 60 ms je Element steht dort unter „billig". Die
   EINE zugestandene Ausnahme über 500 ms ist die Enthüllung eines BILDES
   (clip-path/Unschärfe, 500-700 ms); die trägt hier der Schärfe-Reveal
   mit 0,65 s weiter unten. Text und Knöpfe sind Interface, kein Bild.
   Ease-out für Eintritte, nie linear. */
html.js .held__zeile { animation: fokus-zug 0.45s cubic-bezier(0.2, 0.6, 0.2, 1) both; }
html.js .held__text { animation: sanft-auf 0.35s ease-out 0.06s both; }
html.js .held__knoepfe { animation: sanft-auf 0.35s ease-out 0.12s both; }
html.js .held .notiz { animation: sanft-auf 0.35s ease-out 0.18s both; }
html.js .held__af { animation: af-fassen 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) 0.05s both; }
@keyframes fokus-zug {
  from { filter: blur(16px); opacity: 0.2; letter-spacing: 0.02em; }
  to { filter: blur(0); opacity: 1; letter-spacing: -0.015em; }
}
@keyframes sanft-auf {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}
/* scale(1.14) machte den Rahmen während der ersten Sekunde 14 % breiter
   als das Bild — bei 900 px Fenster ragte er 50 px über den Seitenrand,
   und die Seite ließ sich in dieser Zeit seitlich schieben. Jetzt kleiner
   Ausschlag, und die Figur schneidet ab, was übersteht. */
@keyframes af-fassen {
  from { transform: scale(1.05); opacity: 0; }
  55% { opacity: 1; }
  70% { transform: scale(0.99); }
  to { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .held__zeile, html.js .held__text, html.js .held__knoepfe,
  html.js .held .notiz, html.js .held__af { animation: none; }
}

@media (max-width: 920px) {
  .held { grid-template-columns: 1fr; min-height: 0; padding-right: 0; }
  .held__bild { order: -1; }
}
/* Zwischen Tablet und schmalem Desktop stand das Hochformat als
   schmale Säule links, rechts daneben eine leere halbe Seite (im
   Browser gesehen). Dort wird es zum breiten Kopfbild. */
@media (min-width: 620px) and (max-width: 920px) {
  .held__bild img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    object-position: center 28%;
  }
}
@media (max-width: 619px) {
  .held__bild { max-width: 30rem; }
}

/* ---- Fokus-Buehne: die fuenf Angebote (Startseite, 02.09.2026) ---------
   Frederiks Wahl aus drei Vorschlaegen. Links die Angebote als Schauzeilen,
   rechts EINE Bildbuehne. Wer eine Zeile beruehrt, zieht ihr Bild scharf —
   der Fokuszug der Sucher-Signatur als Bedienidee; alle anderen Zeilen
   treten in die Unschaerfe (nur ueber die Deckkraft, nie ueber blur auf
   Text — das saehe aus wie ein Darstellungsfehler).

   Alles in CSS: `:has()` + `:hover`/`:focus-within`, kein Skript. Ohne
   Zeiger steht das ERSTE Bild — der fertige Zustand ist der Standard.
   Es gibt nur EINEN Satz Bilder: Jedes <picture> steht in seiner Zeile
   (li) und liegt ab 900 px per position:absolute in der rechten
   Rasterspalte; darunter bleibt es in der Zeile, die dann eine Bildkarte
   ist. Die zweite Rasterspalte ist deshalb LEER — sie reserviert nur den
   Platz, auf den die Bilder gelegt werden. */

.buehne {
  --buehne-b: clamp(19rem, 36vw, 29rem);
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--buehne-b);
  column-gap: clamp(2rem, 5vw, 5.5rem);
  margin-top: 2.4rem;
  max-width: var(--breite); margin-inline: auto;
}
.buehne__liste { list-style: none; }
/* `p, li { max-width: 62ch }` gilt global — hier sind die li Zeilen eines
   Rasters, keine Fliesstextabsaetze (die Falle vom 26./27.08.2026). */
.buehne__liste li { max-width: none; }
.buehne__zeile { border-top: 1px solid var(--linie); }
.buehne__zeile:last-child { border-bottom: 1px solid var(--linie); }

.wahlzeile {
  position: relative;
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr) auto 1.4rem;
  align-items: center; column-gap: 1.2rem;
  padding: 1.2rem 0.5rem 1.2rem 0.2rem;
  text-decoration: none; color: inherit;
  transition: opacity 0.3s ease, padding-left 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Der rote Zug an der Unterkante: waechst von links, wie der Akzentzug
   der Zeitleiste — dieselbe Geste, hier als Hover. */
.wahlzeile::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--akzent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.wahlzeile__nr {
  font-family: var(--zier); font-style: italic; font-weight: 500;
  font-size: 1.15rem; color: var(--grau);
  transition: color 0.3s ease;
}
.wahlzeile__name {
  display: block;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.55rem, 2.5vw, 2.25rem);
  line-height: 1.1; letter-spacing: -0.02em;
}
.wahlzeile__unter { display: block; color: var(--grau); font-size: 0.92rem; margin-top: 0.3rem; }
.wahlzeile__ab { font-size: 0.92rem; color: var(--grau); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Gezeichneter Winkel statt Pfeil-Glyph — die Subsets tragen Sonderzeichen
   nicht zwingend (Regel vom Haken der Preistafel). */
.wahlzeile__pfeil {
  width: 0.7rem; height: 0.7rem;
  border-top: 2px solid var(--akzent); border-right: 2px solid var(--akzent);
  transform: rotate(45deg);
  transition: transform 0.3s ease;
}

@media (hover: hover) {
  .buehne__zeile:hover .wahlzeile { padding-left: 0.9rem; }
  .buehne__zeile:hover .wahlzeile__pfeil { transform: translateX(6px) rotate(45deg); }
}
.buehne__zeile:hover .wahlzeile::after,
.buehne__zeile:focus-within .wahlzeile::after { transform: scaleX(1); }
.buehne__zeile:hover .wahlzeile__nr,
.buehne__zeile:focus-within .wahlzeile__nr { color: var(--akzent); }
/* Schaerfentiefe: Sobald eine Zeile im Fokus ist, treten die anderen
   zurueck. 0,6 ist die Grenze: Die Namen (Tinte, ueber 24 px) bleiben
   damit ueber 4,5:1, die kleinen Grauzeilen fallen auf rund 3,6:1 —
   nur waehrend eine ANDERE Zeile beruehrt wird, also ein fluechtiger
   Zustand. Tiefer (0,45) las sich das Kleingedruckte nicht mehr. */
.buehne:has(.buehne__zeile:hover, .buehne__zeile:focus-within)
  .buehne__zeile:not(:hover, :focus-within) .wahlzeile { opacity: 0.6; }

/* Die Bilder: gestapelt in der rechten Spalte, ueber die ganze Hoehe der
   Liste. Standard: unscharf und unsichtbar; das erste Bild ist scharf,
   solange keine Zeile beruehrt wird. Die beruehrte Zeile hebt ihr Bild
   nach vorn (z-index 1) und zieht es scharf — blur 6 px, nicht mehr: bei
   14 px sah ein Bild beim Uebergang aus wie nicht geladen (25.08.2026). */
.buehne__bild {
  display: flex; flex-direction: column;
  opacity: 0; filter: blur(6px); transform: scale(1.03);
  transition: opacity 0.45s ease, filter 0.5s ease, transform 0.5s ease;
  pointer-events: none;
}
.buehne__bild picture { display: block; flex: 1; min-height: 0; background: var(--papier-warm); }
.buehne__bild img { display: block; width: 100%; height: 100%; object-fit: cover; }
.buehne__bild .exif { flex: none; }
.buehne__bild--zeichnung { color: var(--grau); }
.buehne__bild--zeichnung svg {
  flex: 1; min-height: 0; width: 100%;
  background: var(--papier-warm); padding: 14%;
}
.buehne__zeile:first-child .buehne__bild { opacity: 1; filter: none; transform: none; }
.buehne:has(.buehne__zeile:hover, .buehne__zeile:focus-within)
  .buehne__zeile:first-child:not(:hover, :focus-within) .buehne__bild {
  opacity: 0; filter: blur(6px); transform: scale(1.03);
}
.buehne__zeile:hover .buehne__bild,
.buehne__zeile:focus-within .buehne__bild { opacity: 1; filter: none; transform: none; z-index: 1; }

/* Der AF-Rahmen rastet auf dem Bild ein, wenn seine Zeile beruehrt wird —
   dieselben Ecken und dieselbe Bewegung wie am Kopfbild (af-fassen). Der
   Rahmen liegt INNEN im Bild und laesst die EXIF-Zeile frei. */
.buehne__af { position: absolute; left: 0.75rem; right: 0.75rem; top: 0.75rem; bottom: 2.75rem; pointer-events: none; }
.buehne__af i { position: absolute; width: 1.1rem; height: 1.1rem; border: 0 solid var(--akzent); }
.buehne__af i:nth-child(1) { top: 0; left: 0; border-top-width: 2.5px; border-left-width: 2.5px; }
.buehne__af i:nth-child(2) { top: 0; right: 0; border-top-width: 2.5px; border-right-width: 2.5px; }
.buehne__af i:nth-child(3) { bottom: 0; left: 0; border-bottom-width: 2.5px; border-left-width: 2.5px; }
.buehne__af i:nth-child(4) { bottom: 0; right: 0; border-bottom-width: 2.5px; border-right-width: 2.5px; }
.buehne__zeile:hover .buehne__af,
.buehne__zeile:focus-within .buehne__af { animation: af-fassen 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both; }

/* Der leise Hinweis unter der Buehne — nur, wo es einen Zeiger gibt. */
.buehne__hinweis {
  grid-column: 2; align-self: end;
  font-size: 0.74rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--grau); text-align: right;
  margin-top: 0.9rem; max-width: none; display: none;
}
@media (hover: hover) {
  .buehne__hinweis { display: block; transition: opacity 0.3s ease; }
  /* Sobald jemand es tut, braucht es den Hinweis nicht mehr. */
  .buehne:has(.buehne__zeile:hover, .buehne__zeile:focus-within) .buehne__hinweis { opacity: 0; }
}

@media (min-width: 900px) {
  .buehne__bild {
    position: absolute; top: 0; right: 0;
    width: var(--buehne-b); bottom: 2.4rem;
  }
  .buehne__bild--zeichnung { position: absolute; }
}

/* Unter 900 px: eine Bildkarte je Angebot — das Bild bleibt in seiner
   Zeile, ueber dem Namen; Fokuszug und Rahmen entfallen (kein Zeiger). */
@media (max-width: 899.98px) {
  .buehne { display: block; }
  .buehne__zeile { display: grid; border-top: none; border-bottom: 1px solid var(--linie); padding-bottom: 0.4rem; margin-bottom: 1.6rem; }
  .buehne__zeile:last-child { margin-bottom: 0; }
  .buehne__bild {
    order: -1; position: relative;
    opacity: 1; filter: none; transform: none; transition: none;
  }
  .buehne__bild picture { aspect-ratio: 3 / 2; flex: none; }
  .buehne__bild--zeichnung svg { aspect-ratio: 3 / 2; flex: none; height: auto; }
  .buehne__af { animation: none !important; }
  .buehne:has(.buehne__zeile:hover, .buehne__zeile:focus-within)
    .buehne__zeile:first-child:not(:hover, :focus-within) .buehne__bild { opacity: 1; filter: none; transform: none; }
  .buehne:has(.buehne__zeile:hover, .buehne__zeile:focus-within)
    .buehne__zeile:not(:hover, :focus-within) .wahlzeile { opacity: 1; }
  .wahlzeile { grid-template-columns: 2rem minmax(0, 1fr) auto 1.2rem; column-gap: 0.8rem; padding: 0.9rem 0.3rem 0.9rem 0; }
  .buehne__hinweis { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .buehne__bild, .wahlzeile, .wahlzeile::after, .wahlzeile__pfeil, .wahlzeile__nr { transition: none; }
  .buehne__bild, .buehne:has(.buehne__zeile:hover, .buehne__zeile:focus-within)
    .buehne__zeile:first-child:not(:hover, :focus-within) .buehne__bild { filter: none; transform: none; }
  .buehne__af { animation: none !important; }
}

/* ---- Ablauf-Takt (Startseite, 02.09.2026) ---------------------------------
   „Drei Zusagen" (04) und „Ablauf" (05) sind ein Abschnitt geworden: eine
   schmale Zusagen-Leiste, darunter drei Schritte mit den Piktogramm-Muenzen
   von ablauf.html auf einer waagerechten Bahn. Keine Karten — die
   Startseite kuendigt an, ablauf.html erzaehlt. */

.zusagen-leiste {
  list-style: none; display: flex; flex-wrap: wrap;
  gap: 0.6rem 2.4rem; margin-top: 1.5rem;
  max-width: var(--breite); margin-inline: auto;
  font-weight: 600; font-size: 0.95rem;
}
.zusagen-leiste li { max-width: none; display: flex; align-items: center; gap: 0.6rem; }
/* Der Haken ist aus zwei Kanten gezeichnet — kein U+2713 (Subset-Regel). */
.zusagen-leiste__haken {
  width: 0.62rem; height: 0.36rem; margin-top: -0.2rem;
  border-left: 2px solid var(--akzent); border-bottom: 2px solid var(--akzent);
  transform: rotate(-45deg);
}

.takt { position: relative; margin-top: 2.6rem; max-width: var(--breite); margin-inline: auto; }
.takt__bahn {
  position: absolute; left: 1.7rem; right: 0; top: calc(1.7rem - 1px);
  height: 2px; background: var(--linie); border-radius: 2px;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 9rem), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 9rem), transparent);
}
.takt__schritte {
  list-style: none;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.4rem, 3vw, 2.8rem);
}
.takt__schritte li { max-width: none; }
.taktschritt__muenze {
  width: 3.4rem; height: 3.4rem; border-radius: 50%;
  background: var(--papier); border: 1px solid var(--linie);
  display: grid; place-items: center;
  position: relative; z-index: 1;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.taktschritt__nr {
  font-family: var(--zier); font-style: italic; font-weight: 500;
  font-size: 1.05rem; color: var(--akzent);
  margin-top: 1.1rem;
}
.taktschritt__titel { font-size: 1.25rem; margin-top: 0.15rem; }
.taktschritt__satz { color: var(--grau); font-size: 0.98rem; margin-top: 0.5rem; text-wrap: pretty; }
.taktschritt__meta {
  margin-top: 0.75rem; padding-left: 1.15rem; position: relative;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tinte-weich); hyphens: manual;
}
.taktschritt__meta::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 0.7rem; height: 2px; background: var(--akzent);
}
@media (hover: hover) {
  .taktschritt:hover .taktschritt__muenze {
    border-color: var(--akzent); transform: scale(1.06);
    box-shadow: 0 8px 20px rgba(20, 20, 18, 0.08);
  }
}
@media (max-width: 760px) {
  .takt__bahn {
    left: calc(1.7rem - 1px); right: auto; top: 1.7rem; bottom: 1.5rem;
    width: 2px; height: auto;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 4rem), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 4rem), transparent);
  }
  .takt__schritte { grid-template-columns: 1fr; gap: 1.8rem; }
  .taktschritt { display: grid; grid-template-columns: 3.4rem minmax(0, 1fr); column-gap: 1rem; align-items: start; }
  .taktschritt__muenze { grid-row: span 4; }
  .taktschritt__nr { margin-top: 0.15rem; }
}
@media (prefers-reduced-motion: reduce) {
  .taktschritt__muenze { transition: none; }
  .taktschritt:hover .taktschritt__muenze { transform: none; }
}

/* ---- Region / Karte ----------------------------------------------------- */

.region {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem); align-items: center;
  max-width: var(--breite); margin-inline: auto;
}
.region > * { margin-inline: 0; }
@media (max-width: 860px) { .region { grid-template-columns: 1fr; } }

.karte { width: 100%; max-width: 34rem; justify-self: center; font-family: var(--text); }
.karte text { font-size: 10.5px; fill: var(--tinte-weich); letter-spacing: 0.03em; }
.karte .karte__hauptname { font-weight: 700; font-size: 12.5px; fill: var(--tinte); }
.karte__ort { fill: var(--tinte-weich); }
.karte__af path { fill: none; stroke: var(--akzent); stroke-width: 2.4; }
.karte__af circle { fill: var(--akzent); }
.karte__ring {
  fill: none; stroke: var(--grau); stroke-width: 1;
  stroke-dasharray: 5 7; opacity: 0.75;
}
.karte__marke { stroke: var(--grau); stroke-width: 1; opacity: 0.55; }
.karte__rhein { fill: none; stroke: var(--linie); stroke-width: 2.2; }
.karte__notiz { font-size: 9.5px; fill: var(--grau); letter-spacing: 0.08em; text-transform: uppercase; }

/* ---- CTA-Band ----------------------------------------------------------- */

.cta-band {
  max-width: var(--breite); margin-inline: auto;
  text-align: center;
  padding: 1rem 0;
}
.cta-band__zeile {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.9rem, 4.4vw, 3.2rem);
  letter-spacing: -0.02em; line-height: 1.1;
  max-width: 18em; margin-inline: auto;
  text-wrap: balance;
}
.cta-band__knoepfe {
  display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: center;
  margin-top: 1.8rem;
}
/* Zentriert heisst: die BOX in die Mitte, nicht nur der Text darin.
   `.notiz` ist ein <p> und erbt damit die globale Breitengrenze
   `p, li { max-width: 62ch }` (gemessen 558 px). Ohne `margin-inline: auto`
   klebt dieser gekappte Kasten am linken Rand des 1216 px breiten Bandes,
   waehrend sein Text mittig darin steht — der Satz stand dadurch sichtbar
   links neben der Mitte, auf ZEHN Seiten (Frederik, 27.08.2026).
   Es ist dieselbe Ursache wie beim Absendeknopf (26.08.) und beim
   Preistext (27.08.) — darum steht die Regel jetzt am Container und gilt
   fuer JEDES Blockkind, nicht nur fuer die eine Stelle, und
   `abnahme.py` (Messung 9) faengt den naechsten Fall von selbst. */
.cta-band > p, .cta-band > ul, .cta-band > ol, .cta-band > dl {
  margin-inline: auto;
}
.cta-band .notiz { text-align: center; }

/* ---- Angebote (Übersichtsseite) ----------------------------------------- */

/* Fünf Angebote plus eine Rückfrage-Kachel = sechs Zellen: das Raster
   geht bei drei UND bei zwei Spalten glatt auf (vorher blieb unten
   rechts ein Loch — im Browser gesehen, 25.08.2026). */
.angebote {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2.4rem 2rem; margin-top: 2.8rem;
  max-width: var(--breite); margin-inline: auto;
}
.angebot { text-decoration: none; display: block; }
.karte-bild { display: block; overflow: hidden; background: var(--papier-warm); aspect-ratio: 3 / 2; }
.karte-bild img {
  width: 100%; height: 100%; object-fit: cover;
  /* 0,6 s war Zustandswechsel-Tempo für eine Hover-Rückmeldung; die
     Recherche setzt dafür 200-300 ms an (26.08.2026). */
  transition: transform 0.4s ease-out;
}
.angebot:hover .karte-bild img { transform: scale(1.03); }
.karte-bild--zeichnung {
  display: grid; place-items: center; color: var(--grau);
  border: 1px solid var(--linie);
  background:
    repeating-linear-gradient(-45deg, transparent 0 14px,
      rgba(20, 20, 18, 0.022) 14px 15px),
    var(--papier-warm);
}
.karte-bild--zeichnung svg { width: 42%; height: auto; }
.angebot__satz { display: block; padding: 0.9rem 0.2rem 0; border-top: 2px solid var(--tinte); margin-top: 0.9rem; }
.angebot__nr { font-family: var(--zier); font-style: italic; font-weight: 500; color: var(--akzent); margin-right: 0.5rem; }
/* War <strong>; ist seit 26.08.2026 ein <h2> — die Seite hatte sonst eine
   H1 und keine einzige weitere Überschrift. Die Ziffer sitzt IM h2, damit
   sie wie vorher in derselben Zeile steht (h2 ist ein Block). */
.angebot__name { font-family: var(--display); font-size: 1.55rem; font-weight: 700;
  line-height: 1.15; letter-spacing: 0; }
.angebot__was { display: block; color: var(--grau); font-size: 0.88rem; margin-top: 0.35rem; }
.angebot__ab { display: block; font-weight: 600; font-size: 0.95rem; margin-top: 0.5rem; font-variant-numeric: tabular-nums; }

.angebot--frage {
  display: flex; flex-direction: column; justify-content: center;
  gap: 0.9rem;
  background: var(--papier-warm);
  border-top: 2px solid var(--akzent);
  padding: clamp(1.4rem, 3vw, 2rem);
}
.angebot__frage {
  font-family: var(--display); font-size: 1.55rem; font-weight: 700;
  line-height: 1.15;
}
.angebot__frage em { font-style: italic; color: var(--akzent); }
.angebot--frage p { color: var(--tinte-weich); font-size: 0.95rem; }
.angebot--frage .knopf { margin-top: 0.2rem; }

@media (max-width: 1000px) { .angebote { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .angebote { grid-template-columns: 1fr; } }

/* ---- Genre-Kopf --------------------------------------------------------- */

.genrekopf__ab { margin-top: 1.4rem; font-size: 1.02rem; }
.genrekopf__ab strong { font-family: var(--display); font-size: 1.5rem; font-weight: 700; }

/* Handlungszeile im Seitenkopf (30.08.2026): nur die Hochzeitsseite traegt
   sie — der Bewerbungsknopf soll ueber der Falz stehen, nicht erst im Band
   ganz unten. EIGENE Klasse statt `.cta-band__knoepfe`: jene zentriert und
   verschwindet im Druck. Kein <p>, damit die globale Grenze
   `p, li { max-width: 62ch }` den Knopf nicht abschneidet (die Falle vom
   26.08.2026: der Absendeknopf endete 25,6 px vor der Kante). */
.genrekopf__tat {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem;
  margin-top: 1.5rem;
}
.genrekopf__tat + .notiz { margin-top: 0.8rem; }

/* ---- Galerie ------------------------------------------------------------ */

/* Masonry über CSS-Spalten: gemischte Hoch- und Querformate laufen
   lückenlos, ohne dass ein Bild beschnitten wird. Ein festes Raster
   riss hier sichtbare Löcher (im Browser gesehen, 25.08.2026). */
.galerie {
  columns: 2;
  column-gap: 1.6rem;
  max-width: var(--breite); margin-inline: auto;
}
.galerie__feld {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  margin-bottom: 2rem;
}
.galerie--plaetze {
  columns: auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.6rem;
}
.galerie--plaetze .galerie__feld { margin-bottom: 0; }
.galerie__knopf {
  display: block; width: 100%;
  border: none; background: var(--papier-warm);
  padding: 0; cursor: zoom-in;
}
/* 0,55 s war Zustandswechsel-Tempo für eine reine Hover-Rückmeldung —
   die Recherche setzt dafür 200-300 ms an. Gefunden von der geschärften
   Bewegungsprüfung am 26.08.2026, nicht von Auge. */
.galerie__knopf img { width: 100%; transition: transform 0.35s ease-out; }
.galerie__knopf:hover img { transform: scale(1.015); }
@media (max-width: 760px) {
  .galerie { columns: 1; }
  .galerie__feld { margin-bottom: 1.8rem; }
}

/* Zeichnung: reservierter Bildplatz als Federzeichnung */
.galerie__zeichnung {
  border: 1px solid var(--linie);
  background:
    repeating-linear-gradient(-45deg, transparent 0 14px,
      rgba(20, 20, 18, 0.022) 14px 15px),
    var(--papier-warm);
  color: var(--tinte-weich);
  /* Kompakter als ein echtes Foto: ein reservierter Platz soll die
     Galerie nicht dominieren (im Browser abgewogen, 25.08.2026). */
  aspect-ratio: 1 / 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 0.4rem; padding: 1.4rem;
}
.galerie__zeichnung svg { width: min(76%, 17rem); height: auto; }
.zg { fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.zg--fein { stroke-width: 1.4; opacity: 0.6; }
.zg--rot { stroke: var(--akzent); }
circle.zg--rot { fill: none; }
.galerie__zeichnung figcaption {
  text-align: center; font-size: 0.85rem; color: var(--grau);
  display: flex; flex-direction: column; gap: 0.15rem;
}
.galerie__folgt {
  font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--akzent); font-weight: 600;
}

/* ---- Lightbox ----------------------------------------------------------- */

.lupe {
  border: none; padding: 1.2rem;
  border-radius: var(--rund-gross);
  background: var(--papier);
  max-width: min(96vw, 90rem); max-height: 94vh;
  margin: auto;
  box-shadow: 0 30px 80px rgba(15, 14, 13, 0.35);
}
.lupe::backdrop { background: rgba(15, 14, 13, 0.82); }
.lupe img { max-width: 100%; max-height: 78vh; width: auto; height: auto; margin-inline: auto; }
.lupe__zeile { font-size: 0.85rem; color: var(--grau); text-align: center; margin-top: 0.7rem; }
.lupe__zu {
  position: absolute; top: 0.5rem; right: 0.5rem;
  width: 2.6rem; height: 2.6rem;
  border: 1px solid var(--linie); border-radius: var(--rund); background: var(--papier);
  font-size: 1.4rem; line-height: 1; cursor: pointer;
}
.lupe__zu:hover { background: var(--tinte); color: #fff; }
.lupe__pfeil {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 2.8rem; height: 2.8rem;
  border: 1px solid var(--linie); border-radius: var(--rund); background: var(--papier);
  font-size: 1.3rem; cursor: pointer;
}
.lupe__pfeil:hover { background: var(--tinte); color: #fff; }
.lupe__pfeil--zurueck { left: 0.5rem; }
.lupe__pfeil--vor { right: 0.5rem; }

/* ---- Angebots-Karussell (29.08.2026, Frederiks Auftrag) -----------------
   Ein raeumlicher Bilderring ueber der Preistafel: das vordere Bild steht
   mittig, die Nachbarn drehen mit rotateY in die Tiefe, ein Klick (Buehne
   oder Knopf) schiebt alle eine Position nach RECHTS, das rechteste
   rueckt hinten links wieder ein. data-pos vergibt seite.js; die
   STARTPOSITIONEN stehen im Markup (baue.py) — ohne JavaScript steht der
   Faecher fertig da (Muster „schaltet zu, niemals frei“).

   Drei Entscheidungen:
   - overflow:hidden liegt am AUSSENRAHMEN (.karussell), nicht an der
     Buehne mit den raeumlich stehenden Kindern: beschnitten werden soll
     nur, was seitlich hinauslaeuft, damit kein waagerechter Ueberlauf
     der SEITE entsteht (abnahme.py misst den zu drei Zeitpunkten).
   - Die Fotos bleiben KANTIG — Frederiks Regel vom 28.08.2026: der harte
     Bildrahmen gehoert zur Fotografie, gerundet werden nur UI-Kaesten.
   - Der Weiterdreh-Knopf traegt --rund aus der Rundungs-Skala, keinen
     Kreis — ein neuer Kasten bekommt nie eine eigene Zahl. */
.karussell { overflow: hidden; margin-top: 0.6rem; }
.karussell__buehne {
  position: relative;
  perspective: 70rem;
  /* Vergroessert am 29.08.2026 (Frederiks Ansage „ein kleinwenig
     groesser“). NUR die obere Haelfte der clamp waechst: Unter 900 px
     sitzt die Bandmitte rechts der Fenstermitte (Sucher-Rand), und die
     11-rem-Untergrenze ist dort auf 4 px Rand eingemessen — eine
     groessere Untergrenze ragte wieder ueber den rechten Rand
     (Abnahme-Befund vom selben Tag davor). */
  height: clamp(16rem, 36vw, 25.5rem);
}
html.js .karussell__buehne { cursor: pointer; }
/* Diese Grundregel ist zugleich der WARTEZUSTAND (30.08.2026): Sichtbar
   sind immer nur fuenf Plaetze (-2..2). Hat ein Bereich mehr Bilder — die
   Portraitseite hat seit dem 30.08.2026 elf —, stehen alle uebrigen genau
   hier: mittig, ganz hinten, unsichtbar, hinter dem vorderen Bild. Sie
   ruecken mit jedem Schritt nach und tauchen bei -2 aus der Tiefe auf.
   z-index 1 ist die UNTERSTE Sprosse der Leiter (siehe unten) und gehoert
   allein den Wartenden — jeder sichtbare Platz hat eine eigene, hoehere
   Zahl. Der Faecher wird dadurch nie dichter, egal wie viele Bilder
   dazukommen. */
.karussell__bild {
  position: absolute; top: 50%; left: 50%;
  width: clamp(11rem, 25vw, 18.5rem);
  aspect-ratio: 3 / 4;
  opacity: 0; z-index: 1;
  transform: translate(-50%, -50%) translateZ(-14rem);
  /* 0,5 s ist die Obergrenze des Hauskorridors (pruefe.py: 100-500 ms) —
     fuer die Drehung genau richtig: langsamer wirkte zaeh. */
  transition: transform 0.5s cubic-bezier(0.25, 0.7, 0.2, 1),
              opacity 0.5s ease, filter 0.5s ease;
}
.karussell__bild picture, .karussell__bild img {
  width: 100%; height: 100%; display: block;
}
.karussell__bild img { object-fit: cover; }
.karussell__bild[data-pos="0"] {
  transform: translate(-50%, -50%) translateZ(2.5rem);
  opacity: 1; z-index: 6;
  box-shadow: 0 26px 55px rgba(20, 20, 18, 0.2);
}
/* JEDE Position bekommt eine EIGENE Stapelzahl (29.08.2026, Frederiks
   Befund „ab und zu laeuft das Bild vor dem vorletzten statt dahinter"):
   Bei GLEICHER z-index entscheidet die Reihenfolge im Dokument, welches
   Bild oben liegt — und welches der fuenf Bilder gerade hinten herumfaehrt,
   wechselt mit jedem Schritt. Dadurch stimmte die Ueberdeckung mal und mal
   nicht, ohne dass sich am CSS etwas geaendert haette. Die Leiter lautet
   jetzt lueckenlos 6 > 5 > 4 > 3 > 2 (vorn, -1, +1, +2, Rueckfahrer),
   darunter die 1 der WARTENDEN; Gleichstand gibt es nirgends mehr.
   (Bis zum 30.08.2026 trug -2 die 1. Seit die Portraitseite mehr als
   fuenf Bilder hat, teilte -2 diese Zahl mit den Wartenden — und genau
   dort kreuzen sich beim Nachruecken das ausfahrende Bild (+2 -> +3,
   blendet ab) und das einfahrende (-3 -> -2, blendet auf). Derselbe
   Gleichstand, gegen den die Leiter gebaut wurde, eine Stufe tiefer.)
   Die Zahlen werden BEIM WECHSEL DES ATTRIBUTS sofort gesetzt (z-index
   liegt bewusst nicht im transition-Feld) — das Bild ist also schon in dem
   Moment hinten, in dem seine 5-Sekunden-Fahrt beginnt. */
.karussell__bild[data-pos="1"], .karussell__bild[data-pos="-1"] {
  opacity: 1; filter: brightness(0.94);
}
.karussell__bild[data-pos="-1"] { z-index: 5; }
.karussell__bild[data-pos="1"] { z-index: 4; }
.karussell__bild[data-pos="1"] {
  transform: translate(-50%, -50%) translateX(72%) rotateY(-28deg) translateZ(-5rem);
}
.karussell__bild[data-pos="-1"] {
  transform: translate(-50%, -50%) translateX(-72%) rotateY(28deg) translateZ(-5rem);
}
/* Voll deckend auch aussen (Frederiks Ansage 29.08.2026: das Bild, das
   rechts hinausfaehrt und hinten links wieder einrueckt, soll nicht
   durchscheinen — halbtransparent wirkte „unorthodox"). Die Tiefe traegt
   allein die leichte Abdunklung. */
.karussell__bild[data-pos="2"], .karussell__bild[data-pos="-2"] {
  opacity: 1; filter: brightness(0.88);
}
.karussell__bild[data-pos="2"] { z-index: 3; }
/* Position -2 ist im laufenden Ring IMMER der Rueckfahrer: Er kommt von
   +2, quert die ganze Buehne nach links und rueckt hinten wieder ein.
   Deshalb die kleinste Zahl der Leiter — er laeuft damit HINTER allen
   vier anderen durch, auch waehrend er die Mitte quert (dort liegt er
   auf translateZ(-11rem) und ist vom vorderen Bild vollstaendig
   verdeckt). Im Ruhezustand aendert das nichts: links aussen lag er
   auch vorher schon hinter seinem Nachbarn. Er bleibt aber VOR den
   Wartenden (z-index 1) — sonst tauchte das einfahrende Bild hinter
   unsichtbaren Bildern auf. */
.karussell__bild[data-pos="-2"] { z-index: 2; }
.karussell__bild[data-pos="2"] {
  transform: translate(-50%, -50%) translateX(128%) rotateY(-38deg) translateZ(-11rem);
}
.karussell__bild[data-pos="-2"] {
  transform: translate(-50%, -50%) translateX(-128%) rotateY(38deg) translateZ(-11rem);
}
/* Die DAUERFAHRT (29.08.2026, Frederiks Ansage: „keine Animation …
   sondern ein statischer Wechsel“ — gemeint war die 0,5-s-Drehung mit
   4 s Stillstand): Waehrend die Autorotation laeuft, traegt die Buehne
   .karussell__buehne--fahrt. Die Uebergangsdauer entspricht dann GENAU
   dem Takt in seite.js (5 s) und laeuft linear — alle Bilder sind
   staendig gleichzeitig in Bewegung und FAHREN durch den Ring, statt zu
   springen. Ein Klick nimmt die Klasse ab und dreht mit den schnellen
   0,5 s von oben. Die 5 s stehen im Korridor-Waechter von pruefe.py als
   zweite Buehnen-Ausnahme neben der Bild-Enthuellung — wer Takt ODER
   Dauer aendert, aendert beide. */
.karussell__buehne--fahrt .karussell__bild {
  transition: transform 5s linear, opacity 5s linear, filter 5s linear;
}

/* Der Knopf erscheint erst MIT JavaScript — ohne Skript dreht nichts,
   also verspricht auch nichts einen Klick. 2,75 rem = 44 px Klickflaeche
   (WCAG 2.2 verlangt 24). */
.karussell__weiter {
  display: none;
  width: 2.75rem; height: 2.75rem;
  margin: 1.2rem auto 0;
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund);
  cursor: pointer;
  transition: border-color 0.3s ease;
}
html.js .karussell__weiter { display: block; }
.karussell__weiter:hover, .karussell__weiter:focus-visible {
  border-color: var(--tinte);
}
.karussell__pfeil {
  display: block; width: 0.55rem; height: 0.55rem;
  margin: 0 auto;
  border-right: 1.6px solid var(--tinte);
  border-bottom: 1.6px solid var(--tinte);
  transform: translateX(-2px) rotate(-45deg);
}
/* Schmale Fenster (Abnahme-Befund 29.08.2026, 375/500 px): die weit
   ausgestellten Positionen ragten ueber den rechten Seitenrand —
   overflow:hidden beschneidet sie zwar, aber ein Element ueber dem Rand
   bleibt ein Element ueber dem Rand (abnahme.py, Messung 6). Unter
   56,25 rem rueckt der Faecher enger zusammen und die Positionen ±2
   falten sich in den verborgenen Mittelzustand — bei drei sichtbaren
   Bildern bleibt jede Kante im Fenster (die Bildmitte des Bandes sitzt
   wegen des Sucher-Rands RECHTS der Fenstermitte — 52 % ragten dort
   noch 7 px hinaus, gemessen 29.08.2026; darum 46 %). */
@media (max-width: 56.25rem) {
  .karussell__bild[data-pos="1"] {
    transform: translate(-50%, -50%) translateX(46%) rotateY(-24deg) translateZ(-4rem);
  }
  .karussell__bild[data-pos="-1"] {
    transform: translate(-50%, -50%) translateX(-46%) rotateY(24deg) translateZ(-4rem);
  }
  /* Deckend auch hier: hinter dem vorderen Bild ohnehin verdeckt, und
     waehrend der Fahrt dahin bleibt das Bild sichtbar statt zu
     verblassen (dieselbe Ansage wie oben). */
  .karussell__bild[data-pos="2"], .karussell__bild[data-pos="-2"] {
    opacity: 1;
    transform: translate(-50%, -50%) translateZ(-14rem);
  }
}

/* Nur SMARTPHONES (Frederiks Ansage 29.08.2026: „auf dem Smartphone sehr
   klein" — und ausdruecklich NUR dort; Tablets behalten den 25vw-Faecher
   der Regel darueber): groessere Bilder, dafuer ein engerer Faecher.
   Die Rechnung haengt an der Ueberlauf-Grenze (abnahme.py, Messung 6,
   auch beschnittene Elemente zaehlen): Bandmitte sitzt ~15 px RECHTS der
   Fenstermitte (Sucher-Rand), bei 375 px und 58vw-Bild (217 px) bleiben
   mit 25 % Versatz rund 17 px Rand, bei 320 px rund 15 px. Die Buehne
   waechst mit dem Bild mit (4:3 + Schattenluft), gedeckelt wie das Bild. */
@media (max-width: 40rem) {
  .karussell__buehne {
    height: min(calc(58vw * 1.3334 + 1.5rem), 21.5rem);
  }
  .karussell__bild { width: min(58vw, 15rem); }
  .karussell__bild[data-pos="1"] {
    transform: translate(-50%, -50%) translateX(25%) rotateY(-22deg) translateZ(-3.5rem);
  }
  .karussell__bild[data-pos="-1"] {
    transform: translate(-50%, -50%) translateX(-25%) rotateY(22deg) translateZ(-3.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .karussell__bild, .karussell__weiter { transition: none; }
}

/* ---- Preistafel: eine Karte je Paket ------------------------------------
   Neu gefasst am 29.08.2026 nach Frederiks Vorlage (beigeandwhite.de/
   pakete): ruhige weisse Karten mit Serifentitel (Playfair Display),
   bescheidener Preiszeile und stiller INKLUSIVE-Liste — statt grossem
   Preis und Haarlinie je Merkmalzeile. Namen, Preise und Merkmale sind
   unveraendert (inhalt.py); die Dauer (ueberall die ERSTE Merkmalzeile)
   steht als eigene fette Zeile unter dem Preis, wie in der Vorlage.

   UEBERNOMMEN aus der alten Tafel:
   - Der Haken ist aus zwei KANTEN gezeichnet, kein U+2713 — die
     Schriften sind Auszuege, ein fehlendes Zeichen bliebe still leer.
   - Hervorhebung aendert NIE die Rahmenstaerke (1 px bleibt 1 px), nur
     die FARBE: 1,5 px verschoben den Inhalt um einen gemessenen Pixel
     gegen die Nachbarkarte (28.08.2026, align-items: stretch).
   - Die Spalten-Schwelle misst den CONTAINER, nicht das Fenster.
   ENTFALLEN mit der Vorlage: die Anhebung der Mitte und das Etikett
   ueber der Kante — das Etikett sitzt jetzt als Chip IM Kartenkopf
   (wie „Beliebt“ in der Vorlage), alle Karten stehen auf einer
   Linie. Und: VIER Karten stehen in EINER Reihe (Frederiks Vorgabe
   29.08.2026; vorher 2x2).
   -------------------------------------------------------------------- */

/* `margin-top` ist die Luft UNTER dem Karussell, nicht ein Abstand der
   Tafel — deshalb haengt sie seit dem 31.08.2026 am Ring statt an der
   Tafel. Auf einer Seite OHNE Ring (Paar & Familie seit 31.08., Hochzeit)
   stand sie sonst als 41,6 px Rest ueber der ersten Gruppenzeile, zusaetz-
   lich zum Blockpolster. `.block--hochzeitspreis .tarife` weiter unten ist
   gleich spezifisch und steht spaeter — die Hochzeitsseite behaelt ihre
   eigene Zahl. */
.tarife {
  max-width: var(--breite); margin-inline: auto;
  display: grid; gap: clamp(2.6rem, 5vw, 3.8rem); margin-top: 0;
}
.karussell + .tarife { margin-top: 2.6rem; }

.tarifgruppe__titel {
  font-family: var(--display); font-weight: 700; font-size: 1.6rem;
  padding-bottom: 0.85rem; margin-bottom: 0.4rem;
  border-bottom: 1px solid var(--linie);
}
/* 0-1-1 schlaegt die em-Regel (0-0-1) — das Gewicht muss hier stehen,
   sonst faelscht der Browser einen Schnitt, den Fraunces nicht hat. */
.tarifgruppe__titel em { color: var(--akzent); font-weight: 500; }
/* Eine unsichtbare Ueberschrift bleibt fuer die Sprachausgabe stehen,
   darf aber weder Linie noch Abstand mitbringen. */
.tarifgruppe__titel.unsichtbar { border-bottom: none; padding: 0; margin: 0; }

.pakete-feld { container-type: inline-size; }
.pakete {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 1.6rem; justify-items: center; margin-top: 2.2rem;
}

.paket {
  position: relative;
  width: 100%; max-width: 30rem;
  display: flex; flex-direction: column; align-items: flex-start;
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: clamp(1.6rem, 2.6cqi, 2.4rem) clamp(1.3rem, 2.4cqi, 2rem);
}
/* Wie in der Vorlage traegt die ausgezeichnete Karte eine getoente
   Rahmenlinie — abgemildertes Signaturrot; Vollrot waere lauter als die
   Vorlage. GLEICHE Staerke, nur die Farbe (siehe Kopfkommentar). */
.paket--hervor {
  border-color: color-mix(in srgb, var(--akzent) 55%, var(--linie));
}

/* ---- Die Karte reagiert auf Zeigen (zurueck am 29.08.2026) ------------
   Nach dem Wegfall der Kartenknoepfe stand die Karte kurz still;
   Frederiks Ansage noch am selben Tag: beim Hover sollen sich FARBE und
   GROESSE leicht aendern. transform aendert nur die Darstellung, nicht
   den Platz — die Nachbarkarten stehen still (die 1-px-Falle vom 28.08.
   betrifft Rahmen und Polster, nicht transform). scale bewusst klein
   (1,02): mehr weicht die Schrift auf. Hinter (hover:hover), damit die
   Auszeichnung am Telefon nicht nach dem Antippen klebt; z-index, sonst
   legt sich der Rahmen der Nachbarkarte ueber den Schatten; reduzierte
   Bewegung nimmt die Groessenaenderung heraus, die Farbe bleibt. */
.paket {
  transition: transform 0.3s ease, border-color 0.3s ease,
              box-shadow 0.3s ease;
}
@media (hover: hover) {
  .paket:hover {
    border-color: var(--tinte);
    box-shadow: 0 18px 40px rgba(20, 20, 18, 0.09);
    transform: scale(1.02);
    z-index: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .paket { transition: none; }
  .paket:hover { transform: none; }
}

/* Das Etikett sitzt als Chip IM Kartenkopf, wie „Beliebt“ in der
   Vorlage — nicht mehr ueber der Kante. Karten ohne Chip beginnen mit
   dem Titel etwas hoeher; auch das macht die Vorlage so. */
.paket__etikett {
  display: inline-block;
  background: var(--papier-warm);
  border: 1px solid var(--linie);
  border-radius: var(--rund-klein);
  font-family: var(--text); font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tinte-weich);
  padding: 0.32rem 0.7rem;
  margin-bottom: 1.05rem;
}

/* Der Serifentitel — die eine Stelle, an der --serif auftritt. */
.paket__name {
  font-family: var(--serif); font-weight: 500;
  font-size: clamp(1.45rem, 2.4cqi, 1.85rem); line-height: 1.12;
  letter-spacing: 0.005em;
  color: var(--tinte);
}
.paket__preis {
  font-family: var(--text); font-weight: 700; font-size: 1.08rem;
  margin-top: 0.85rem; font-variant-numeric: lining-nums;
}
.paket__dauer {
  margin-top: 0.55rem; font-size: 0.95rem; font-weight: 600;
  color: var(--tinte-weich);
}

.paket__inklusive {
  width: 100%;
  margin-top: 1.35rem; padding-top: 1.35rem;
  border-top: 1px solid var(--linie);
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--grau);
}
.paket__merkmale {
  list-style: none; width: 100%;
  margin-top: 0.9rem; margin-bottom: 0.3rem;
}
.paket__merkmale li {
  display: flex; align-items: flex-start; gap: 0.72rem;
  padding: 0.42rem 0;
  font-size: 0.95rem; color: var(--tinte-weich); line-height: 1.5;
}
/* Zwei Kanten, um 45 Grad gedreht — gezeichnet, nicht gesetzt. Der Haken
   ist in der Vorlage stiller als der Text: --grau statt --tinte. */
.paket__haken {
  flex: none;
  width: 0.6rem; height: 0.33rem; margin-top: 0.5rem;
  border-left: 1.6px solid var(--grau);
  border-bottom: 1.6px solid var(--grau);
  transform: rotate(-45deg);
}


/* Etwas breiter als der Fliesstext des Abschnitts: der Satz gehoert
   unter die Karten, nicht in eine eigene schmale Spalte daneben. */
.tarifgruppe__zusatz {
  margin-top: 1.2rem; font-size: 0.92rem; color: var(--grau);
  max-width: 48rem;
}

/* Drei — und auf der Portraitseite VIER — Spalten erst, wenn das FELD
   sie traegt. Die 59-rem-Schwelle stammt aus der alten Tafel (eingemessen
   an der dichtesten Seite, Firmen & Event); die neue Liste darf umbrechen
   wie die Vorlage, Haarlinien je Zeile gibt es nicht mehr — die Schwelle
   bewacht jetzt Titel- und Knopfbreite. Darunter: EINE ruhige Saeule. */
@container (min-width: 59rem) {
  .pakete {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1.1rem, 2cqi, 1.6rem);
    align-items: stretch;
    margin-top: 1.8rem;
  }
  .paket { max-width: none; }
  /* Vier in EINER Reihe (Frederiks Vorgabe 29.08.2026; vorher 2x2).
     Die Karten sind schmaler als im Dreierfeld — Innenpolster und
     Titel weichen ueber cqi mit, gemessen am laengsten Namen
     („Ausfuehrlich“) und am Knopftext. */
  .pakete--vier { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .pakete--vier .paket { padding-inline: clamp(1.1rem, 1.8cqi, 1.7rem); }
  .pakete--vier .paket .paket__name { font-size: clamp(1.3rem, 2cqi, 1.6rem); }
}

.objekt {
  max-width: var(--breite); margin-inline: auto; margin-top: 2.2rem;
  border-left: 3px solid var(--akzent);
  padding: 0.4rem 0 0.4rem 1.6rem;
}
.objekt h3 { font-family: var(--display); font-size: 1.5rem; font-weight: 700; }
.objekt h3 em { color: var(--akzent); }
.objekt p { color: var(--grau); margin-top: 0.7rem; }
.objekt .knopf { margin-top: 0.4rem; }

/* ---- Zweispalt, Hinweis, Liste ------------------------------------------ */

.zweispalt {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  max-width: var(--breite); margin-inline: auto;
}
.zweispalt > * { margin-inline: 0; }
.zweispalt h2 { font-size: 1.75rem; margin-bottom: 0.8rem; }
@media (max-width: 820px) { .zweispalt { grid-template-columns: 1fr; } }

.hinweis {
  margin-top: 1.6rem; padding: 1.2rem 1.4rem;
  border: 1px solid var(--linie); background: var(--papier-warm);
  border-radius: var(--rund-gross);
}
.hinweis h3 { font-size: 1.1rem; }
.hinweis p { font-size: 0.95rem; color: var(--grau); margin-top: 0.5rem; }

.liste { list-style: none; }
.liste li {
  padding: 0.7rem 0 0.7rem 1.6rem;
  border-bottom: 1px solid var(--linie);
  position: relative;
}
.liste li::before {
  content: ""; position: absolute; left: 0; top: 1.35rem;
  width: 0.55rem; height: 0.55rem;
  border: 2px solid var(--akzent);
  border-radius: 50%;
}

/* ---- Ablauf-Seite: Buehne + Zeitleiste (Neuaufbau 01.09.2026) -----------
   Frederiks Auftrag mit Referenz-Screenshots, in vier Runden gewachsen:
   links ein haftender Kopf mit der Handlung, rechts die Zeitleiste —
   Piktogramm-Muenzen auf einer Bahn, die der Scroll-Scrub (--f,
   seite.js) mit dem Akzent fuellt; je Schritt eine warme Karte
   (Runde 4) mit Blocksatz-Text (Runde 3, Grenzen s. u.) und einem
   kleinen Buehnenbild (Runde 2). Der fertige Zustand ist der Standard:
   --f steht hier auf 1, das Skript scrubbt 0 -> 1; die Schritt-Reveals
   laufen ueber die .zeige-Mechanik samt Reissleine. Alle Uebergaenge
   dieser Buehne liegen im 100-500-ms-Korridor. */

.ablauf-lage {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.4rem, 6vw, 5.5rem);
  align-items: start;
}
.ablauf-lage > * { min-width: 0; }
/* Der Kopf haftet nur, wo beide Spalten nebeneinander stehen — einspaltig
   waere ein haftender Kopf ein Hindernis VOR der Liste. */
@media (min-width: 861px) {
  .ablauf-kopf { position: sticky; top: clamp(5rem, 12vh, 7rem); }
}
/* Eigene Groesse statt der 4,6-rem-Schauzeile: die H1 teilt sich die
   Breite mit der Zeitleiste. 0-1-1 gegen die Typregel h1 (0-0-1).
   hyphens: none — Frederiks Ansage 01.09.2026: „Shooting" wird nicht
   getrennt; break-word bleibt als Netz, und das laengste Wort passt
   bei 375 px einzeilig. */
.ablauf-kopf h1 { font-size: clamp(2.1rem, 3.8vw, 3.4rem); max-width: 13em; hyphens: none; }
/* Linksbuendig und OHNE Silbentrennung (Frederiks Ansage 01.09.2026,
   „Ueberra-schungen" brach hier um) — die ruhige Kante traegt
   text-wrap: pretty, die Spalte ist mit ~44 Zeichen breit genug. */
.ablauf-kopf__text {
  color: var(--grau); font-size: 1.12rem; margin-top: 1.2rem;
  text-wrap: pretty;
  hyphens: manual;
}
.ablauf-kopf__knoepfe { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.9rem; }

.lauf { position: relative; --f: 1; /* fertiger Zustand; seite.js scrubbt 0 -> 1 */ }
/* Die Bahn beginnt in der Mitte der ersten Muenze (Muenzen-Offset
   0,55 rem + halbe Muenze 1,7 rem) und laeuft unten weich aus — ein
   hartes Ende mitten im letzten Schritt saehe abgeschnitten aus. Die
   Maske beschneidet auch den Akzentzug, er ist ihr Kind. */
.lauf__bahn {
  position: absolute; top: 2.25rem; bottom: 0.4rem;
  left: calc(1.7rem - 1.5px); width: 3px;
  background: var(--linie); border-radius: 2px;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 5rem), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 5rem), transparent);
}
.lauf__zug {
  position: absolute; top: 0; left: 0; width: 100%;
  height: calc(var(--f) * 100%);
  background: var(--akzent); border-radius: 2px;
}
.lauf__schritte { list-style: none; display: grid; gap: clamp(1.6rem, 3vw, 2.2rem); }
.lauf__schritt {
  display: grid; grid-template-columns: 3.4rem minmax(0, 1fr);
  column-gap: clamp(1rem, 2.2vw, 1.4rem);
  align-items: start;
}
/* Die Muenze steht deckend AUF der Bahn (z-index 1), damit die Linie
   hinter ihr durchlaufen kann, ohne sie zu schneiden; der kleine
   Offset setzt ihre Mitte auf Hoehe der Titelzeile in der Karte. */
.lauf__zeichen {
  width: 3.4rem; height: 3.4rem; border-radius: 50%;
  background: var(--papier); border: 1px solid var(--linie);
  display: grid; place-items: center;
  position: relative; z-index: 1;
  margin-top: 0.55rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.np--lauf { width: 1.6rem; height: 1.6rem; }

/* Je Schritt eine Karte (Runde 4, Frederiks Referenz-Screenshot):
   warmes Papier, Haarlinie, grosse Hausrundung — Erhebung ueber
   Flaechenkontrast, nicht ueber Schatten (Preistafel-Muster). */
.lauf__karte {
  background: var(--papier-warm);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: clamp(1.1rem, 2vw, 1.45rem) clamp(1.2rem, 2.2vw, 1.6rem);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
/* Ab 1160 px steht das Buehnenbild als zweite Spalte IN der Karte —
   darunter faellt es unter den Text (sonst fiele die Textspalte unter
   ~35 Zeichen). Die Schwelle sass frueher am li, jetzt an der Karte. */
@media (min-width: 1160px) {
  .lauf__karte {
    display: grid; grid-template-columns: minmax(0, 1fr) 10.5rem;
    column-gap: 1.3rem; align-items: center;
  }
  .lauf__karte > .lauf__text { align-self: start; }
}
.lauf__nr {
  font-family: var(--zier); font-style: italic; font-weight: 500;
  font-size: 1.05rem; line-height: 1; color: var(--akzent);
}
/* Klasse steht mit im Selektor, damit die Ausnahme spezifischer ist als
   die Sammelregel `h2` (die Spezifitaetsfalle dieses Ordners). */
.lauf__schritt h2.lauf__titel {
  font-size: clamp(1.25rem, 2vw, 1.5rem); letter-spacing: -0.005em;
  margin-top: 0.25rem;
}
/* Blocksatz auf Frederiks Ansage (01.09.2026, dritte Runde) — die
   Hausregel warnt: deutscher Blocksatz ohne verlaessliche Trennung
   reisst Loecher. Deshalb bleibt hyphens: auto AN und wird nur
   GEZUEGELT: getrennt wird erst ab 9 Zeichen und nie naeher als 4
   an den Wortenden. Die 4/4-Mindestlaenge verhindert strukturell
   genau die haesslichen Kurztrennungen („pas-sieren",
   „Ueberraschun-gen"); getrennt wird im Blocksatz ohnehin nur, wo
   sonst ein Loch risse — bei ~50 Zeichen Spaltenbreite selten, in
   der schmalen Spalte oefter, und das ist dort das kleinere Uebel.
   Firefox kennt die Grenzen nicht und trennt normal (dort schliesst
   die Trennung die Luecken). Das Abnahme-Chromium kennt KEINE
   deutschen Trennmuster; die Kontaktboegen uebertreiben die
   Lueckenbildung deshalb — im echten Chrome nachsehen, nicht am
   Bogen urteilen. */
.lauf__satz {
  color: var(--grau); margin-top: 0.45rem; max-width: 52ch;
  text-align: justify;
  hyphens: auto;
  hyphenate-limit-chars: 9 4 4;
  -webkit-hyphenate-limit-before: 4;
  -webkit-hyphenate-limit-after: 4;
}
/* Die Meta-Zeile trennt NIE — gesperrte Versalien mit Trennstrich
   („SEL-BEN") sehen nach Fehler aus; sie darf zweizeilig werden, der
   haengende Einzug faengt das auf. */
.lauf__meta {
  font-size: 0.78rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--grau); margin-top: 0.7rem;
  padding-left: 1.65rem; text-indent: -1.65rem;
  hyphens: manual;
}
.lauf__meta::before {
  content: ""; display: inline-block;
  width: 1.1rem; height: 2px; background: var(--akzent);
  margin-right: 0.55rem; vertical-align: 0.22em;
  transition: width 0.2s ease;
}

/* Buehnenbilder (Runde 2): in der warmen Karte WEISS — sonst
   verschwaende Flaeche auf Flaeche (die moosa-Falle: eine Flaeche in
   der Farbe ihres Grundes ist unsichtbar). Rein dekorativ, aria-hidden
   im Markup; jede Aussage steht daneben als Text. EIN roter Akzent je
   Bild. */
.vig {
  width: min(11rem, 100%);
  min-height: 6.6rem;
  margin-top: 1rem;
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund);
  display: flex; flex-direction: column;
  justify-content: center; align-items: center;
  gap: 0.4rem; padding: 0.8rem;
}
@media (min-width: 1160px) {
  .vig { grid-column: 2; grid-row: 1; width: 10.5rem; margin-top: 0; justify-self: end; }
}
/* 01 — der Anfragebogen in klein; die Feldzeilen tragen den warmen Ton,
   sonst waeren sie weiss auf weiss */
.vig__feld {
  display: block; width: 78%; height: 0.55rem;
  background: var(--papier-warm); border: 1px solid var(--linie);
  border-radius: 0.3rem;
}
.vig__feld--kurz { width: 52%; }
.vig__knopf {
  display: inline-block; margin-top: 0.15rem;
  font-size: 0.62rem; font-weight: 600; letter-spacing: 0.01em;
  color: var(--papier); background: var(--tinte);
  padding: 0.32em 0.85em; border-radius: var(--rund);
  transition: background-color 0.2s ease;
}
/* 02 — Chat mit Terminzusage; die Zusage traegt den roten Akzent */
.vig--antwort { align-items: stretch; }
.vig__blase {
  display: block; width: fit-content; max-width: 92%;
  font-size: 0.62rem; line-height: 1.45; color: var(--tinte-weich);
  background: var(--papier-warm); border: 1px solid var(--linie);
  border-radius: 0.6rem 0.6rem 0.6rem 0.2rem;
  padding: 0.3em 0.75em;
}
.vig__blase--ich {
  margin-left: auto; color: #fff;
  background: var(--akzent); border-color: var(--akzent);
  border-radius: 0.6rem 0.6rem 0.2rem 0.6rem;
}
.vig__haken {
  display: inline-block; width: 0.5em; height: 0.28em;
  border-left: 1.5px solid #fff; border-bottom: 1.5px solid #fff;
  transform: rotate(-45deg); margin-left: 0.3em;
  vertical-align: 0.14em;
}
/* 03 — Sucher: vier Ecken, Motiv, roter AF-Rahmen, EXIF-Zeile */
.vig--shooting { position: relative; }
.vig__ecke { position: absolute; width: 0.8rem; height: 0.8rem; border: 1.5px solid var(--tinte); }
.vig__ecke--lo { top: 0.55rem; left: 0.55rem; border-right: 0; border-bottom: 0; }
.vig__ecke--ro { top: 0.55rem; right: 0.55rem; border-left: 0; border-bottom: 0; }
.vig__ecke--lu { bottom: 0.55rem; left: 0.55rem; border-right: 0; border-top: 0; }
.vig__ecke--ru { bottom: 0.55rem; right: 0.55rem; border-left: 0; border-top: 0; }
.vig__af {
  position: absolute; top: 1.5rem; right: 2.6rem;
  width: 0.9rem; height: 0.9rem;
  border: 1.5px solid var(--akzent);
  transition: transform 0.25s ease;
}
.np--vig { width: 2.1rem; height: 2.1rem; }
.vig__exif {
  font-size: 0.56rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--grau);
}
/* 04 — Galeriekacheln; Favoriten tragen die getoente Rahmenlinie der
   Preistafel-Hervorhebung (gleiche Staerke, nur Farbe) */
.vig--auswahl { display: grid; grid-template-columns: repeat(2, auto); gap: 0.45rem; justify-content: center; }
.vig__kachel {
  width: 2.6rem; height: 2rem;
  background: var(--papier-warm); border: 1px solid var(--linie);
  border-radius: 0.25rem;
  display: grid; place-items: center;
}
.vig__kachel--herz { border-color: color-mix(in srgb, var(--akzent) 55%, var(--linie)); }
.vig__kachel .np { width: 0.95rem; height: 0.95rem; transition: transform 0.2s ease; }
/* 05 — Regler; Bewegung nur auf Zeigen, 0,3 s im Korridor */
.vig--bearbeitung { align-items: stretch; gap: 0.75rem; padding-inline: 1.1rem; }
.vig--bearbeitung .vig__exif { align-self: center; margin-top: 0.1rem; text-align: center; }
.vig__spur { position: relative; display: block; height: 2px; background: var(--linie); border-radius: 1px; }
.vig__griff {
  position: absolute; top: 50%; width: 0.62rem; height: 0.62rem;
  transform: translate(-50%, -50%); border-radius: 50%;
  background: var(--papier); border: 1.5px solid var(--tinte);
  transition: left 0.3s ease;
}
.vig__spur--a .vig__griff { left: 34%; }
.vig__spur--b .vig__griff { left: 68%; border-color: var(--akzent); }
.vig__spur--c .vig__griff { left: 48%; }
/* 06 — das gerahmte Bild haengt leicht schief und richtet sich beim
   Zeigen auf — der Drehpunkt sitzt am Nagel */
.vig__nagel { width: 0.35rem; height: 0.35rem; border-radius: 50%; background: var(--akzent); }
.vig__rahmen {
  width: 3.9rem; padding: 0.32rem;
  background: var(--papier-warm); border: 2px solid var(--tinte);
  display: grid; place-items: center;
  transform: rotate(-3deg); transform-origin: 50% -0.45rem;
  transition: transform 0.25s ease;
}
.np--bild { display: block; width: 2.2rem; height: 1.5rem; }

/* Zeigen belohnt, Tippen klebt nicht: alles hinter (hover: hover). */
@media (hover: hover) {
  .lauf__schritt:hover .lauf__zeichen {
    border-color: var(--akzent);
    box-shadow: 0 10px 24px rgba(20, 20, 18, 0.08);
    transform: scale(1.06);
  }
  .lauf__schritt:hover .lauf__karte {
    border-color: color-mix(in srgb, var(--tinte) 26%, var(--linie));
    box-shadow: 0 18px 40px rgba(20, 20, 18, 0.06);
  }
  .lauf__schritt:hover .lauf__meta::before { width: 1.7rem; }
  .lauf__schritt:hover .vig__knopf { background: var(--akzent); }
  .lauf__schritt:hover .vig__af { transform: translate(-0.5rem, 0.45rem); }
  .lauf__schritt:hover .vig__kachel .np { transform: scale(1.18); }
  .lauf__schritt:hover .vig__spur--a .vig__griff { left: 52%; }
  .lauf__schritt:hover .vig__spur--b .vig__griff { left: 44%; }
  .lauf__schritt:hover .vig__spur--c .vig__griff { left: 64%; }
  .lauf__schritt:hover .vig__rahmen { transform: rotate(0deg); }
}
@media (prefers-reduced-motion: reduce) {
  .lauf__zeichen, .lauf__karte, .lauf__meta::before, .vig__knopf,
  .vig__af, .vig__kachel .np, .vig__griff, .vig__rahmen { transition: none; }
  .lauf__schritt:hover .lauf__zeichen { transform: none; }
}
@media (max-width: 860px) {
  .ablauf-lage { grid-template-columns: minmax(0, 1fr); }
  .lauf { margin-top: 0.4rem; }
  .lauf__schritt { grid-template-columns: 2.8rem minmax(0, 1fr); column-gap: 0.8rem; }
  .lauf__zeichen { width: 2.8rem; height: 2.8rem; margin-top: 0.45rem; }
  .np--lauf { width: 1.35rem; height: 1.35rem; }
  .lauf__bahn { left: calc(1.4rem - 1.5px); top: 1.85rem; }
  .lauf__karte { padding: 1rem 1.05rem; }
}

/* ---- Unfotogen (dunkle Strecke) ----------------------------------------- */

.unfotogen__zitat {
  font-size: clamp(2rem, 5vw, 3.6rem);
  max-width: 16em;
}
.unfotogen__zitat em { color: var(--akzent); }
.unfotogen .block__satz { max-width: 58ch; }

/* ---- Fragen (FAQ) ------------------------------------------------------- */

/* Fragen linksbündig zum Seitenkopf, Randspalte füllt den Weißraum —
   vorher stand die Liste zentriert und brach die Kante (25.08.2026). */
.fragen-lage {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(2rem, 5vw, 4rem); align-items: start;
  max-width: var(--breite); margin-inline: auto; margin-top: 2.4rem;
}
.fragen-lage > * { margin-inline: 0; }
.fragen__rand { display: grid; gap: 1rem; justify-items: start; }
.fragen__rand picture { background: var(--papier-warm); }
.fragen__rand .notiz { margin-top: 0; }
@media (max-width: 860px) {
  .fragen-lage { grid-template-columns: 1fr; }
  .fragen__rand { max-width: 26rem; }
}

.fragen { margin-top: 0; }
.frage { border-bottom: 1px solid var(--linie); }
/* Das Flexbett liegt seit 26.08.2026 im <h2> statt im <summary>: Die Frage
   ist eine Überschrift, das Plus-Zeichen ihr Kind (summary darf genau ein
   Überschriftenelement tragen). */
.frage summary {
  padding: 1.15rem 0.2rem; cursor: pointer;
  list-style: none;
}
.frage summary::-webkit-details-marker { display: none; }
.frage__titel {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  font-family: var(--display); font-size: 1.3rem; font-weight: 700;
  line-height: 1.25; letter-spacing: 0;
}
.frage__plus { position: relative; width: 1rem; height: 1rem; flex: none; }
.frage__plus::before, .frage__plus::after {
  content: ""; position: absolute; background: var(--akzent);
  transition: transform 0.3s ease;
}
.frage__plus::before { left: 0; top: calc(50% - 1px); width: 100%; height: 2px; }
.frage__plus::after { top: 0; left: calc(50% - 1px); height: 100%; width: 2px; }
.frage[open] .frage__plus::after { transform: scaleY(0); }
.frage p { color: var(--grau); padding: 0 0.2rem 1.3rem; }

/* ---- Formular ----------------------------------------------------------- */

.formular { max-width: 52rem; margin-inline: auto; margin-top: 2.6rem; }
.formular__gitter {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem 2.2rem;
}
@media (max-width: 700px) { .formular__gitter { grid-template-columns: 1fr; } }

.feld { display: flex; flex-direction: column; gap: 0.3rem; margin-top: 1.2rem; max-width: none; }
.feld label {
  font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--grau);
  /* Fest gesetzt, nicht geerbt: Das Beschriftungsband unten rechnet in
     Zeilen, und die Erbschaft aus dem body (1,65) ist fuer 12-px-Versalien
     ohnehin zu locker. */
  line-height: 1.35;
}
.feld input, .feld select, .feld textarea {
  font: inherit; color: var(--tinte);
  background: transparent;
  border: none; border-bottom: 1.5px solid var(--tinte-weich);
  border-radius: 0;
  padding: 0.45rem 0.1rem;
}
.feld select { cursor: pointer; }
.feld input:focus-visible, .feld select:focus-visible, .feld textarea:focus-visible {
  outline: none;
  border-bottom-color: var(--akzent);
  box-shadow: 0 1.5px 0 var(--akzent);
}
.feld textarea { border: 1.5px solid var(--tinte-weich); border-radius: var(--rund); padding: 0.7rem; resize: vertical; }
.feld textarea:focus-visible { border-color: var(--akzent); box-shadow: none; }

.formular fieldset {
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: 1.2rem 1.4rem 1.4rem;
  margin-top: 2rem;
}
.formular legend {
  font-family: var(--display); font-size: 1.2rem; font-weight: 700;
  padding: 0 0.6rem;
}
.formular fieldset label {
  display: flex; align-items: baseline; gap: 0.55rem;
  padding: 0.3rem 0; cursor: pointer;
}
.formular input[type="radio"] { accent-color: var(--akzent); }

.feld--falle { position: absolute; left: -200vw; width: 1px; height: 1px; overflow: hidden; }

.slots { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0.6rem 0 1rem; }
.slot {
  font: inherit; font-size: 0.9rem;
  border: 1.5px solid var(--tinte-weich); border-radius: var(--rund-klein);
  background: var(--papier);
  padding: 0.45rem 0.9rem; cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.slot:hover { border-color: var(--akzent); color: var(--akzent); }
.slot[aria-pressed="true"] { background: var(--tinte); border-color: var(--tinte); color: #fff; }

.formular__fehler {
  border: 1.5px solid var(--akzent);
  border-radius: var(--rund);
  background: color-mix(in srgb, var(--akzent) 6%, var(--papier));
  padding: 1rem 1.2rem; margin-top: 1.6rem;
  font-size: 0.98rem;
}


/* ---- Kontaktbogen (30.08.2026, beigeandwhite-Vorlage) -------------------
   EIN Anfragebogen auf kontakt.html, Nachfolger der vierstufigen
   Terminseite: links die weisse Formularkarte auf warmem Grund, rechts
   Kontaktkarte und Foto. Muster der Vorlage, Farben, Schriften und
   Rundungs-Skala vom Haus (--rund-gross Karten, --rund Knoepfe/Felder,
   --rund-klein Kacheln; Fotos bleiben kantig).

   Spezifizitaet, wie immer in diesem Ordner: `.formular fieldset` und
   `.feld input` sind Klasse+Typ — jede Ausnahme unten ist deshalb
   mindestens `.formular--bogen …` (eine Stufe spezifischer), sonst
   verliert sie lautlos (die Falle steht achtmal im Gedaechtnis). */

.anfrage {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(1.4rem, 3vw, 2.6rem);
  max-width: var(--breite); margin-inline: auto;
  margin-top: 2.4rem;
  align-items: start;
}

/* ---- Der Bogen rueckt an den Kopf (30.08.2026, Frederiks Ansage) -------
   „Setze das Kontaktformular hoeher an die navbar, dass die Besucher
   direkt einen grossen Teil des Kontaktformulars sehen."

   Denselben Weg wie am 26.08. auf der Terminseite: der Platz kommt aus
   MEHREREN kleinen Posten, nicht aus einem grossen — ein einzelner
   haette entweder die Schauzeile entwertet oder den Bogen gequetscht.
   `block--knapp` (Haus-Schalter) traegt das Generische, das
   Seitenspezifische haengt hier an `.block--anfragekopf` und an
   `.anfrage`, die es auf keiner anderen Seite gibt.

   Die H1 ist bewusst 0-2-1 (`.block.block--anfragekopf h1`): die
   Falz-Regeln von `block--knapp` weiter unten sind 0-1-1 und wuerden sie
   in flachen Fenstern sonst wieder aufblasen — dort ist die eigene
   vh-Kopplung (unten) die schaerfere. */
.block.block--anfragekopf h1 { font-size: clamp(1.9rem, 3.6vw, 3.1rem); }
.block--anfragekopf .block__satz { margin-top: .7rem; }
.block--anfragekopf .anfrage { margin-top: 1.5rem; }
@media (max-height: 820px) {
  /* Flache Laptopfenster: die Schauzeile haengt zusaetzlich an der
     Fensterhoehe — sonst frisst genau sie den gewonnenen Platz wieder
     auf (Muster vom 26.08.2026, dort an drei Hoehenstufen eingemessen). */
  .block.block--anfragekopf h1 { font-size: min(clamp(1.75rem, 3.6vw, 3.1rem), 6.4vh); }
  .block--anfragekopf .anfrage { margin-top: 1.1rem; }
}
@media (max-width: 900px) { .anfrage { grid-template-columns: 1fr; } }
.anfrage > * { min-width: 0; }

/* Die Formularkarte traegt zwei Sucher-Ecken — dieselbe Zeichnung wie am
   Sucher rechts: zwei Kanten, nie ein Schriftzeichen (Subset-Regel). */
.anfrage__bogen {
  position: relative;
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: clamp(1.25rem, 3.2vw, 2.5rem);
}
.anfrage__bogen::before,
.anfrage__bogen::after {
  content: ""; position: absolute; width: 1.05rem; height: 1.05rem;
  border: 0 solid var(--akzent); pointer-events: none;
}
.anfrage__bogen::before { top: .55rem; left: .55rem; border-top-width: 1.5px; border-left-width: 1.5px; }
.anfrage__bogen::after { bottom: .55rem; right: .55rem; border-bottom-width: 1.5px; border-right-width: 1.5px; }

.anfrage .formular { max-width: none; margin-top: 0; }
/* Im Raster kommt der Abstand aus `gap` — ein zusaetzliches margin-top
   traf sonst nur die LINKE Zelle nicht (:first-of-type war nur das erste
   <p>), und die rechte Spalte begann 1,2 rem tiefer (Screenshot
   30.08.2026). */
.formular--bogen .formular__gitter > .feld { margin-top: 0; }
.anfrage .feld:first-of-type { margin-top: 0; }

/* Felder als gefuellte Kaesten (Vorlage), nicht als Unterstriche: warmes
   Papier auf der weissen Karte. Schlaegt die globale Unterstrich-Regel
   `.feld input` (0-1-1) mit 0-2-1. */
.formular--bogen .feld input,
.formular--bogen .feld select {
  background: var(--papier-warm);
  border: 1px solid var(--linie);
  border-radius: var(--rund);
  padding: .5rem .85rem;
}
.formular--bogen .feld textarea {
  background: var(--papier-warm);
  border: 1px solid var(--linie);
}
.formular--bogen .feld input:focus-visible,
.formular--bogen .feld select:focus-visible,
.formular--bogen .feld textarea:focus-visible {
  outline: none;
  border-color: var(--akzent);
  box-shadow: 0 0 0 1.5px var(--akzent);
}
/* Beschriftungen wie in der Vorlage: Satzschrift statt Versalien. */
.formular--bogen .feld label,
.formular--bogen .feld__name {
  font-size: .95rem; font-weight: 600;
  letter-spacing: 0; text-transform: none;
  color: var(--tinte-weich); line-height: 1.35;
}
.feld__name { display: block; }
.feld__leicht { font-weight: 400; color: var(--grau); font-size: .85rem; }

/* Formular-Abschnitte: kein Kasten im Kasten — nur die EXIF-Zwischenzeile
   mit Haarlinie (dieselbe Zeile wie frueher in Stufe 4). */
.formular--bogen fieldset.bogen__gruppe,
.formular--bogen fieldset.formular__anlass {
  border: 0; background: none;
  padding: 0;
  margin-top: 2.2rem;
}
.formular--bogen fieldset.bogen__gruppe > legend,
.formular--bogen fieldset.formular__anlass > legend {
  display: flex; align-items: center; gap: 1rem;
  width: 100%; padding: 0;
  font-family: var(--text); font-size: .74rem; font-weight: 700;
  letter-spacing: .15em; text-transform: uppercase; color: var(--grau);
  line-height: 1.35;
}
.formular--bogen fieldset.bogen__gruppe > legend::after,
.formular--bogen fieldset.formular__anlass > legend::after {
  content: ""; flex: 1 0 2rem; height: 1px; background: var(--linie);
}
.formular--bogen fieldset.bogen__gruppe > .formular__gitter,
.formular--bogen fieldset.formular__anlass > .formular__gitter { margin-top: .3rem; }
.bogen__notiz { margin-top: .9rem; }

/* Chips: die Auswahlknoepfe der Vorlage. Das <label> ist der Chip, der
   Radio liegt unsichtbar darueber (opacity 0, volle Flaeche) — damit ist
   der ganze Chip die Klickflaeche und die Tastatur landet trotzdem auf
   dem Radio (:focus-visible unten). Gewaehlt: dunkle Fuellung. */
.chips {
  display: flex; flex-wrap: wrap; gap: .6rem;
  margin-top: 1rem;
}
/* `.formular fieldset label` setzt display:flex und Polster — und wer
   display an einer Klasse setzt, muss [hidden] fuer dieselbe Klasse
   wieder erlauben (die Falle vom 26.08.2026, hier beim ersten Screenshot
   WIEDER getreten: der versteckte Hochzeits-Chip stand sichtbar da).
   Gleiche Spezifizitaet wie die Sammelregel (0-1-2 -> 0-2-2/0-2-3). */
.formular fieldset label.chip { display: inline-block; padding: 0; }
.formular fieldset label.chip[hidden] { display: none; }
.formular--bogen .feld[hidden] { display: none; }
/* Fragemodus (01.09.2026) versteckt ganze Fieldsets — die Erlaubnis
   steht im selben Zug hier, bevor eine Sammelregel mit display sie
   je stumm schlagen kann (die [hidden]-Falle vom 30.08.2026). */
.formular--bogen fieldset[hidden] { display: none; }
.chip { position: relative; }
.chip > input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.chip > span {
  display: inline-block;
  font-size: .95rem; font-weight: 600;
  color: var(--tinte);
  background: var(--papier);
  border: 1.5px solid var(--linie);
  border-radius: var(--rund);
  padding: .62rem 1.15rem;
  transition: background-color 0.2s ease, color 0.2s ease,
              border-color 0.2s ease;
}
@media (hover: hover) {
  .chip:hover > span { border-color: var(--tinte-weich); }
}
.chip:has(input:focus-visible) > span {
  outline: 2px solid var(--akzent); outline-offset: 3px;
}
.chip:has(input:checked) > span {
  background: var(--tinte); border-color: var(--tinte); color: var(--papier);
}
/* Ausgegraut, nicht versteckt: „5 Bilder" ausserhalb von Portrait — man
   sieht, dass es das Paket gibt und dass es hier nicht gilt. Bewusst
   OHNE opacity: der Text bleibt --grau auf Weiss (6,7:1) — eine
   halbtransparente Beschriftung fiele im Kontrast durch, und ein
   deaktivierter Knopf muss trotzdem lesbar sein. */
.chip--aus > span {
  color: var(--grau);
  background: none;
  border-style: dashed;
}
.chip--aus > input { cursor: not-allowed; }

/* Die Zeile „Noch frei verfuegbare Termine" mit dem Knopf
   „Terminauswahl" (30.08.2026, zweite Runde). Beides baut seite.js —
   ohne Kalender gibt es nichts zu oeffnen. Der Knopf ist der EINE
   Einstieg in den Monatskalender; der Winkel daran ist gezeichnet, zwei
   Kanten, kein Zeichen aus der Schrift (die Subsets tragen Symbole nicht
   zwingend). */
.terminauswahl {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: .45rem;
  margin-top: .2rem;
}
.terminauswahl .feld__name {
  font-size: .95rem; font-weight: 600; color: var(--tinte-weich);
  line-height: 1.35;
}
.freifeld__knopf {
  font: inherit; font-weight: 600; text-align: left;
  color: var(--papier);
  background: var(--tinte);
  border: 1.5px solid var(--tinte);
  border-radius: var(--rund);
  padding: .62rem 2.6rem .62rem 1.15rem;
  min-height: 2.75rem;
  cursor: pointer; position: relative;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.freifeld__knopf:hover { background: var(--akzent); border-color: var(--akzent); }
.freifeld__knopf::after {
  content: ""; position: absolute; right: 1.1rem; top: 50%;
  width: .46em; height: .46em;
  border-right: 1.8px solid currentColor;
  border-bottom: 1.8px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.2s ease;
}
.freifeld__knopf--offen::after { transform: translateY(-30%) rotate(-135deg); }

/* Rechte Spalte: Kontaktkarte mit gezeichneten Piktogrammen, darunter
   das Foto (kantig — Fotos bleiben kantig, Frederiks Wahl 28.08.2026). */
.seitenkarte {
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: clamp(1.3rem, 2.6vw, 1.8rem);
}
.seitenkarte__titel {
  font-family: var(--serif); font-weight: 500;
  font-size: 1.7rem; letter-spacing: 0;
}
.seitenkarte__liste { margin: 1.2rem 0 0; display: grid; gap: 1.1rem; }
.seitenkarte__zeile { display: flex; gap: .9rem; align-items: flex-start; }
.seitenkarte__zeile > div { min-width: 0; }
.seitenkarte__pikto {
  flex: none; width: 2.4rem; height: 2.4rem;
  display: grid; place-items: center;
  background: var(--papier-warm);
  border-radius: var(--rund-klein);
  color: var(--tinte-weich);
}
.seitenkarte__pikto .np { width: 1.25rem; height: 1.25rem; }
.seitenkarte__zeile dt { font-weight: 700; font-size: .98rem; }
.seitenkarte__zeile dd {
  margin: .1rem 0 0; color: var(--grau); font-size: .95rem;
  overflow-wrap: anywhere;
}
/* Links in der Karte brauchen ihre Klickflaeche SELBST — neue Elemente
   erben die WCAG-Reparatur der Nachbarn nicht (abnahme-Befund
   30.08.2026: 19 px hoch, verlangt sind 24). */
.seitenkarte__zeile dd a { display: inline-block; padding: .25rem 0; }
.anfrage__seite > .notiz { margin-top: .95rem; }


/* ---- Der Bogen rueckt an den Kopf (Auftrag Frederik, 26.08.2026) -------
   Auf der Terminseite entscheidet EINE Sache, ob jemand anfaengt: ob die
   zwei Auswahlkarten der ersten Stufe ohne Scrollen vollstaendig
   dastehen. Gemessen vor dem Umbau (Fenster 861 px hoch): Die Karten
   endeten bei 880 px — 19 px unter der Falz, also gerade so abgeschnitten.
   Das ist der unguenstigste aller Zustaende: Es sieht vollstaendig aus und
   ist es nicht, und niemand scrollt nach etwas, von dem er nicht weiss,
   dass es da ist.

   Der Platz kommt aus SECHS kleinen Posten statt aus einem grossen —
   ein einzelner haette entweder die Ueberschrift entwertet oder den
   Bogen gequetscht:

     Blockpolster oben   112 -> 40 px   (der Abstand zum Kopf, ausdruecklich)
     Formular-Abstand     42 -> 22 px
     Bogenpolster oben    48 -> 28 px
     Wegweiser unten      37 -> 26 px
     Karten-Abstand       27 -> 18 px
     Unterzeile enger      9 ->  4 px

   Zusammen rund 135 px. Der Blockfuss bleibt unangetastet — nach unten
   soll die Seite atmen, nur oben nicht.

   `.block--knapp` ist ein SCHALTER je Seite, keine globale Aenderung: Das
   Polster der uebrigen Seiten ist der Rhythmus der ganzen Webseite, wer es
   global anfasst, aendert 19 Seiten wegen einer. Gesetzt auf `termin.html`
   und (27.08.2026, gleiche Meldung von Frederik) auf `ueber-mich.html` —
   dort wurden die beiden Knoepfe „Termin anfragen / Meine Bilder ansehen"
   um 15 px angeschnitten. (Die Terminseite selbst ist am 30.08.2026 im
   Kontaktbogen aufgegangen; der Schalter bleibt fuer ueber-mich.html.)
   Generisch sind nur das Polster oben und die Hoehenkopplung der
   Schauzeile.

   **Merksatz: Ein Seitenschalter darf nur das Generische selbst tun; alles
   Seitenspezifische haengt er an einen Nachfahren.** Sonst ist der zweite
   Einsatz ein Umbau statt einer Zeile. */

.block--knapp { padding-top: clamp(1.6rem, 3.2vw, 2.5rem); }
.block--knapp .block__satz { margin-top: .85rem; }
/* ueber-mich: die Knopfzeile ist hier das, was die Karten auf der
   Terminseite sind — die Handlung. Sie hing an 2 rem Abstand. */
.block--knapp .held__knoepfe { margin-top: 1.5rem; }
.block--knapp .ueber__satz p { margin-top: .9rem; }

/* Ab hier zaehlt die Fensterhoehe, nicht die Breite: Bei niedrigen
   Fenstern (Laptop im Querformat, ~700-800 px) reicht auch das gekuerzte
   Polster nicht, und die zweizeilige Schauzeile ist dann der groesste
   Posten. Sie wird deshalb zusaetzlich an `vh` gekoppelt — dasselbe
   Muster wie im Kopfbereich der Startseite (Entscheidung 25.08.2026,
   „vw-Typo plus Hochformat ist eine Hoehenfalle"). Ueber 900 px Hoehe
   greift die Grenze nicht und die Zeile steht in voller Groesse. */
@media (max-height: 900px) {
  .block--knapp h1 { font-size: min(clamp(2rem, 5.2vw, 4.6rem), 8.2vh); }
  .block--knapp { padding-top: clamp(1.2rem, 2.4vw, 1.8rem); }
}
/* Zweite Stufe fuer wirklich flache Fenster (Laptop mit Lesezeichenleiste,
   ~700 px). Gemessen: Mit der ersten Stufe allein blieben bei 700 px nur
   5 px Luft unter den Karten — das ist kein Puffer, das ist Glueck. Wer
   dort noch eine Leiste einblendet, sieht wieder eine abgeschnittene
   Karte. */
@media (max-height: 780px) {
  .block--knapp h1 { font-size: min(clamp(1.9rem, 5.2vw, 4.6rem), 7.4vh); }
  .block--knapp .block__satz { margin-top: .6rem; }
  .block--knapp .ueber__satz p { margin-top: .75rem; }
  .block--knapp .held__knoepfe { margin-top: 1.15rem; }
}
/* Dritte Stufe: 1366 x 768 ist immer noch eine verbreitete Laptop-Aufloesung
   und ergibt mit der Browser-Leiste rund 640 px Sichtflaeche. Ohne diese
   Stufe wurden die Karten dort um 16 px angeschnitten — also genau der
   Fehler, um den es hier geht, nur eine Fensterhoehe tiefer.
   Merksatz: Wer eine Falz-Regel setzt, prueft sie an der KLEINSTEN
   Hoehe, die wirklich vorkommt, nicht an der eigenen. */
@media (max-height: 680px) {
  .block--knapp h1 { font-size: min(clamp(1.75rem, 5.2vw, 4.6rem), 6.5vh); }
  .block--knapp { padding-top: .55rem; }
  .block--knapp .ueber__satz p { margin-top: .62rem; }
  .block--knapp .held__knoepfe { margin-top: .95rem; }
  .block--knapp .block__satz { margin-top: .45rem; }
}

/* ---- Monatskalender (Stufe 3) ------------------------------------------
   Weisse Karte auf dem warmen Bogen. Gefuellt von seite.js aus
   assets/frei.json — Ort, Schluessel und Form sind die Kopplung zu
   kalender_cron.php, pruefe.py haelt beide Seiten gegeneinander. */

.kal {
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: clamp(.9rem, 3vw, 1.5rem);
  margin-top: 1.7rem;
  max-width: 34rem;
}
.kal__kopf {
  display: flex; align-items: center; gap: .6rem;
  padding-bottom: .85rem; border-bottom: 1px solid var(--linie);
}
.kal__monat {
  flex: 1; text-align: center;
  font-family: var(--display); font-size: 1.3rem; font-weight: 700;
}
.kal__pfeil {
  font: inherit; font-size: 1.4rem; line-height: 1;
  background: none; border: 1px solid var(--linie); border-radius: var(--rund);
  color: var(--tinte);
  width: 2.5rem; height: 2.5rem;      /* 40 px — WCAG 2.2 verlangt 24 */
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.kal__pfeil:hover { border-color: var(--akzent); color: var(--akzent); }
.kal__pfeil[disabled] { color: var(--linie); cursor: default; }
.kal__pfeil[disabled]:hover { border-color: var(--linie); color: var(--linie); }

.kal__wochentage, .kal__gitter {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: .25rem;
}
.kal__wochentage {
  margin-top: 1rem; margin-bottom: .35rem;
  font-size: .68rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--grau); text-align: center;
}
.kal__tag {
  font: inherit; font-size: .95rem; font-variant-numeric: tabular-nums;
  aspect-ratio: 1; display: grid; place-items: center;
  border: 1px solid transparent; border-radius: var(--rund-klein);
  background: none;
  color: var(--linie); padding: 0;
  position: relative;               /* Bezugsrahmen fuer den Punkt */
}
.kal__tag--frei {
  color: var(--tinte); border-color: var(--linie); cursor: pointer;
  background: var(--papier-warm);
  transition: border-color 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}
.kal__tag--frei:hover { border-color: var(--tinte); background: var(--papier); }
.kal__tag--frei[aria-pressed="true"] {
  background: var(--tinte); border-color: var(--tinte); color: var(--papier);
}
/* Der Punkt sagt „hier ist etwas frei" ohne Farbe — Form vor Farbe,
   wie Haken gegen Strich in der Preistafel. */
.kal__tag--frei::after {
  content: ""; position: absolute; left: 50%; bottom: .3rem;
  transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: var(--akzent);
}
.kal__tag--frei[aria-pressed="true"]::after { background: var(--papier); }
.kal__tag--heute { font-weight: 700; }

.kal__zeiten { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1rem; }
.kal__zeiten .slot { background: var(--papier-warm); border-color: var(--linie); }
.kal__zeiten .slot:hover { border-color: var(--tinte); color: var(--tinte); background: var(--papier); }
.kal__zeiten .slot[aria-pressed="true"] { background: var(--tinte); border-color: var(--tinte); color: #fff; }
/* Beide Wunschtermine belegt: die uebrigen Fenster sind nicht waehlbar.
   Gestrichelt und grau wie die ausgegrauten Umfang-Chips — bewusst OHNE
   opacity, damit die Beschriftung lesbar bleibt (--grau auf Weiss ist
   6,7:1). Der Hinweis darunter sagt, was zu tun ist. */
.kal__zeiten .slot[disabled] {
  color: var(--grau); background: none;
  border-style: dashed; cursor: not-allowed;
}
.kal__zeiten .slot[disabled]:hover { border-color: var(--linie); color: var(--grau); }
.kal__leer { color: var(--grau); font-size: .92rem; margin-top: 1rem; }

/* Die zwei Wunschtermin-Felder stehen IMMER offen (30.08.2026): Sie
   nehmen eigene Eingaben UND zeigen an, was im Kalender angetippt wurde.
   Ein Aufklapper darueber waere eine Klappe vor der Antwort — und die
   frueher noetige Liste „Deine Auswahl" ist damit entfallen, denn der
   Zustand steht im Formular selbst. */
.terminfrei { margin-top: 1.3rem; }

/* ---- Eine Kante fuer alles ---------------------------------------------
   Lehre vom 26.08.2026 („die Linien sind nicht buendig miteinander"),
   fuer den Bogen unveraendert gueltig: Formular-ABSCHNITTE tragen keinen
   Kasten im Kasten — ihre Felder muessen mit den Feldern darueber
   fluchten. Die Abschnitts-Optik (EXIF-Zeile mit Haarlinie) steht oben
   im Kontaktbogen-Block (`.bogen__gruppe`, `.formular__anlass`).

   Und: `p, li { max-width: 62ch }` trifft auch den Absatz um den
   Absendeknopf — der ist kein Fliesstext. */

.formular--bogen p:has(> .knopf--gross) { max-width: none; }


/* ---- 3. Zwei Unterstriche nebeneinander, auf einer Hoehe --------------
   Der eigentliche Befund hinter „die Linien sind nicht buendig": In einer
   Rasterzeile standen die Unterstriche zweier Felder bis zu 49,7 px
   auseinander. Zwei Ursachen, die sich addierten:

   a) `<select>` ist im Chrome 5 px flacher als `<input>` — die UA-Regel
      setzt `line-height: normal`, und `font: inherit` traegt die
      Zeilenhoehe dort NICHT mit (gemessen: input 43,9 px / select
      38,9 px bei identischem Polster und identischer Schriftgroesse).
      Behoben ueber eine gemeinsame Mindesthoehe statt ueber
      `line-height` — die wirkt bei Selects je nach Browser anders, eine
      Hoehe wirkt ueberall gleich.

   b) Eine zweizeilige Beschriftung („Budgetrahmen (hilft beim
      Paketvorschlag)") oder ein Hilfstext („Ab dem zweiten Tier …")
      schob das Feld darunter nach unten, waehrend der Nachbar oben
      blieb. Behoben mit `margin-top: auto` am Bedienelement: Die
      Beschriftung bleibt oben am Zeilenanfang, das Feld sinkt an den
      Fuss der Rasterzeile — und damit stehen ALLE Unterstriche einer
      Zeile auf einer Linie, unabhaengig davon, wie lang die
      Beschriftung darueber ist.

   Merksatz: **In einem Raster fluchten nicht die Felder, sondern die
   Zeilen.** Wer Beschriftung und Feld als einen Block behandelt, bekommt
   so viele Grundlinien wie es Beschriftungslaengen gibt. */

.feld input, .feld select { min-height: 2.75rem; }

/* Der Hilfstext steht VISUELL unter dem Feld, im Markup aber weiter oben
   — `order` verschiebt nur die Darstellung. Fuer die Sprachausgabe bleibt
   die Reihenfolge Beschriftung → Hinweis → Feld, also die richtige: Man
   hoert den Hinweis, BEVOR man tippt. Nichts davon ist fokussierbar, die
   Tabreihenfolge aendert sich also nicht. */
.feld { position: relative; }
.feld__hilfe { order: 3; margin-top: .1rem; }

/* Oberhalb von 700 px steht das Raster zweispaltig — dort bekommen alle
   Beschriftungen dasselbe Band (zwei Zeilen Hoehe), damit die Felder
   darunter auf EINER Grundlinie beginnen und enden, egal wie lang die
   Beschriftung ist. Darunter ist das Raster einspaltig: dort gibt es
   nichts, womit etwas fluchten muesste, und reservierte Leerzeilen waeren
   nur verschenkter Platz am Telefon. */
/* Die Regel `.formular fieldset label { display:flex; padding:.3rem 0 }`
   ist fuer RADIOZEILEN gedacht (Kaestchen und Text nebeneinander). Seit
   die Stufen `<fieldset>` sind, liegt JEDE Feldbeschriftung darin — und
   hat 9,6 px Polster geerbt, das niemand bestellt hat. Sichtbar wurde es
   erst beim Rechnen: Das Beschriftungsband unten misst in Zeilen, das
   Polster zaehlte lautlos mit, und die Unterstriche standen bei
   701-820 px wieder 9,6 px auseinander.

   `.feld > label` allein (0-1-1) reicht als Ausnahme NICHT — die Regel
   ist Klasse+Typ+Typ (0-1-2). Zum sechsten Mal dieselbe Falle in diesem
   Ordner; sie sitzt im Muster „Sammelregel `.eltern typ` plus
   Sonderfall", nicht im Einzelfall. Gegenprobe:
   getComputedStyle(label).paddingTop muss 0px sein. */
.formular fieldset .feld > label { display: block; padding: 0; }

@media (min-width: 701px) {
  /* Genau zwei Zeilen: 2 x line-height 1.35. Der erste Anlauf stand auf
     2,6em und war damit fuer ZWEI Zeilen zu knapp — bei 768 px, wo
     „Welcher Hintergrund schwebt dir vor?" umbricht, standen die beiden
     Unterstriche der Zeile wieder 18 px auseinander. Gemessen, nicht
     geschaetzt: Wer ein Band in `em` reserviert, muss die Zeilenhoehe
     kennen, die darin gilt. */
  .formular__gitter > .feld > label { min-height: 2.7em; }
}



/* Der Absendeknopf schliesst den Bogen ueber die volle Breite ab —
   der letzte Schritt endet mit einer klaren Kante, nicht mit einem
   Knopf, der links im Raster haengt. Nur hier: auf anderen Seiten
   bleibt .knopf--gross ein normaler Knopf. */
.formular--bogen .knopf--gross {
  display: block; width: 100%;
  margin-top: 2.2rem;
  padding-block: 1.15rem;
  text-align: center;
  letter-spacing: .04em;
}


/* ---- Ablauf-Bildstreifen, FAQ-Randbild, Über-mich, Danke ---------------- */

.streifen {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.8rem; align-items: start;
  max-width: var(--breite); margin-inline: auto; margin-top: 3.2rem;
}
.streifen__bild:last-child { margin-top: clamp(1rem, 4vw, 3rem); }
.streifen__bild picture { background: var(--papier-warm); }
@media (max-width: 700px) {
  .streifen { grid-template-columns: 1fr; }
  .streifen__bild:last-child { margin-top: 0; }
}


.ueber {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  max-width: var(--breite); margin-inline: auto;
  align-items: start;
}
.ueber > * { margin-inline: 0; }
.ueber__satz p { margin-top: 1.1rem; color: var(--tinte-weich); }
.ueber__satz h1 { margin-bottom: 0.4rem; }
.ueber__satz .held__knoepfe { margin-top: 2rem; }
.ueber__bild .galerie__zeichnung { aspect-ratio: 4 / 5; }
/* 30.08.2026: Der reservierte Zeichnungsplatz traegt jetzt ein Foto.
   Die 4:5-Proportion bleibt — sie ist der eingemessene Platz DIESER
   Spalte; das Original ist 2:3 und damit hoeher, ungeschnitten wuerde
   die sticky-Spalte laenger als der Text daneben. Der Ausschnitt sitzt
   leicht unter der Mitte, dort liegt die Kamera. */
.ueber__figur picture { display: block; background: var(--papier-warm); }
.ueber__figur img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 58%;
}
/* Die Textspalte ist länger als der reservierte Bildplatz — sticky
   hält ihn auf Augenhöhe, statt eine halbe Spalte leer zu lassen. */
@media (min-width: 861px) {
  .ueber__bild { position: sticky; top: 6rem; align-self: start; }
}
@media (max-width: 860px) {
  .ueber { grid-template-columns: 1fr; }
  .ueber__bild { max-width: 26rem; }
}

/* Breites Bildband: begrenzte Höhe, damit ein Hochformat den Abschnitt
   nicht sprengt — der Ausschnitt sitzt oben (Himmel/Motiv). */
.band { max-width: var(--breite); margin-inline: auto; }
.band picture { display: block; background: var(--papier-warm); }
.band img {
  width: 100%;
  aspect-ratio: 16 / 7;
  object-fit: cover;
  /* Ausschnitt liegt tief: bei diesem Hochformat steht das Motiv
     (Stadt, Brücke, Laterne) in der unteren Bildhälfte — bei 32 %
     war fast nur Himmel zu sehen (im Browser gemessen). */
  object-position: center 66%;
}
.band__zeile {
  display: flex; flex-wrap: wrap; gap: 0.6rem 2rem;
  justify-content: space-between; align-items: baseline;
  margin-top: 0.7rem;
}
.band__zeile span:last-child { color: var(--grau); font-size: 0.95rem; max-width: 44ch; }
@media (max-width: 700px) { .band img { aspect-ratio: 4 / 3; } }

.band--hoch { margin-top: 2.8rem; }
/* Portraitmotiv im Band: Ausschnitt höher setzen, sonst schneidet der
   Streifen den Kopf ab (im Browser gemessen). */
.band--hoch img { object-position: center 34%; }

/* ---- Kontakt ------------------------------------------------------------ */

.karte-rahmen {
  max-width: var(--breite); margin-inline: auto; margin-top: 2.4rem;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3rem); align-items: center;
  border: 1px solid var(--linie); background: var(--papier);
  border-radius: var(--rund-gross);
  padding: clamp(1.4rem, 3.5vw, 2.6rem);
}
.karte-rahmen iframe { width: 100%; height: 24rem; border: 0; grid-column: 1 / -1; }
@media (max-width: 860px) { .karte-rahmen { grid-template-columns: 1fr; } }

/* ---- Recht -------------------------------------------------------------- */

/* Die Rechtsseiten tragen die längsten Wörter der ganzen Seite —
   „Datenschutzerklärung", „Geschäftsbedingungen", „Widerrufsbelehrung".
   Bei der normalen H1-Größe (Untergrenze 2,5 rem = 40 px) passt keines
   davon in 340 px, und dann bricht `overflow-wrap: break-word` MITTEN im
   Wort um: „Widerrufsbelehr / ung". Das sieht aus wie ein Fehler.

   `hyphens: auto` steht seit dem 25.08. am Text und wäre die elegante
   Lösung — es hängt aber daran, dass der Browser deutsche Trennmuster
   mitbringt. Gemessen am 26.08.2026: das Chromium der Abnahme hat sie
   NICHT (Testwort in 90 px Breite bleibt einzeilig und läuft über), macOS-
   Chrome vermutlich schon. Eine Gestaltung, die von einem Wörterbuch
   abhängt, ist keine — deshalb hier die Ursache beseitigt statt das
   Symptom: eine eigene, kleinere Größe für die Rechtsseiten.
   Eine Rechtsseite braucht ohnehin keine 40-px-Schauzeile.

   NACHGEMESSEN am 27.08.2026 nach dem Schriftwechsel: Plus Jakarta Sans
   läuft breiter als Bodoni Moda. Mit den alten 1,9 rem (30,4 px) brach
   „Geschäftsbedingungen" bei 375 px MITTEN IM WORT auf drei Zeilen —
   dieselbe hässliche Stelle wie vor der Reparatur vom 26.08., nur aus
   einem neuen Grund. Gemessen: ab 28 px passt das Wort, darüber nicht.
   1,65 rem = 26,4 px lässt Luft. **Wer die Schrift wieder tauscht, misst
   diese eine Zeile neu** — sie ist das längste Wort der ganzen Seite. */
.recht h1 {
  margin-bottom: 1.6rem;
  font-size: clamp(1.65rem, 6vw, 3.1rem);
}
.recht h2 { font-size: 1.35rem; margin-top: 2.2rem; margin-bottom: 0.6rem; }
.recht p { color: var(--tinte-weich); }

/* ---- Fußzeile ----------------------------------------------------------- */
/* Seit 02.09.2026 WEISS statt --dunkel (Frederiks Ansage: „auf jeder Seite
   schwarz … nicht so schön"). Die dunkle Strecke der Startseite ist am
   selben Tag entfallen; die Fußzeile war die letzte dunkle Fläche. Weil das
   CTA-Band darüber ebenfalls weiß ist, trennt eine Haarlinie (Bandwechsel
   durchzählen — moosa-web, 19.08.2026). Zugleich gekürzt: Wortmarke von
   bis zu 102 px auf H2-Größe, Polster enger — gemessen bei 1440 px
   ~590 → ~440 px Höhe (−25 %). */
.fuss {
  background: var(--papier); color: var(--grau);
  border-top: 1px solid var(--linie);
  padding: clamp(2rem, 4vw, 2.8rem) var(--rand) 1.3rem;
  margin-top: 0;
}
.fuss a { color: var(--tinte); text-decoration-color: color-mix(in srgb, var(--tinte) 28%, transparent); }
.fuss a:hover { text-decoration-color: var(--akzent); }
/* Das Fußzeilenwort trägt weiter den 800er-Schnitt (einzige Stelle), steht
   aber seit 02.09.2026 in H2-Größe statt als größte Zeile der Seite. */
.fuss__wort {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  line-height: 1; letter-spacing: -0.025em;
  color: var(--tinte);
  max-width: var(--breite); margin-inline: auto;
  border-bottom: 1px solid var(--linie);
  padding-bottom: 1.1rem;
}
.fuss__spalten {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.6rem 2rem;
  max-width: var(--breite); margin-inline: auto;
  padding: 1.5rem 0 1.6rem;
}
.fuss__titel {
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--tinte);
  margin-bottom: 0.55rem;
}
.fuss__liste { list-style: none; }
.fuss__liste a { text-decoration: none; }
.fuss__liste a:hover { color: var(--akzent); }
/* 24 px Klickfläche auch in der Fußzeile (gemessen: vorher 20 px). Das
   Polster ist zugleich der Zeilenabstand — 0,26 rem ergibt bei 1,65
   Zeilenhöhe ~34 px je Zeile (vorher ~36), Klickfläche bleibt über 24. */
.fuss__liste a { display: inline-block; padding: 0.26rem 0; }
.fuss__liste li { padding: 0; }
.fuss__orte { font-size: 0.92rem; line-height: 1.8; }
.fuss__unten {
  max-width: var(--breite); margin-inline: auto;
  display: flex; flex-wrap: wrap; gap: 0.8rem 1rem; justify-content: space-between;
  border-top: 1px solid var(--linie);
  padding-top: 1.1rem;
  font-size: 0.85rem;
}
/* Vier Einträge statt zwei (AGB und Widerruf kamen am 26.08.2026 dazu) —
   ohne Umbruch lief die Zeile bei 375 px auf 439 px hinaus und die Seite
   ließ sich seitlich schieben. Gemessen von abnahme.py, nicht gesehen:
   im vollen Screenshot sieht ein Überlauf am rechten Rand nach nichts aus. */
.fuss__recht {
  list-style: none;
  display: flex; flex-wrap: wrap;
  gap: 0.4rem 1.6rem;
  min-width: 0;
}
@media (max-width: 420px) { .fuss__recht { gap: 0.4rem 1.1rem; } }
.fuss__recht a { display: inline-block; padding: 0.3rem 0; }
@media (max-width: 860px) { .fuss__spalten { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .fuss__spalten { grid-template-columns: 1fr; } }

/* ==========================================================================
   Nachtrag 26.08.2026 — SEO-Nachbesserung und Einwilligung
   ========================================================================== */

/* ---- Thema in der H1 ----------------------------------------------------
   Die Angebotsseiten hatten eine reine Bildzeile als H1 („Ein Portrait, das
   dich nicht verkleidet.") — die stärkste Überschrift der Seite ohne
   Leistung und ohne Ort. Die Vorzeile sitzt jetzt IN der H1 und trägt
   beides; sie ist bewusst klein, damit die Bildzeile die Bildzeile bleibt. */

.h1__thema {
  display: block;
  font-family: var(--text);
  font-size: clamp(0.8rem, 1.4vw, 0.95rem);
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--grau);
  line-height: 1.35;
  margin-bottom: 0.85rem;
}

/* ---- Etappen (Hochzeitsseite) -------------------------------------------
   Solange dort kein einziges Foto liegt, trägt der Text die Seite. Zwei
   Spalten ab 46 rem Container — darunter reißen die Absätze zu schmal um. */

.etappen {
  display: grid;
  gap: 2rem 2.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  max-width: var(--breite);
  margin: 2.6rem auto 0;
}
.etappe { border-top: 2px solid var(--tinte); padding-top: 1rem; }
.etappe h3 { margin-bottom: 0.7rem; }
.etappe p { color: var(--tinte-weich); font-size: 0.97rem; }
.etappe p + p { margin-top: 0.7rem; }

/* ---- Querverweise zwischen den Angebotsseiten ---------------------------
   Vorher verband die fünf Seiten nur die Navigation. Der Ankertext trägt
   Leistung und Ort, nicht „mehr erfahren". */

.block--weiter .weiterlinks { list-style: none; }
.weiterlinks {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  max-width: var(--breite);
  margin: 2rem auto 0;
  list-style: none;
}
.weiterlinks a {
  display: block;
  text-decoration: none;
  color: inherit;
  border-top: 2px solid var(--tinte);
  padding: 0.9rem 0.2rem 1rem;
  transition: border-color 0.25s ease;
}
.weiterlinks a:hover { border-top-color: var(--akzent); }
.weiterlinks strong {
  display: block;
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 700;
}
.weiterlinks span {
  display: block;
  color: var(--grau);
  font-size: 0.88rem;
  margin-top: 0.3rem;
}

/* ---- Textknopf: sieht aus wie ein Verweis, ist aber ein Knopf ----------- */

.textknopf, .fuss__knopf {
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
/* Klickflächen: gemessen 22 px hoch (abnahme.py, 26.08.2026) — WCAG 2.2
   „Target Size (Minimum)" verlangt 24. Dieselben 0,3 rem Polster wie an
   den Nachbarlinks der Fußzeile, damit die Zeile nicht springt. */
.fuss__knopf { display: inline-block; padding: 0.3rem 0; }
.karte__fuss .textknopf { display: inline-block; padding: 0.3rem 0; }
.textknopf:hover, .fuss__knopf:hover { color: var(--akzent); }
.karte__fuss { margin-top: 0.9rem; }

/* ---- Einwilligungsbanner ------------------------------------------------
   Sitzt unten und deckt die Seite NICHT zu: Wer nichts anklickt, kann alles
   lesen — er wird nur nicht gezählt und sieht keine Karte. Die beiden
   Knöpfe sind gleich groß; „Nur das Nötigste" ist nicht kleiner oder
   blasser als „Beides erlauben". */

.einw {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;
  padding: clamp(0.8rem, 2vw, 1.4rem);
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.einw[hidden] { display: none; }
.einw__kasten {
  pointer-events: auto;
  width: min(46rem, 100%);
  background: var(--papier);
  border: 1px solid var(--tinte);
  border-top: 3px solid var(--akzent);
  border-radius: var(--rund-gross);
  box-shadow: 0 18px 44px rgba(20, 20, 18, 0.18);
  padding: clamp(1.1rem, 2.6vw, 1.7rem);
  max-height: 80vh;
  overflow-y: auto;
}
.einw__titel {
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 0.5rem;
}
.einw__text { color: var(--tinte-weich); font-size: 0.94rem; }
.einw__wahl { margin-top: 0.9rem; }
.einw__wahl summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  /* Lag mit gemessenen 24,0 px genau auf der WCAG-Grenze — Polster dazu.
     `width: fit-content`, damit die Klickfläche nicht als 680 px breiter
     Streifen quer durch den Kasten läuft. */
  padding: 0.35rem 0;
  width: fit-content;
}
.einw__liste { list-style: none; margin: 0.9rem 0; display: grid; gap: 0.8rem; }
.einw__liste li { display: grid; grid-template-columns: auto 1fr; gap: 0.7rem; }
.einw__liste input { margin-top: 0.28rem; width: 1.05rem; height: 1.05rem; accent-color: var(--akzent); }
.einw__liste label { cursor: pointer; }
.einw__liste strong { display: block; font-size: 0.95rem; }
.einw__liste span { display: block; color: var(--grau); font-size: 0.86rem; margin-top: 0.15rem; }
.einw__knoepfe { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 1.1rem; }
.einw__knoepfe .knopf { flex: 1 1 12rem; text-align: center; }
.knopf--klein { padding: 0.55rem 1.2rem; font-size: 0.85rem; }
.einw__fein { margin-top: 0.9rem; font-size: 0.82rem; color: var(--grau); }
.einw__fein a { color: inherit; }

@media (max-width: 520px) {
  .einw { padding: 0; }
  .einw__kasten { border-left: 0; border-right: 0; border-bottom: 0; }
}

/* ---- Zusatzfelder je Anlass (26.08.2026) --------------------------------
   Der Kasten steht im selben Gitter wie das Hauptformular, ist aber ein
   <fieldset> — und genau da sitzt die Spezifitätsfalle dieses Ordners:
   `.formular fieldset label` (0-1-2) schlägt `.feld label` (0-1-1). Die
   Beschriftungen wären dadurch Flex-Zeilen mit Polster und Zeigerhand
   geworden statt der gesperrten Kapitälchen der übrigen Felder — ohne
   Fehlermeldung, im Markup sieht alles richtig aus. Die Ausnahme unten
   ist mit zwei Klassen spezifischer als die Regel, die sie aufhebt.
   Gegenprobe: getComputedStyle(label).textTransform muss "uppercase" sein
   und display "block". */

.formular__anlass .feld label {
  display: block;
  padding: 0;
  cursor: default;
  font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--grau);
}
.formular__anlass .formular__gitter { margin-top: -0.4rem; }
.formular__anlass .feld { margin-top: 1rem; }
.feld__hilfe {
  font-size: 0.86rem;
  color: var(--tinte-weich);
  line-height: 1.45;
}
.feld--anlass[hidden] { display: none; }

/* ---- Muster-Widerrufsformular -------------------------------------------
   Eine Liste, keine Eingabemaske: Das Formular wird abgeschrieben oder
   kopiert, nicht auf der Seite ausgefüllt — abgeschickt wird es per Post
   oder E-Mail. Ein echtes <form> hier hätte einen Absendeweg suggeriert,
   den es nicht gibt. */

.widerrufsformular {
  list-style: none;
  counter-reset: widerruf;
  max-width: 44rem;
  margin-top: 1.2rem;
  border-left: 2px solid var(--linie);
  padding-left: 1.2rem;
}
.widerrufsformular li {
  color: var(--tinte-weich);
  padding: 0.5rem 0;
}
.widerrufsformular li + li { border-top: 1px solid var(--linie); }
.recht .widerrufsformular li:last-child { color: var(--grau); font-size: 0.9rem; }


/* ---- Hochzeitsseite: das Bewerbungs-Konzept (27.08.2026) ----------------
   Frederiks Ansage: Es gibt noch keine fotografierte Hochzeit, also keine
   Paket-Werbung — stattdessen offen: Bewerberpreis 299 €, Referenz-
   Vereinbarung, Zweitkamera als Argument. Die kolorierten Federzeichnungen
   (_ZB in baue.py) benutzen dieselbe Tuschelinie wie .zg, dazu vier flache
   Festfarben. Die Farben sind GESTALTUNG (aria-hidden), kein
   Informationstraeger — sie muessen darum keinen Textkontrast halten.
   Fuellung und Linie sind GETRENNTE Formen (erst .zgf, dann .zg darueber),
   weil .zg fill:none setzt und eine Kombiklasse gegen die Kaskade verloere. */

:root {
  --fest-gold: #c19a3f;
  --fest-laub: #6f8a63;
  --fest-himmel: #5f7d99;
  --fest-rose: #d8a29a;
}

.zgf { stroke: none; }
.zgf--gold { fill: var(--fest-gold); }
.zgf--laub { fill: var(--fest-laub); }
.zgf--himmel { fill: var(--fest-himmel); }
.zgf--rose { fill: var(--fest-rose); }
.zgf--rot { fill: var(--akzent); }
.zgf--papier { fill: var(--papier); }
.zgf--warm { fill: var(--papier-warm); }

.zgs { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.zgs--gold { stroke: var(--fest-gold); stroke-width: 5; }
.zgs--laub { stroke: var(--fest-laub); stroke-width: 2.5; }
.zgs--himmel { stroke: var(--fest-himmel); stroke-width: 2.5; }
.zgs--rose { stroke: var(--fest-rose); stroke-width: 2.5; }

.hb-girlande { display: flex; justify-content: center; margin: 1.4rem auto 0; }
.hb-girlande svg { width: min(29rem, 86%); height: auto; }

.hb-karten {
  display: grid;
  gap: 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  max-width: var(--breite);
  margin: 1.8rem auto 0;
}
.hb-karte {
  background: var(--papier-warm);
  border: 1px solid var(--linie);
  border-radius: var(--rund-gross);
  padding: 1.7rem 1.5rem 1.6rem;
}
.hb-karte__bild { display: block; width: 5.4rem; margin-bottom: 1.1rem; color: var(--tinte); }
.hb-karte__bild svg { width: 100%; height: auto; display: block; }
.hb-karte h3 { font-size: 1.25rem; margin-bottom: 0.55rem; }
.hb-karte p { color: var(--tinte-weich); font-size: 0.97rem; }

/* Das Zweitkamera-Band: bewusst KEIN eigenes Angebot (Frederiks Wahl
   27.08.2026), nur ein Argument — darum ein Randstreifen, keine Karte
   in der Reihe. */
.hb-zweitkamera {
  display: flex;
  gap: 1.9rem;
  align-items: center;
  max-width: var(--breite);
  margin: 1.6rem auto 0;
  background: var(--papier-warm);
  border: 1px solid var(--linie);
  border-left: 3px solid var(--akzent);
  border-radius: var(--rund-gross);
  padding: 1.5rem 1.7rem;
}
.hb-zweitkamera__bild { flex: none; width: 6.6rem; color: var(--tinte); }
.hb-zweitkamera__bild svg { width: 100%; height: auto; display: block; }
.hb-zweitkamera h3 { font-size: 1.25rem; margin-bottom: 0.45rem; }
.hb-zweitkamera p { color: var(--tinte-weich); font-size: 0.97rem; }
@media (max-width: 640px) {
  .hb-zweitkamera { flex-direction: column; align-items: flex-start; gap: 1.1rem; }
  .hb-zweitkamera__bild { width: 5.4rem; }
}

/* Vier Schritte: Muster der .etappe (Deckstrich), dazu Zeichnung und eine
   grosse kursive Ziffer als Wasserzeichen (Fraunces 500 kursiv — der
   einzige kursive Schnitt, siehe Schriftblock oben). */
.hb-schritte {
  list-style: none;
  display: grid;
  gap: 1.8rem 2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(14.5rem, 100%), 1fr));
  max-width: var(--breite);
  margin: 1.8rem auto 0;
}
.hb-schritt {
  position: relative;
  border-top: 2px solid var(--tinte);
  padding-top: 1rem;
}
.hb-schritt__nr {
  position: absolute;
  top: 0.55rem;
  right: 0.1rem;
  font-family: var(--zier);
  font-style: italic;
  font-weight: 500;
  font-size: 2.7rem;
  line-height: 1;
  color: color-mix(in srgb, var(--tinte) 15%, transparent);
}
.hb-schritt__bild { display: block; width: 5.1rem; margin: 0.2rem 0 0.9rem; color: var(--tinte); }
.hb-schritt__bild svg { width: 100%; height: auto; display: block; }
.hb-schritt h3 { font-size: 1.2rem; margin-bottom: 0.5rem; }
.hb-schritt p { color: var(--tinte-weich); font-size: 0.95rem; }

/* Eine Ein-Karten-Gruppe (Hochzeit: der Bewerberpreis) bleibt in jeder
   Containerbreite EINE zentrierte Spalte — im Dreispalter stuende die
   einzelne Karte sonst links vor zwei leeren Spalten. Steht bewusst nach
   der 59-rem-Containerregel: gleiche Kaskade, spaeter gewinnt. */
.pakete:has(.paket:only-child) {
  grid-template-columns: minmax(0, 32rem);
  justify-content: center;
}

/* ---- Hochzeitsseite: Dichte und Textausrichtung (27.08.2026) ------------
   Frederiks Ansage nach der ersten Fassung: "alles steht sehr weit
   auseinander, man muss eine Ewigkeit scrollen", und der Erlaeuterungstext
   unter der Preiskarte wirkte unausgerichtet. Drei Antworten:
   1. .block--dicht - engeres Blockpolster NUR auf dieser Seite (das grosse
      Polster ist der Rhythmus der uebrigen 18 Seiten, siehe .block--knapp).
   2. Der Preis-Abschnitt wird ab 62 rem ein ZWEISPALTER: Karte links,
      Erlaeuterung als gleichwertige Spalte daneben - der Text ist damit
      Teil der Komposition statt ein Anhaengsel unter der Karte.
   3. Schmal bleibt der Text buendig MIT der Karte (gleiche 32 rem, mittig),
      nicht am linken Seitenrand. Umbrueche steuert die Spaltenbreite je
      Ansicht (text-wrap: pretty), nie ein fester Umbruch im Text. */

/* Mit dem Standard bei 4.5rem (31.08.2026) waeren die alten 4.2rem keine
   Ausnahme mehr, sondern ein Rundungsfehler. Im selben Verhaeltnis
   mitgezogen (Faktor 4.5/7), damit die Hochzeitsseite weiter sichtbar
   dichter steht als die uebrigen — das war ihr Zweck. */
.block--dicht { padding-block: clamp(2rem, 4vw, 3.4rem); }

.block--hochzeitspreis .tarife { margin-top: 1.2rem; }
.block--hochzeitspreis .pakete { margin-top: 1.8rem; }
.block--hochzeitspreis .tarifgruppe__zusatz {
  font-size: 1rem;
  color: var(--tinte-weich);
  max-width: 32rem;
  margin-inline: auto;
  text-wrap: pretty;
}
.block--hochzeitspreis .notiz--preis { margin-top: 1.6rem; }

@media (min-width: 62rem) {
  .block--hochzeitspreis .tarifgruppe {
    display: grid;
    grid-template-columns: minmax(0, 32rem) minmax(0, 34rem);
    justify-content: center;
    align-items: center;
    column-gap: clamp(2.4rem, 5vw, 4.5rem);
  }
  /* Kein padding-top mehr: das Etikett sitzt seit dem 29.08.2026 als
     Chip IM Kartenkopf, nicht mehr ueber der Kante. */
  .block--hochzeitspreis .pakete { margin-top: 0; }
  .block--hochzeitspreis .tarifgruppe__zusatz {
    margin: 0;
    max-width: none;
    font-size: 1.05rem;
  }
}

/* Ruhigere Flatterkante in den Text-Bausteinen der Seite. */
.hb-karte p, .hb-schritt p, .hb-zweitkamera p, .etappe p { text-wrap: pretty; }

