/* =========================================================================
   RENIDENS — minimalistischer Entwurf

   Eine Regel trägt alles: die Bilder sprechen, sonst niemand. Keine
   Serientitel, keine Nummern, keine Kameradaten, keine Animation. Die Spalte
   ist fest, damit die Seite auf jedem Schirm gleich ruhig steht — und weil
   ein Bild, das mitwächst, nie eine feste Größe hat, an der das Auge sich
   festhält.
   ========================================================================= */

:root {
  --papier: #ffffff;
  --tinte:  #282828;      /* nicht Schwarz — Schwarz auf Weiß sticht */
  --leise:  #6b6b6b;      /* seit 25.09.2026 wie --mittel: #8c8c8c hatte 3,36 : 1 auf Weiß, zu wenig für 10 bis 12 px (Yuno: Grau + Tippflächen) */
  --mittel: #6b6b6b;      /* Beschriftungen, die man lesen muss: 5,3 : 1 auf Weiß (Review 09.09., B-5) */
  --spalte: 720px;
  --luft:   8px;          /* zwischen zwei Bildern einer Zeile */
  --rand:   20px;         /* seitlich auf schmalen Schirmen */
  --schrift: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--papier);
  color: var(--tinte);
  font: 400 11px/1.6 var(--schrift);
  letter-spacing: 0.04em;
  -webkit-font-smoothing: antialiased;
}

img, video { display: block; width: 100%; height: auto; }

/* Solange ein Bild lädt, stand an seiner Stelle nur Weiß — beim Scrollen
   entstanden Löcher, die aussahen, als sei die Seite nicht fertig. Ein sehr
   heller Grundton hält den Platz sichtbar frei. */
.reihe figure { background: #f2f0ed; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--leise); }
a:focus-visible { outline: 1px solid var(--tinte); outline-offset: 3px; }

/* ---------- Kopf und Fuß: Mikroschrift, immer links oben und links unten --- */

.kopf,
.fuss {
  padding: 26px var(--rand);
  display: grid;
  gap: 1px;
}
.kopf p,
.fuss p { margin: 0; }
.kopf .marke { font-weight: 600; letter-spacing: 0.02em; }
/* 06.09. (Yuno): der Satz unter der Marke ist wieder weg („sieht net gut aus").
   Die Startseite trägt die Marke als h1 (Jury: keine Überschrift), gesetzt wie
   die Kopfzeile. */
.kopf h1.marke { font: inherit; font-weight: 600; margin: 0; }
.kopf p:not(.marke),
.fuss p { color: var(--leise); }

.fuss {
  padding-top: 120px;
  padding-bottom: 40px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.reihe-titel {
  font: inherit;
  font-weight: 400;
  color: var(--leise);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin: 120px 0 8px;
}

/* ---------- Die Spalte ---------------------------------------------------- */

.spalte {
  width: var(--spalte);
  max-width: calc(100vw - 2 * var(--rand));
  margin: 0 auto;
  /* Anlauf vor dem ersten Bild. Zusammen mit der Videohöhe unten ergibt das
     genau einen Schirm: Kopfzeile, Luft, Bewegtbild — nichts angeschnitten,
     egal wie hoch das Fenster ist.
     29.08.: von 12vh auf 7vh (Yuno — das Video stand zu tief). Bei 900 px
     Fensterhöhe sind das 63 statt 108 px. Der Wert ist bewusst nicht kleiner:
     der Kopf hat selbst 26 px Innenabstand, und alles unter rund 50 px liest
     sich, als klebte das Bild am Text, statt darunter zu stehen. */
  padding-top: 7vh;
}

.reihe { margin: 0 0 var(--luft); }
.reihe:last-child { margin-bottom: 0; }

/* Ein Hochformat über die volle Spaltenbreite wäre 1080 px hoch — höher als
   die meisten Fenster. Man scrollt dann durch ein halbes Bild, statt es zu
   sehen. Deshalb bekommt jedes Einzelbild eine Höhenschranke und wird
   schmaler statt angeschnitten; Querformate bleiben davon unberührt, sie
   erreichen die Schranke nie. */
.voll { display: flex; justify-content: center; }
.voll img {
  width: auto;
  max-width: 100%;
  max-height: min(84vh, 980px);
}
/* Hochformate gleich breit (16.10.2026): Unter der Höhenschranke wäre ein
   3:4-Bild breiter als die 2:3-Bilder, deshalb höchstens so breit wie ein
   2:3-Bild an der Schranke. 2:3 selbst ändert sich dadurch nicht, 3:4 wird
   etwas niedriger statt breiter. Querformate tragen die Klasse nicht. Die
   Grenze sitzt am Link, nicht am Bild: Am Bild bliebe der Link so breit wie
   vorher, und das Bild stünde links darin statt mittig. */
.voll.hoch > .lupe { max-width: calc(min(84vh, 980px) * 2 / 3); }
/* Platz freihalten, solange ein Einzelbild lädt (Todo 16 x, 17.10.2026). Mit
   width: auto war jedes Einzelbild bis zum Laden 0 × 0 px groß (ein Bild ohne
   Daten hat für den Browser die Eigengröße null), width und height im HTML
   halfen nicht. Gemessen am Rechner (1350 × 940): CLS 0,339, und weil die Seite
   vor dem Laden nur 1.020 statt 20.656 px hoch war, luden alle 27 Aufnahmen
   gleich beim Aufruf (mit Bühne und Film 9,1 MB), loading="lazy" griff nicht.
   Jetzt hat jedes Bild eine Mindestgröße aus denselben Schranken wie oben:
   die Spalte (100cqw, .voll ist dafür Container), die Höhenschranke und die
   2:3-Grenze der Hochformate. Die zweite Seite kommt aus dem Seitenverhältnis,
   das width und height im HTML angeben. Die Mindestgröße liegt einen halben
   Pixel unter der Größe nach dem Laden und greift danach nie: Lage und Größe
   aller Bilder bleiben gemessen auf den Tausendstel Pixel gleich (exakt
   gesetzt wichen sie um 1/64 px ab). Die Klassen setzt build.mjs:
     hoch          Hochformat ab 2:3 Breite: so breit wie die 2:3-Grenze
     hoch schmal   schmaler als 2:3: so hoch wie die Höhenschranke
     quer          Querformat ab 3:2: so breit wie Spalte oder Schranke × 3/2
   Ein Querformat zwischen 1:1 und 3:2 trägt keine und hält keinen Platz frei.
   Unter 800 px und im Druck aufgehoben: Dort ist das Bild spaltenbreit
   (width: 100 %) und hält seinen Platz über das Seitenverhältnis ohnehin. */
.voll { container-type: inline-size; }
.voll.hoch img { min-width: calc(min(100cqw, min(84vh, 980px) * 2 / 3) - 0.5px); }
.voll.hoch.schmal img { min-width: 0; min-height: calc(min(84vh, 980px, 150cqw) - 0.5px); }
.voll.quer img { min-width: calc(min(100cqw, min(84vh, 980px) * 3 / 2) - 0.5px); }

.paar {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--luft);
}
.paar figure { margin: 0; }

/* Das Bewegtbild ist der Auftakt, nicht Teil der Reihe: mehr Abstand nach
   unten, und es richtet sich nach der SCHIRMHÖHE statt nach der Spalte. Ein
   Hochformat über die volle Spaltenbreite wäre 1280 px hoch — man sähe nie
   mehr als zwei Drittel davon auf einmal. So steht es immer ganz im Bild. */
.bewegt {
  margin: 7vh 0 calc(var(--luft) * 7);   /* der Anlauf, der vorher an der Spalte hing */
  display: flex;
  justify-content: center;
}
/* Der Rahmen hat das Seitenverhältnis des Clips; Video und Standbild füllen ihn
   deckungsgleich — das Standbild liegt darunter und ist nur zu sehen, wenn das
   Video nicht läuft (Bewegung reduziert, Unterseite unter 1310 px, Ladepause).
   Die Höhe bindet (ein Hochformat in voller Spaltenbreite wäre
   1280 px hoch), die Breite folgt aus dem Verhältnis. */
.bewegt .rahmen {
  position: relative;
  height: min(70vh, 820px);
  aspect-ratio: 720 / 1280;
  max-width: 100%;
  background: #f2f0ed;
}
.bewegt video,
.bewegt .standbild {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}
/* Ohne Bühne auf der Startseite kein doppelter Anlauf: den trägt jetzt .bewegt. */
.spalte { padding-top: 0; }
/* Unterseiten zeigen die Bühne nur im Split (ab 1310 px). */
.unterseite .buehne { display: none; }

/* ---------- Der Leuchttisch ------------------------------------------------
   Ein Bild angeklickt, groesser, mit den Kameradaten darunter.

   WEISS, nicht schwarz. Jeder andere Leuchttisch im Netz verdunkelt — hier
   waere das ein zweiter umgekehrter Block, und die Regel lautet: die Tafel auf
   der Buchen-Seite ist die einzige Ausnahme. Auf Weiss sieht die Aufnahme
   ausserdem genauso aus wie in der Spalte, nur groesser. Der Leuchttisch ist
   damit dasselbe Bild von naeher, keine andere Umgebung.
   ------------------------------------------------------------------------- */

/* Der Verweis darf das Raster nicht anfassen: kein eigener Kasten, keine
   Unterstreichung, keine Farbe. Das Bild bleibt, was es war. */
a.lupe {
  display: block;
  color: inherit;
  text-decoration: none;
  cursor: zoom-in;
}
a.lupe:hover { color: inherit; }
a.lupe:focus-visible { outline: 1px solid var(--tinte); outline-offset: 4px; }
.reihe.paar a.lupe { flex: 1 1 0; min-width: 0; }

/* Der querformatige Film in der Spalte (Yuno, 09.09.2026): volle Spaltenbreite,
   mittig, im eigenen Seitenverhältnis — NICHT beschnitten wie die Bühne.
   Das Standbild liegt als eigenes Bild darunter und hält den Platz frei; das
   Video liegt deckungsgleich darüber. Keine Höhenschranke: 16:9 wird nie zu
   hoch, und eine Schranke hätte den Kasten breiter als den Film gemacht —
   schwarze Balken links und rechts (Review 09.09., M-3). */
.filmrahmen { position: relative; width: 100%; }
/* Die Höhenschranke der Einzelbilder (84vh) gilt für das Standbild NICHT:
   sonst wird der Rahmen bei flachen Fenstern niedriger als der Film, und links
   und rechts stehen schwarze Balken (Review 09.09., M-3). 16:9 wird nie zu
   hoch, die Schranke ist hier ohne Zweck. */
.filmrahmen .standbild { width: 100%; height: auto; max-height: none; }
.film video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.leuchte {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--papier);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--rand);
}
.leuchte[hidden] { display: none; }

/* Solange der Leuchttisch offen ist, scrollt die Seite darunter nicht mit —
   sonst steht man nach dem Schliessen an einer anderen Stelle als vorher. */
html.leuchte-offen { overflow: hidden; }

.leuchte-buehne {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.leuchte figure { margin: 0; }

.leuchte img {
  display: block;
  max-height: 84vh;
  max-width: calc(100vw - 2 * var(--rand));
  width: auto;
  height: auto;
  background: #f2f0ed;
}

/* Die Daten stehen linksbuendig unter dem Bild, nicht mittig: aller Text auf
   dieser Seite steht links. Und NICHT in Versalien — „RICOH GR IV HDF" ist
   nicht der Modellname, „RICOH GR IV HDF" schon; gesperrte Grossbuchstaben
   machen aus einer Messung eine Ueberschrift. */
.leuchte figcaption {
  margin-top: 14px;
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--leise);
  text-transform: none;
}
.leuchte figcaption[hidden] { display: none; }

.leuchte-knopf {
  position: absolute;
  border: 0;
  background: none;
  color: var(--leise);
  font-family: var(--schrift);
  cursor: pointer;
  padding: 0;
  /* 44 px, damit der Daumen sie trifft — dieselbe Schwelle wie in der Tafel. */
  width: 44px;
  height: 44px;
  line-height: 44px;
  text-align: center;
}
.leuchte-knopf:hover { color: var(--tinte); }
.leuchte-knopf:focus-visible { outline: 1px solid var(--tinte); outline-offset: 2px; }

.leuchte-zu   { top: 12px; right: var(--rand); font-size: 24px; }
.leuchte-vor  { left: 4px;  top: 50%; margin-top: -22px; font-size: 30px; }
.leuchte-nach { right: 4px; top: 50%; margin-top: -22px; font-size: 30px; }

@media (max-width: 800px) {
  .leuchte img { max-height: 74vh; }
  /* Auf dem Telefon nehmen die Pfeile am Rand zu viel vom Bild weg — dort
     blaettert man ohnehin mit dem Daumen ueber die Flaeche. */
  .leuchte-vor, .leuchte-nach { top: auto; bottom: 10px; margin-top: 0; }
  .leuchte-vor  { left: var(--rand); }
  .leuchte-nach { right: var(--rand); }
}

@media (prefers-reduced-motion: reduce) {
  .leuchte { transition: none; }
  /* Der Film bleibt Standbild — das Video liegt darüber und würde sonst ein
     schwarzes Feld zeigen, weil es nie zu laden beginnt. */
  .film video { display: none; }}

@media print { .leuchte { display: none; } }

/* ---------- Schmale Schirme ----------------------------------------------- */

@media (max-width: 800px) {
  :root { --luft: 6px; --rand: 16px; }
  /* Auf schmalen Schirmen bindet die Breite, nicht die Höhe. */
  .voll img { width: 100%; max-height: none; }
  .voll.hoch > .lupe { max-width: none; }
  .voll.hoch img, .voll.hoch.schmal img, .voll.quer img { min-width: 0; min-height: 0; }   /* Mindestgrößen von oben (Todo 16 x) */
  /* Kein Flex auf schmalen Schirmen (16.10.2026): Safari auf dem iPhone gab
     beim Laden zufällig einem Bild eine zu kleine Breite, weil der Verweis
     als Flex-Element seine Breite aus dem noch ladenden Bild nimmt. Hier ist
     das Bild ohnehin spaltenbreit, also bekommt der Verweis die volle Breite
     fest vom Block und hängt an keinem Ladezustand. */
  .voll { display: block; }
  /* Auf dem Telefon darf das Video die Breite nehmen — dort ist der Schirm
     selbst hochkant, Höhe und Spalte kommen sich nicht in die Quere. */
  .bewegt .rahmen { width: calc(100% - 2 * var(--rand)); height: auto; }
  /* Unter dem Video dreimal der Bildabstand, am Telefon 18 px (Yuno 17.10.2026:
     erst „Die Lücke stört mich extrem. Mach sie kleiner", dann „du kannst die
     lücke zum video schon real halten, aber halt nicht so extrem wie jetzt.
     vielleicht 18 px"). Vorher 7 × 6 = 42 px. */
  .bewegt { margin-top: 5vh; margin-bottom: calc(var(--luft) * 3); }
  .fuss { padding-top: 90px; }
}

/* Ein Paar nebeneinander wird auf dem Telefon zu schmal, sobald der Schirm
   unter rund 460 px fällt — dann lieber untereinander. */
@media (max-width: 460px) {
  .paar { grid-template-columns: 1fr; }
}

/* ---------- Bewegung reduzieren ------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  /* Wer bewegte Bilder abbestellt hat, bekommt das Standbild — in genau
     derselben Größe, damit die Seite gleich aussieht und nichts springt. */
  video { display: none; }
  /* Der Rahmen behält seine Maße, das Standbild dahinter wird sichtbar. */
}

/* ---------- Der Split (ab 1310 px; bis 04.09. 1100) --------------------------
   Yuno, 03.09.: „Links bleibt das Bewegtbild mit der Auswahl, rechts kann man
   scrollen." Die linke Seite (Kopf + Bühne) klebt in voller Fensterhöhe, die
   rechte trägt Inhalt und Fuß und scrollt mit dem Dokument. Unter 1310 px
   stehen beide wie bisher untereinander. Regel 3 („aller Text bündig links,
   alle Bilder mittig in der Spalte") gilt seither je Spalte: links der Kopf
   bündig und die Bühne mittig, rechts der Inhalt bündig bzw. die Bilder mittig.
   ------------------------------------------------------------------------- */

@media (min-width: 1310px) {
  /* Zwei gleiche Hälften (Yuno, 04.09.: „split mittig"). Links steht der Block
     aus Kopf und Clip mittig, rechts Bilder und Text (Regeln am Blockende).
     --kopf-hoehe ist der gemessene Kopf (fünf Zeilen, 161 px; der Satz vom
     04.09. ist seit 06.09. wieder weg); stimmt er nicht mehr, entsteht nur Luft,
     nie Beschnitt — die Rahmenregeln lesen die echte Spalte. Untergrenze für den
     Kopf 260 px: das Menü „PORTFOLIO ÜBER BUCHEN" ist 208 px breit und darf im
     Split umbrechen (Sicherheitsnetz). Die alte Fassung „Spalte so breit wie der
     Clip" (03.09.) steht in .sicherung/site.css.vor-mittig-20260904. */
  :root { --kopf-hoehe: 161px; }   /* 06.09.: ohne Satz wieder fünf Zeilen */   /* seit 04.09. mit dem Satz unter der Marke (zwei Zeilen): 161 + 35 + 1 */
  body {
    display: grid;
    /* VARIANTE „beide mittig" (Yuno, 04.09.: „die Elemente beide mittig
       platzieren, ich will mal sehen, wie das aussieht"): zwei gleiche Hälften.
       Links steht der Block aus Kopf und Clip mittig, rechts die Bildspalte.
       Die vorige Fassung (linke Spalte so breit wie der Clip) liegt in
       .sicherung/site.css.vor-mittig-20260904 und als Kommentar hier:
       grid-template-columns: min(42%, max(300px, calc((100vh - var(--kopf-hoehe)
         - var(--rand)) * 720 / 1280 + 2 * var(--rand)))) minmax(0, 1fr); */
    grid-template-columns: 50% 50%;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* max-content + 1fr: der Fuß folgt direkt auf den Inhalt, Restplatz eines
       hohen Fensters landet darunter — nicht je zur Hälfte über und unter dem
       Fuß, wie es zwei auto-Zeilen mit dem 100vh-Posten täten (Review 03.09.). */
    grid-template-rows: max-content 1fr;
    min-height: 100vh;
    align-items: start;
  }
  .seite {
    grid-column: 1;
    grid-row: 1 / span 2;
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    flex-direction: column;
  }
  .seite .kopf { flex: 0 0 auto; }
  /* Das Umbrechen des Menüs stand bis 12.09. nur hier. Seit Todo 31 gilt es
     überall (siehe .kopf .menue weiter unten), deshalb steht hier nichts mehr. */
  .unterseite .buehne { display: flex; }
  .buehne {
    flex: 1 1 auto;
    min-height: 0;
    margin: 0;
    padding: 0 var(--rand) var(--rand);
    align-items: flex-end;
  }
  /* Die Höhe ist die Resthöhe — aber nie mehr, als die Spaltenbreite im
     Verhältnis 9:16 hergibt. Sonst gewinnt max-width, das Verhältnis fällt
     weg und der Clip stünde mit Bändern im Rahmen (Review 03.09.: bis 695 px
     grau bei 1600 × 2000). Die Spaltenbreite kommt als Container-Einheit
     (cqw) von .seite — 42vw rechnete den Rollbalken mit, 11 px zu hoch. */
  .seite { container-type: inline-size; }
  .buehne .rahmen { height: min(100%, calc((100cqw - 2 * var(--rand)) * 1280 / 720)); background: transparent; }
  main, .fuss { grid-column: 2; }
  /* Der Anlauf vor dem ersten Bild — rechts gibt es keine Bühne mehr darüber. */
  .spalte { padding-top: 7vh; max-width: calc(100% - 2 * var(--rand)); }
  /* Textseiten: die Überschrift beginnt auf der Höhe der Marke links (26 px),
     nicht am Fensterrand (Review 03.09.: h1 bei y = 0). */
  main.text { padding-top: 26px; }   /* main.text, weil die Grundregel .text{padding:0 …} weiter unten steht */
  .fuss { padding-top: 120px; }
  /* „beide mittig": Kopf und Clip bilden links einen Block gleicher Breite
     (--block = Clipbreite aus der Resthöhe, höchstens Spalte minus Rand), der in
     der Hälfte zentriert steht; die Menüzeile beginnt damit an der linken Kante
     des Clips. Der Kopf ist mindestens 260 px breit (Menü). Rechts zentriert
     .spalte ohnehin (margin auto); die Textseiten ziehen mit. */
  .seite { align-items: center; }
  .seite .kopf, .seite .buehne {
    --block: min(calc((100vh - var(--kopf-hoehe) - var(--rand)) * 720 / 1280), calc(100cqw - 2 * var(--rand)));
  }
  .seite .kopf { width: max(260px, var(--block)); padding-left: 0; padding-right: 0; }
  .seite .buehne { width: var(--block); padding-left: 0; padding-right: 0; }
  /* max-height 100 %: Wird der Kopf höher als --kopf-hoehe annimmt (Satz in
     drei Zeilen bei 260-px-Spalte, gemessen 1440 × 600: Kopf 215), schrumpft der
     Rahmen statt unter den Kopf zu rutschen; object-fit: contain hält den Clip
     im Verhältnis, der Rahmen ist im Split durchsichtig. */
  .buehne .rahmen { width: 100%; height: auto; max-height: 100%; }
  /* Sehr hohe Fenster (Todo 16 p, 17.10.2026): Bindet die Breite statt der Höhe
     (erst ab etwa 1.530 px Fensterhöhe bei 1.600 px Breite), ist der Clip
     niedriger als der Platz unter dem Kopf. align-items: flex-end stellte ihn
     dann unten hin, gemessen bei 1600 × 2000 mit 468 px Leere zwischen Kopf und
     Clip. Jetzt rückt er um genau diesen Überschuss nach oben und steht direkt
     unter dem Kopf, die Leere liegt darunter. Der Überschuss ist die Resthöhe,
     die --block annimmt, minus die Clip-Höhe aus der Breite, und höchstens der
     freie Platz in der Bühne (wächst der Kopf, etwa mit größerer Schrift, rückt
     der Clip nie über ihn). In allen Fenstern, in denen die Höhe bindet, ist er
     null, dort bleibt alles pixelgleich (gemessen 1310 × 720, 1440 × 900,
     1920 × 1080, 2560 × 1440). */
  .buehne .rahmen {
    top: calc(-1 * max(0px, min(100vh - var(--kopf-hoehe) - var(--rand) - (100cqw - 2 * var(--rand)) * 1280 / 720,
      100% - min(100%, var(--block) * 1280 / 720))));
  }
  main.text { margin: 0 auto; }
}

/* ---------- Druck ---------------------------------------------------------- */

@media print {
  /* .unterseite .buehne, weil die Split-Regel (Spezifität 0,2,0) bei
     Druckbreiten ab 1310 px weitergilt und die einfache Klasse dann verliert;
     auf A4/Letter (816 px) greift ohnehin die Grundregel (Review 03.09.). */
  .fuss, video, .buehne, .unterseite .buehne, .film video { display: none; }
  body { display: block; }
  .seite { position: static; height: auto; }
  .spalte { padding-top: 0; }   /* der 7vh-Anlauf des Splits, war vor dem Split schon hier */
  /* Die Mittig-Regeln des Splits zurücknehmen — sonst stünden Kopf und Text ab
     1310 px Drucklayoutbreite (Skalierung 50 %, Ledger) versetzt (Review 04.09.). */
  .seite { align-items: stretch; }
  .seite .kopf { width: auto; padding-left: var(--rand); padding-right: var(--rand); }
  main.text { margin: 0; }
  /* Bildhöhe nicht an der Fensterhöhe zum Druckzeitpunkt (84vh) — sonst druckt
     dieselbe Seite je nach Fenster verschieden große Fotos (vierte Runde:
     756 px bei 900 Fensterhöhe, 252 bei 300). 22 cm passt auf A4 und Letter. */
  .voll img { max-height: 22cm; }
  .voll.hoch > .lupe { max-width: calc(22cm * 2 / 3); }
  .voll.hoch img, .voll.hoch.schmal img, .voll.quer img { min-width: 0; min-height: 0; }   /* die Mindestgrößen rechnen mit 84vh */
}

/* ---------- Textseiten: Über und Buchen ----------------------------------
   Dieselbe Ruhe wie im Portfolio: alles am linken Rand, eine Textbreite, keine
   Kästen, keine Linien, keine Farbe. Struktur entsteht durch Abstand und durch
   winzige Marken in Versalien — nicht durch Größe.                          */

 /* Feste Breite statt „ch" — das Maß hängt sonst an der 11-Pixel-Grundschrift
    und fällt für die zweispaltigen Listen darunter zu schmal aus. */
.text { padding: 0 var(--rand); max-width: calc(620px + 2 * var(--rand)); }

.text h1 {
  margin: 0 0 34px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Porträt auf der Über-Seite (08.09.): an der Textkante, schmaler als die Spalte,
   ohne Unterschrift — Regel 3 (eine Textkante) bleibt. */
.text .portraet { margin: 0 0 30px; width: min(100%, 440px); }
.text .portraet img { display: block; width: 100%; height: auto; }

.text .lese {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.75;
  max-width: 54ch;
  /* In den Rechtstexten stehen Adressen wie die Meta-Vereinbarung zu den
     Seiten-Insights: 64 Zeichen ohne Leerzeichen. Ein Wort, das breiter ist
     als die Spalte, schiebt bei 320 und 375 px die ganze Seite nach rechts
     (gemessen 12.09.2026, Review H2, Befund 12). anywhere bricht solche
     Ketten notfalls mitten im Wort, normale Woerter bleiben unberuehrt. */
  overflow-wrap: anywhere;
  word-break: break-word;
}

.block { margin-top: 64px; }

.marke-klein {
  margin: 0 0 18px;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--leise);
}

/* Begriff und Erklärung: nebeneinander, sobald Platz ist — sonst untereinander */
.text dl {
  margin: 0 0 16px;
  display: grid;
  grid-template-columns: 13em 1fr;
  gap: 0 20px;
  align-items: baseline;
}
.text dt { font-size: 12px; }
.text dd {
  margin: 0;
  font-size: 12px;
  line-height: 1.7;
  color: var(--leise);
}

/* ---------- Leistungen ---------- */

/* Ohne Nummern: die Leistungen heißen ja, wie sie heißen. Auf einer Seite
   bedeutete „01" vorher dreierlei — Buchungsschritt, Leistung, Ablaufschritt.
   Das war der eigentliche Grund für die Unruhe, nicht der fehlende Kontrast. */
.posten { margin: 0 0 40px; }
/* Titel links, Preis rechts auf derselben Zeile — eine Preisliste liest man
   in zwei Spalten, nicht als Absatz mit nachgestellter Zahl. */
.posten-kopf {
  margin: 0 0 8px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
}
.posten-titel { font-size: 13px; font-weight: 600; }
.posten .preis { font-size: 12px; letter-spacing: 0.06em; white-space: nowrap; }

/* Die Einzelheiten waren vier graue Aufzählungspunkte je Leistung — sechzehn
   Zeilen auf einer Seite, die ruhig sein soll. Jetzt eine Zeile. */
.posten-zeile {
  margin: 0;
  font-size: 11px;
  line-height: 1.7;
  color: var(--leise);
}

.klein .marke-klein { color: var(--leise); }
.klein p {
  margin: 0 0 10px;
  font-size: 11px;
  line-height: 1.7;
  color: var(--leise);
  max-width: 56ch;
}

.anfrage {
  margin: 64px 0 0;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.anfrage a { border-bottom: 1px solid var(--tinte); padding-bottom: 2px; }

/* Noch auszufüllende Stellen — sichtbar, aber ohne Lärm */
.offen {
  background: none;
  color: inherit;
  border-bottom: 1px dotted var(--leise);
}

/* Die Seite, auf der man gerade ist, steht im Fuß ohne Verweis. Seit 25.09. auch
   unterstrichen wie oben im Menü: Mit dem dunkleren Grau liegen Tinte und Grau nur
   noch 2,77 : 1 auseinander, zu wenig, um den Zustand allein über die Farbe zu zeigen. */
.fuss [aria-current] { color: var(--tinte); border-bottom: 1px solid var(--tinte); padding-bottom: 2px; }

@media (max-width: 640px) {
  .text dl { grid-template-columns: 1fr; gap: 4px; }
}

/* ---------- Pflichtseiten ------------------------------------------------ */

.text .punkte {
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
  font-size: 12px;
  line-height: 1.8;
  color: var(--leise);
  max-width: 56ch;
}

/* Erklärender Nebensatz — kleiner als der Absatz, zu dem er gehört */
.fussnote {
  margin: 6px 0 0;
  font-size: 11px;
  line-height: 1.7;
  color: var(--leise);
  max-width: 52ch;
}

/* Die zweite Fußreihe: Impressum, Datenschutz, AGB */
.fuss .pflicht {
  margin-top: 14px;
  display: grid;
  gap: 1px;
}
.fuss .pflicht p { color: var(--leise); }
/* Der Widerrufs-Link steht seit 03.10.2026 hervorgehoben: § 356a Abs. 1 BGB verlangt eine
   Widerrufsfunktion, die „hervorgehoben platziert“ und mit „Vertrag widerrufen“ beschriftet ist
   (Gegencheck 03.10., B1). Tinte und Unterstrich statt Grau heben ihn von Impressum,
   Datenschutz und AGB ab. Auf der Widerrufsseite selbst greift [aria-current] von oben. */
.fuss .pflicht a[href="widerruf.html"],
.fuss .pflicht a[href="/widerruf.html"] { color: var(--tinte); text-decoration: underline; text-underline-offset: 3px; }   /* /widerruf.html: die Fehlerseite verweist wurzelabsolut (17.10.2026) */

/* Tippflächen im Fuß (Todo 16 h, 17.10.2026). Gemessen waren die Links am
   Telefon 13 px hoch, „AGB" 27 px breit. Wie im Kopf (25.09.): inline-block mit
   vertical-align: top macht jeden Link so hoch wie seine Zeile (17,6 px), ein
   unsichtbares ::before reicht 9 px zu beiden Seiten und je einen halben Pixel
   in den Zeilenabstand. Die Flächen stoßen damit aneinander, ohne sich zu
   überlappen: 18,6 px hoch, so weit lässt der Zeilenabstand es zu, ohne dass
   sich etwas sichtbar ändert. Wo frei ist, reicht die Fläche weiter: die erste
   Zeile 26 px nach oben in den Abstand über dem Fuß (44 px), die letzte 26 px
   nach unten in den Rand (44 px), die Zeile vor den Pflichtseiten und die erste
   Pflichtseite teilen sich die 15 px dazwischen (je 25,6 px). Die Zeilen
   dazwischen bleiben bei 18,6 px: 24 px (WCAG 2.5.8) gingen dort nur mit mehr
   Zeilenabstand, also sichtbar. */
@media (pointer: coarse) {
  .fuss p a { display: inline-block; vertical-align: top; position: relative; }
  .fuss p a::before { content: ''; position: absolute; left: -9px; right: -9px; top: -0.5px; bottom: -0.5px; }
  .fuss > p:first-child a::before { top: -26.5px; }
  .fuss > p:last-of-type a::before { bottom: -7.5px; }
  .fuss .pflicht p:first-child a::before { top: -7.5px; }
  .fuss .pflicht p:last-child a::before { bottom: -26.5px; }
}

/* Anschriften und Kontaktzeilen stehen als ein Block, nicht als Folge von
   Absätzen — sonst reißt der Absatzabstand die Adresse auseinander. */
.anschrift {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.85;
}

/* ---------- Buchen-Quicklink im Kopf ------------------------------------- */

/* Die Navigation stand bisher nur ganz unten, hinter der kompletten
   Bilderstrecke — auf dem Telefon nach über 7.000 Pixeln. Drei Testleser
   haben sie schlicht nicht gefunden und wussten nicht, dass es „Über" und
   „Buchen" überhaupt gibt. Sie steht jetzt im Kopf, klein wie alles andere,
   aber auf dem ersten Bildschirm. Im Fuß bleibt sie zusätzlich stehen. */
/* Seit 12.09. (Todo 31) umbricht das Menü ÜBERALL und nicht mehr nur im Split:
   Mit „Zusatzleistungen" als fünftem Eintrag stand die Zeile auf dem Telefon
   sonst über den rechten Rand hinaus, „Global · EN" war nicht mehr zu sehen
   (gemessen bei 375 px). Der Zeilenabstand ist kleiner als der Wortabstand,
   damit zwei Menüzeilen nicht wie zwei Absätze aussehen. */
.kopf .menue {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.kopf .menue a { border-bottom: 1px solid transparent; padding-bottom: 2px; }
.kopf .menue a:hover { color: var(--tinte); border-bottom-color: var(--tinte); }
.kopf .menue [aria-current] { color: var(--tinte); border-bottom: 1px solid var(--tinte); padding-bottom: 2px; }
.kopf .menue a { color: var(--leise); }

/* 25.09.2026 (Yuno: Grau + Tippflächen): Am Telefon waren Telefon und Mail im
   Kopf 13 px hoch antippbar, die Menüpunkte 21 px. Jetzt trägt jeder Link ein
   unsichtbares ::before von 44 px Höhe, die Schrift bleibt, wo sie ist.
   Die Flächen überlappen sich nicht: Das Telefon greift nach oben über Rolle und
   Marke (beide nicht antippbar), die Mail nach unten, das Menü nach unten in den
   Abstand zum Inhalt. inline-block mit vertical-align: top macht den Link genau
   so hoch wie seine Zeile (17,6 px), damit hängen die Maße nicht an der Schrift
   des Geräts. Dafür rückt das Menü 12 px tiefer (sonst läge die Fläche der Mail
   über seiner ersten Zeile), und zwei Menüzeilen halten 24 px Abstand (bei
   320 px bricht Global · EN um). Seitlich reichen die Flächen 9 px über den
   Text, bei 18 px Wortabstand stoßen sie genau aneinander.
   Nach dem Review vom 25.09.: Der Kopf gibt die 12 px unten wieder ab (Innenabstand
   26 → 14 px), sonst rutschte alles darunter mit, der Clip ragte auf dem iPhone
   7,6 px unter die Schirmkante und im Split stimmte --kopf-hoehe (161 px) nicht
   mehr. Das ::before misst von der Innenkante des Links aus, der 1-px-Strich
   unter dem Menüpunkt zählt nicht mit: deshalb 24,5 statt 23,4 px (sonst 43 px).
   Der Fokusring liegt 1 statt 3 px vom Link ab, weil der Link als inline-block
   2,3 px höher ist: sonst berührte der Ring die Unterlängen der Rolle darüber. */
@media (pointer: coarse) {
  .kopf { padding-bottom: 14px; }
  .kopf p a { display: inline-block; vertical-align: top; }
  .kopf p a:focus-visible { outline-offset: 1px; }
  .kopf p a, .kopf .menue a { position: relative; }
  .kopf p a::before, .kopf .menue a::before { content: ''; position: absolute; left: -9px; right: -9px; }
  .kopf a[href^="tel:"]::before { top: -26px; bottom: -0.5px; }
  .kopf a[href^="mailto:"]::before { top: -0.5px; bottom: -26px; }
  .kopf .menue { margin-top: 26px; row-gap: 24px; }
  .kopf .menue a::before { top: 0; bottom: -24.5px; }
}

/* ---------- Feine Trennlinien zwischen den Leistungen -------------------- */

.posten + .posten {
  border-top: 1px solid var(--tinte);
  padding-top: 30px;
}

/* ---------- Zusatzleistungen, kompakt und ausklappbar (13.09., Yuno) ------
   Yuno: „mir gefällt im übrigen der tab zusatzleistungen nicht. das sollte
   eigentlich kompakt im Buchen tab stehen. meinetwegen ausklappbar." Vom
   12.09. bis zum 13.09. war das eine eigene Seite. Jetzt ein natives
   <details> unter den vier Angeboten, gebaut wie die Klappzeilen der
   Buchungsstrecke, nur hell: zugeklappt eine Zeile, ohne JavaScript
   bedienbar. Die Posten stehen als Zeilen, nicht als Absätze — sonst wäre
   der Block so lang wie die Seite, die er ersetzt.                          */

.zusatz { border-top: 1px solid var(--tinte); border-bottom: 1px solid var(--tinte); }
.zusatz > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 18px;
  padding: 16px 0;
}
.zusatz > summary::-webkit-details-marker { display: none; }
.zusatz > summary .marke-klein { margin: 0; color: var(--tinte); }
.zusatz-satz { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--mittel); }
.zusatz-knopf {
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mittel);
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
  margin-left: auto;
}
.zusatz[open] > summary .zusatz-knopf { display: none; }
.zusatz > summary:hover .zusatz-knopf { color: var(--tinte); }
.zusatz > summary:focus-visible { outline: 1px solid var(--tinte); outline-offset: 3px; }
.zusatz[open] > summary { border-bottom: 1px solid #e0dedb; }

.zusatz-inhalt { padding: 22px 0 26px; }
.zusatz-inhalt > .lese { margin-top: 0; }
.zusatz-gruppe { margin-top: 26px; }
.zusatz-gruppe .marke-klein { margin: 0 0 8px; }
.zusatz-zeile {
  margin: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding: 7px 0;
  border-top: 1px solid #eceae7;
  font-size: 12px;
}
.zusatz-gruppe .marke-klein + .zusatz-zeile { border-top: 0; }
.zusatz-zeile .preis { color: var(--mittel); white-space: nowrap; letter-spacing: 0.06em; }
.zusatz-gruppe .posten-zeile { margin-top: 10px; }
.zusatz-klein { margin-top: 26px; }
.zusatz-klein p { margin: 0 0 8px; font-size: 11px; line-height: 1.7; color: var(--leise); }

/* Wie bei den Leistungen: unter 560 px passen Titel und Preis nicht
   nebeneinander (dieselbe Messung wie bei .posten-kopf). */
@media (max-width: 560px) {
  .zusatz-zeile { display: block; }
  .zusatz-zeile .preis { display: block; margin-top: 2px; white-space: normal; }
}
@media print { .zusatz-knopf { display: none; } }

/* ---------- Buchungsstrecke (nur Oberfläche) ----------------------------- */


.schritt {
  margin: 34px 0 0;
  padding: 0;
  border: 0;
  border-top: 1px solid var(--tinte);
}
.schritt legend {
  padding: 0 14px 0 0;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.schritt legend .nr { color: var(--leise); }

/* Eine Wahl ist eine Textzeile, kein Kasten. Ausgewählt wird sie durch einen
   Strich links — dieselbe Geste wie die Trennlinien, nur senkrecht. */
.wahl {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 9px 0 9px 16px;
  margin-left: -16px;
  border-left: 1px solid transparent;
  cursor: pointer;
  font-size: 13px;
}
.wahl input { position: absolute; opacity: 0; pointer-events: none; }
.wahl-text { flex: 1; }
.wahl-zusatz { font-size: 11px; color: var(--leise); letter-spacing: 0.06em; }

.wahl:hover .wahl-text { color: var(--leise); }
.wahl:has(input:checked) { border-left-color: var(--tinte); }
.wahl:has(input:checked) .wahl-text { font-weight: 600; }
.wahl:has(input:focus-visible) { outline: 1px solid var(--tinte); outline-offset: 2px; }

.wahl.aus { cursor: default; }
.wahl.aus .wahl-text { color: var(--leise); }
.wahl.aus:hover .wahl-text { color: var(--leise); }

/* Ein Tag ist eine Zeile: Datum links, die Zeiten rechts daneben. Zwölf
   einzelne Zeilen hätten den Tag jedes Mal wiederholt. */
.tage { display: grid; }
.tag {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 9px 0;
  font-size: 13px;
}
.tag-datum { flex: 1; }
.zeit {
  padding: 3px 10px;
  margin-left: 2px;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 12px;
  color: var(--leise);
  letter-spacing: 0.06em;
}
.zeit input { position: absolute; opacity: 0; pointer-events: none; }
.zeit:hover { color: var(--tinte); }
.zeit:has(input:checked) { border-color: var(--tinte); color: var(--tinte); }
.zeit:has(input:focus-visible) { outline: 1px solid var(--tinte); outline-offset: 2px; }

.knopf-zeile { margin: 40px 0 26px; }
.knopf {
  display: inline-block;
  padding: 12px 26px;
  border: 1px solid var(--tinte);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.knopf:hover { background: var(--tinte); color: var(--papier); }
/* Als <button> (Kontakt, Global, Widerruf) bringt der Knopf sonst die Browser-Optik
   mit: Safari malt den Sendeknopf im Systemblau, Chromium grau (Yuno 09.09.:
   „Warum ist der button blau"). Deshalb hier alles ausdrücklich. */
button.knopf {
  -webkit-appearance: none; appearance: none;
  font: inherit;   /* Schriftgröße und Zeilenhöhe kommen aus .knopf bzw. dem Umfeld */
  background: var(--papier); color: var(--tinte);
  border-radius: 0; cursor: pointer;
}
button.knopf:disabled { color: var(--mittel); border-color: var(--mittel); background: var(--papier); cursor: default; }
/* Fokusring wie bei den Links der Seite; ohne diese Regel zeichnet der Browser nach dem
   Klick seinen blauen, runden Systemring (Review 09.09., B-1). */
.knopf:focus-visible { outline: 1px solid var(--tinte); outline-offset: 3px; }

.vorschau { margin-top: 16px; font-style: italic; }



/* Auf Touchgeräten müssen die antippbaren Flächen mindestens 44 px hoch sein —
   eine 27 Pixel hohe Uhrzeit trifft niemand mit dem Daumen zuverlässig. */
@media (pointer: coarse) {
  .zeit { padding: 11px 14px; }
  .wahl { padding-top: 13px; padding-bottom: 13px; }
  .tag { padding: 4px 0; }
}

/* Auf schmalen Schirmen passen Titel und Preis nicht nebeneinander — „Halbtag
   ab 690 € · Ganztag ab 1.190 €" ist 244 Pixel breit und quetscht den Titel in
   zwei Zeilen. Dann lieber untereinander. */
@media (max-width: 560px) {
  .posten-kopf { display: block; }
  .posten .preis { display: block; margin-top: 3px; white-space: normal; color: var(--leise); }
}

/* ---------- Die Tafel: der einzige Ort zum Handeln ------------------------
   Alles auf dieser Seite ist Text auf Weiß — Leistungen, Ablauf, Fußnoten
   lesen sich gleich schwer. Die Buchungsstrecke ist aber das Einzige, wo man
   etwas TUT. Deshalb kehrt sie das Verhältnis um: Weiß auf Schwarz. Ein Block
   auf der ganzen Seite, nicht vier — sonst wäre es wieder ein Muster statt
   eines Hinweises.                                                          */

.tafel {
  margin: 46px 0 0;
  padding: 34px 32px 30px;
  background: var(--tinte);
  color: var(--papier);
}

.tafel-marke {
  margin: 0 0 16px;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
.tafel-satz {
  margin: 0 0 6px;
  font-size: 13px;
  line-height: 1.7;
  max-width: 46ch;
}

.tafel .schritt {
  margin: 30px 0 0;
  border-top-color: rgba(255, 255, 255, 0.28);
}
.tafel .schritt legend { color: var(--papier); }
.tafel .schritt legend .nr { color: rgba(255, 255, 255, 0.5); }

.tafel .wahl-zusatz,
.tafel .tag-datum ~ .zeit,
.tafel .zeit { color: rgba(255, 255, 255, 0.55); }

.tafel .wahl:hover .wahl-text,
.tafel .zeit:hover { color: var(--papier); }

/* Ein 1-Pixel-Strich reichte nicht: Testleser waren sich nicht sicher, ob sie
   überhaupt etwas ausgewählt hatten. Jetzt ein breiter Balken, ein leicht
   aufgehellter Grund und fette Schrift — und die Uhrzeit füllt sich ganz. */
.tafel .wahl:has(input:checked) {
  border-left: 3px solid var(--papier);
  background: rgba(255, 255, 255, 0.09);
}
.tafel .zeit:has(input:checked) {
  background: var(--papier);
  border-color: var(--papier);
  color: var(--tinte);
  font-weight: 600;
}
.tafel .wahl:has(input:focus-visible),
.tafel .zeit:has(input:focus-visible) { outline-color: var(--papier); }

/* Gesperrt heißt nicht unlesbar: „auf Anfrage" ist die Auskunft, dass diese
   Leistungen per Mail laufen. Bei 0.38 lag der Kontrast auf dem schwarzen
   Grund bei 3,4 — mit 0.5 sind es 4,9 und damit über der Schwelle. */
.tafel .wahl.aus .wahl-text,
.tafel .wahl.aus:hover .wahl-text { color: rgba(255, 255, 255, 0.5); }

/* Der Knopf dreht das Verhältnis noch einmal um: Schwarz auf Weiß, mitten
   im schwarzen Feld. Damit ist er das Hellste auf der Seite. */
.tafel .knopf {
  background: var(--papier);
  color: var(--tinte);
  border-color: var(--papier);
}
.tafel .knopf:hover { background: transparent; color: var(--papier); }

.tafel .fussnote { color: rgba(255, 255, 255, 0.5); }

@media (max-width: 640px) {
  .tafel { padding: 26px 18px 22px; }
}

/* ---------- Widerrufsfunktion (§ 356a BGB, 04.09.) ------------------------ */
/* Formulare (Widerruf, Global, Kontakt) sehen seit 09.09. alle gleich aus:
   nur eine Linie unter dem Feld, kleine Marke als Beschriftung, kein Kasten.
   Yuno: „Das bei global beißt sich von der Optik mit der restlichen Fassung." */
.formular { max-width: 46ch; }
.formular .feld { display: grid; gap: 6px; margin: 0 0 22px; }
.formular label { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--mittel); }
.formular input, .formular select, .formular textarea {
  font: inherit; font-size: 13px; line-height: 1.4;
  padding: 8px 0; min-height: 40px; box-sizing: border-box;
  border: 0; border-bottom: 1px solid var(--tinte); border-radius: 0;
  background: transparent; color: var(--tinte);
  -webkit-appearance: none; appearance: none;   /* auch input/textarea, sonst iOS-Innenschatten (B-10) */
}
.formular input::placeholder, .formular textarea::placeholder { color: var(--mittel); opacity: 1; }
.formular select { padding-right: 22px;
  background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23282828' stroke-width='1.2'/%3E%3C/svg%3E") no-repeat right center; }
.formular textarea { min-height: 96px; resize: vertical; }
/* Fokus: dickere Linie UND ein feiner Rahmen mit Abstand, wie bei den Links der Seite
   (Review 09.09., B-2: nur die Linie war zu wenig). */
.formular input:focus-visible, .formular select:focus-visible, .formular textarea:focus-visible {
  outline: 1px solid var(--tinte); outline-offset: 4px; border-bottom: 2px solid var(--tinte); padding-bottom: 7px; }
.formular .honig { position: absolute; left: -9999px; }
.formular .knopf { margin-top: 6px; }
@media (pointer: coarse) {
  .formular input, .formular select, .formular textarea, .formular .knopf { min-height: 44px; }
  .formular input, .formular select, .formular textarea { font-size: 16px; }   /* unter 16 px zoomt iOS Safari beim Antippen (B-9) */
}
/* Druck: Kontakt- und Business-Formular weg (die Verweise darauf auch, s. u.);
   das Widerruf-Formular druckt mit, weil die Anleitung darüber es beschreibt (B-3). */
@media print { #inquiry, #kontakt { display: none; } }

/* Verweise „Zum Kontaktformular" (Angebote) und die Zeile „Nichts Passendes
   dabei?" in der Strecke; Ziel ist #kontakt, das Scrollen ist sanft. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
#kontakt { scroll-margin-top: 24px; }
#buchung { scroll-margin-top: 24px; }   /* Ziel von „Jetzt buchen" (12.09., Nachtrag zu Todo 21) */
.posten-link { margin: 8px 0 0; font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; }
.posten-link a { border-bottom: 1px solid currentColor; padding-bottom: 1px; }
.posten-link a, .strecke-sonst a { white-space: nowrap; position: relative; }   /* nie Zum / Kontaktformular auf zwei Zeilen (B-7) */
/* Tippfläche 44 px ohne sichtbare Änderung: ein unsichtbares Kissen über und unter dem Link (B-6). */
@media (pointer: coarse) { .posten-link a::after, .strecke-sonst a::after { content: ''; position: absolute; left: 0; right: 0; top: -16px; bottom: -16px; } }
@media print { .posten-link, .strecke-sonst { display: none; } }
.tafel a:focus-visible { outline-color: var(--papier); }   /* der Fokusring der Seite ist tintenfarben, auf der Tafel unsichtbar (B-1) */
.tafel a:hover { color: var(--papier); }   /* 25.09.: a:hover (--leise, seit heute #6b6b6b) gäbe auf der Tafel 2,77 : 1, auf Schwarz wird der Verweis heller statt dunkler */
.strecke-sonst { margin: 6px 0 0; padding: 10px 0 4px 16px; font-size: 12px; line-height: 1.6; color: rgba(255, 255, 255, 0.7); }
.strecke-sonst strong { display: block; font-weight: 600; color: var(--papier); }
.strecke-sonst a { color: var(--papier); border-bottom: 1px solid rgba(255, 255, 255, 0.5); }

/* ---------- Buchungsstrecke kompakt (06.09., Yuno) --------------------------
   Zu: eine Zeile (Marke · Kurzsatz · Knopf). Offen: Vorspann, drei Klappzeilen
   für Was / Wo / Wann, Knopf, Fußnote. Alles auf der schwarzen Tafel wie zuvor. */
.tafel.kompakt { padding: 0; }
.tafel.kompakt summary { list-style: none; cursor: pointer; }
.tafel.kompakt summary::-webkit-details-marker { display: none; }
.strecke > summary {
  display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap;
  padding: 20px 28px;
}
.strecke > summary .tafel-marke { margin: 0; }
.strecke-satz { flex: 1; font-size: 13px; }
.strecke-knopf {
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  padding: 8px 14px; border: 1px solid var(--papier);
}
.strecke[open] > summary .strecke-knopf { display: none; }
.strecke > summary:hover .strecke-knopf { background: var(--papier); color: var(--tinte); }
.strecke[open] > summary { border-bottom: 1px solid rgba(255, 255, 255, 0.28); }
.tafel.kompakt .tafel-satz { margin: 18px 28px 6px; }
.tafel.kompakt details.schritt {
  margin: 0 28px; padding: 0; border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.28);
}
.tafel.kompakt details.schritt:first-of-type { border-top: 0; }
.tafel.kompakt details.schritt > summary {
  display: flex; align-items: baseline; gap: 10px;
  padding: 13px 0;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--papier);
}
.tafel.kompakt details.schritt > summary .nr { color: rgba(255, 255, 255, 0.5); }
.tafel.kompakt .stand {
  margin-left: auto; text-transform: none; letter-spacing: 0;
  font-size: 12px; color: rgba(255, 255, 255, 0.55);
}
.tafel.kompakt .stand.gesetzt { color: var(--papier); font-weight: 600; }
.tafel.kompakt .optionen { padding: 2px 0 12px; }
.tafel.kompakt .wahl { padding: 7px 0 7px 16px; }
.tafel.kompakt .tag { padding: 6px 0; }
.tafel.kompakt .knopf-zeile { margin: 22px 28px 14px; }
.tafel.kompakt .fussnote { margin: 0 28px 20px; }
@media (max-width: 640px) {
  .strecke > summary { padding: 16px 18px; gap: 12px; }
  .tafel.kompakt .tafel-satz, .tafel.kompakt details.schritt, .tafel.kompakt .knopf-zeile, .tafel.kompakt .fussnote { margin-left: 18px; margin-right: 18px; }
}

/* Nachbesserungen aus dem Review 06.09. (kompakte Strecke) */
/* B4: Kurzsatz schrumpfte gegen null, die Zeile brach am Telefon in vier Zeilen.
   Jetzt: Satz nimmt die Zeile, die Knopf-Attrappe wandert rechtsbündig darunter. */
.strecke-satz { flex: 1 1 auto; min-width: 0; }
@media (max-width: 640px) {
  .strecke > summary { row-gap: 10px; }
  .strecke-satz { flex: 1 1 60%; }
  .strecke-knopf { margin-left: auto; }
}
/* B7: die Kompakt-Regel schlug die Touch-Regel (44 px) — hier wieder hergestellt. */
@media (pointer: coarse) { .tafel.kompakt .wahl { padding-top: 13px; padding-bottom: 13px; } }
/* B5: die untere Marge der Fußnote kollabierte nach außen — Polster statt Marge. */
.tafel.kompakt .fussnote { margin-bottom: 0; padding-bottom: 20px; }
/* B6/N6: Fokusringe auf der schwarzen Tafel in Weiß, nicht in Tinte. */
.tafel.kompakt summary:focus-visible { outline: 1px solid var(--papier); outline-offset: 2px; }
.tafel .knopf:focus-visible { outline: 1px solid var(--papier); outline-offset: 3px; }
/* Live-Region nur fürs Vorlesen */
.nur-vorlesen { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* 06.09. (Yuno): „die auswählbaren Elemente sollen besser zu erkennen sein":
   ein Ring vor jeder Wahl (gefüllt, wenn gewählt), leichter Grund beim Zeigen,
   Uhrzeiten als Chips mit sichtbarem Rand. */
.tafel.kompakt .wahl { align-items: center; }
.tafel.kompakt .wahl::before {
  content: ''; flex: 0 0 14px; width: 14px; height: 14px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.6); box-sizing: border-box;
}
/* Hover nur auf noch nicht gewählten, nicht gesperrten Zeilen — die Kompakt-
   Regeln sind spezifischer als `.tafel .wahl:has(input:checked)` und machten
   die Auswahl unter dem Zeiger blasser bzw. die Uhrzeit weiß auf weiß
   (Review 06.09., Fehlerklasse Spezifität). */
.tafel.kompakt .wahl:not(.aus):not(:has(input:checked)):hover { background: rgba(255, 255, 255, 0.06); }
.tafel.kompakt .wahl:not(.aus):hover::before { border-color: var(--papier); }
.tafel.kompakt .wahl:has(input:checked)::before {
  background: var(--papier); border-color: var(--papier);
  box-shadow: inset 0 0 0 3px var(--tinte);
}
.tafel.kompakt .wahl.aus::before { border-style: dashed; opacity: 0.45; }
.tafel.kompakt .wahl.aus:hover { background: transparent; }
.tafel.kompakt .zeit { border-color: rgba(255, 255, 255, 0.35); }
.tafel.kompakt .zeit:not(:has(input:checked)):hover { border-color: var(--papier); color: var(--papier); }
/* N8 (vorbestehend): Chips lagen bei 43,2 px, versprochen sind 44. */
@media (pointer: coarse) { .tafel.kompakt .zeit { padding-top: 11.5px; padding-bottom: 11.5px; } }


/* ---------- Buchung mit echten Terminen (08.09., Backend) ------------------
   Das Formular liegt auf der Tafel: dieselbe Bauform wie Kontakt und Widerruf,
   nur in Weiß auf Schwarz. Darunter die Bestätigung als Liste. */
.tafel .formular label { color: rgba(255, 255, 255, 0.55); }
.tafel .formular input, .tafel .formular textarea {
  color: var(--papier); border-bottom-color: rgba(255, 255, 255, 0.5); }
.tafel .formular input::placeholder, .tafel .formular textarea::placeholder { color: rgba(255, 255, 255, 0.5); }
.tafel .formular input:focus-visible, .tafel .formular textarea:focus-visible {
  outline-color: var(--papier); border-bottom-color: var(--papier); }
.tafel .formular .feld .fussnote { margin: 0; }
/* Preisblock unmittelbar vor dem Buchungsknopf (03.10.2026): § 312j Abs. 2 BGB verlangt Preis
   und Zusatzkosten „unmittelbar“ vor der Bestellung „in hervorgehobener Weise“. Deshalb volle
   Schriftfarbe der Tafel und Lesegröße, nicht die graue Fußnote. */
.tafel .formular .preis-block { margin: 20px 0 16px; font-size: 13px; line-height: 1.65; color: var(--papier); max-width: 62ch; }
.tafel .formular .preis-block p { margin: 0 0 8px; }
.tafel .formular .preis-block strong { font-weight: 600; }
.buchung-formular { margin: 30px 28px 0; padding-top: 24px; border-top: 1px solid rgba(255, 255, 255, 0.28); }
.buchung-formular .gewaehlt { margin: 0 0 22px; font-size: 12px; letter-spacing: 0.04em; color: rgba(255, 255, 255, 0.7); }
/* Die Häkchen sind echte Kästchen, keine Linien: Der Formularstil oben nimmt
   allen Eingabefeldern die Systemform (appearance: none), das darf für die
   Kästchen nicht gelten. Yuno 08.09.: „kann die Häkchen für agb usw nicht
   richtig setzen". Die Sätze daneben bleiben Lesetext, keine Versalien. */
.haken { display: grid; gap: 12px; margin: 4px 0 24px; max-width: 46ch; }
.formular .haken label { display: flex; gap: 12px; align-items: flex-start; font-size: 12px; line-height: 1.6;
  letter-spacing: 0; text-transform: none; color: rgba(255, 255, 255, 0.75); cursor: pointer; }
.formular .haken input[type="checkbox"] {
  -webkit-appearance: checkbox; appearance: auto;
  width: 18px; height: 18px; min-height: 0; margin: 2px 0 0; padding: 0;
  border: 0; background: transparent; flex: none; accent-color: var(--papier); cursor: pointer; }
.formular .haken input[type="checkbox"]:focus-visible { outline: 1px solid var(--papier); outline-offset: 3px; border: 0; padding: 0; }
@media (pointer: coarse) { .formular .haken input[type="checkbox"] { width: 22px; height: 22px; min-height: 0; } }
.haken a { color: var(--papier); border-bottom: 1px solid rgba(255, 255, 255, 0.5); }
/* Tippflächen auf der Tafel (Todo 16 h, 17.10.2026). Gemessen am Telefon: „AGB"
   24,5 × 16 px und „Widerrufsbelehrung" 112,6 × 16 px im Satz am ersten Häkchen,
   „Datenschutzerklärung" 124,4 × 13 px in der Fußnote unter dem Knopf. Unsichtbare
   Flächen wie im Fuß, ohne dass sich etwas verschiebt. AGB reicht 20 px nach oben
   in den Abstand über den Häkchen (4 px Luft zum Notizfeld), Widerrufsbelehrung
   8 px nach unten (6 px Luft zum zweiten Häkchen). Zueinander hin nur 1,5 px: Bei
   320 px Breite bricht der Satz um, dann steht Widerrufsbelehrung 3,2 px unter
   AGB. Ergebnis 36,5, 24,5 und 25 px hoch. Die Flächen nehmen nur Platz vom
   eigenen Häkchen-Satz, keinen von einem anderen Link oder Häkchen. */
@media (pointer: coarse) {
  .haken a, #buchungs-formular > .fussnote a { position: relative; }
  .haken a::after, #buchungs-formular > .fussnote a::after { content: ''; position: absolute; }
  .haken a[href="agb.html"]::after { left: -6px; right: -6px; top: -20px; bottom: -1.5px; }
  .haken a[href="widerruf.html"]::after { left: -2px; right: -2px; top: -1.5px; bottom: -8px; }
  #buchungs-formular > .fussnote a::after { left: -2px; right: -2px; top: -6px; bottom: -6px; }
}
.buchung-fertig { margin: 18px 28px 30px; }
.buchung-fertig h2 { margin: 0 0 10px; font-size: 18px; font-weight: 600; letter-spacing: 0.02em; }
.buchung-fertig .lese { color: rgba(255, 255, 255, 0.8); max-width: 46ch; }
.buchung-fertig dl { display: grid; gap: 12px; margin: 22px 0 0; }
.buchung-fertig dt { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255, 255, 255, 0.5); }
.buchung-fertig dd { margin: 2px 0 0; font-size: 14px; }
.buchung-fertig .knopf-zeile { margin: 28px 0 10px; }
.ort-klein { font-size: 11px; color: rgba(255, 255, 255, 0.5); margin-left: 10px; letter-spacing: 0.04em; }
.buchung-leer { margin: 6px 0 0; font-size: 12px; line-height: 1.6; color: rgba(255, 255, 255, 0.7); max-width: 46ch; }
.buchung-leer a { color: var(--papier); border-bottom: 1px solid rgba(255, 255, 255, 0.5); white-space: nowrap; }
@media (max-width: 640px) { .buchung-formular, .buchung-fertig { margin-left: 18px; margin-right: 18px; } }
@media print { .buchung-formular, [data-buchung-fertig] .knopf-zeile { display: none; } }
